2017-08-30 175 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)并解决了我的问题。谢谢!! –

相关问题