2017-08-30 119 views
0

當我嘗試使用apache poi庫讀取excel文件(5.9Mb,共37列,7列使用SUM(A1:A50)等公式時)時出現內存問題(版本3.16)。這裏是我的代碼:使用Apache poi讀取excel文件時出現內存問題

public static ArrayList<ReturnObject> readExcel(InputStream inputStreamExcelData) { 

    ArrayList<ReturnObject> list = new ArrayList<ReturnObject>(); 

    try { 
     //Here is the problem 
     workbook = new XSSFWorkbook(inputStreamExcelData); 
     Sheet firstSheet = workbook.getSheetAt(0); 
     Iterator<Row> iterator = firstSheet.iterator(); 

     while (iterator.hasNext()) { 
      Row nextRow = iterator.next(); 

      ReturnObject reg = new ReturnObject(); 

      Cell cell = nextRow.getCell(0); 
      reg.setData1(getValueCell(cell)); 

      cell = nextRow.getCell(1); 
      reg.setData2(getValueCell(cell)); 

      list.add(reg); 
     } 

     workbook.close(); 
     inputStreamExcelData.close(); 

    } catch (IOException e) { 
     logger.error("", e); 
    } 
    return list; 
} 

的getValueCell功能:

public static String getValueCell(Cell cell) { 

    String result = ""; 

    if (cell != null) { 

     switch (cell.getCellTypeEnum()) { 
     case STRING: 
      result = cell.getStringCellValue(); 
      break; 
     case NUMERIC: 
      Double num = cell.getNumericCellValue(); 
      result = num.longValue() + ""; 
      if (DateUtil.isCellDateFormatted(cell)) { 

       String value = sdf.format(cell.getDateCellValue()); 
       return value; 
      } 
      break; 
     case FORMULA: 
      CellValue cellValue = evaluator.evaluate(cell); 
      result = cellValue.getStringValue(); 
     default: 
      break; 
     } 
    } 

    return result; 
} 

主要方法

public static void main(String... args){ 
     InputStream is = new FileInputStream("/files/file.xlsm"); 
     List<ReturnObjec> r = readExcel(is); 
     System.out.ptintln(r); 
} 

類ReturnObjec:

public class ReturnObject{ 
    private String data1; 
    private String data2; 
    ... setters and getters ... 

} 

當我的第一次運行,它工作正常,但我記得我們年齡顯着增加(58%至74%)並留在這裏。當我運行一個secont企圖內存使用增加一次到77%,然後,我得到一個內存泄漏異常。

Exception in thread "ajp-bio-8009-AsyncTimeout" java.lang.OutOfMemoryError: GC overhead limit exceeded at java.util.concurrent.ConcurrentLinkedQueue.iterator(ConcurrentLinkedQueue.java:663) at org.apache.tomcat.util.net.JIoEndpoint$AsyncTimeout.run(JIoEndpoint.java:157)

我怎麼能管理這個內存的問題?我認爲workbook.close()會釋放一些內存,但它不會發生。

+3

'list'有多大? 'list'返回時會發生什麼?請發佈[最小,完整,可驗證]示例(https://stackoverflow.com/help/mcve)以及Excel需要包含的內容。 –

+0

我更新了我的問題frind Andrex。列表是litle,它只有2個元素。 –

回答

0

嘗試使用XSSF和SAX(Event API)。閱讀應該是這個樣子:

OPCPackage pkg = OPCPackage.open(filename); 
XSSFReader r = new XSSFReader(pkg); 

更多信息,請訪問XSSF SAX APISXSSF

+0

我能夠解決這個問題,我使用了XLSX2CSV類(https://svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/poi/xssf/eventusermodel/XLSX2CSV。 java)並解決了我的問題。謝謝!! –

相關問題