从INPUT-STREAM加载一个大的xlsx文件,抛出OutOfMemoryError Apache POI

问题描述 投票:1回答:1

我想读取一个大的excel文件(.xlsx / .xls)。当我上传20MB的文件时,Java-Heap突然增加了2GB,并遇到OutOfMemoryError。

private Sheet getSheetForFileType(String filType, InputStream fileData) throws IOException {
    Workbook workbook;
    Sheet sheet;
    if (filType.equalsIgnoreCase("xls")) {
        workbook = new HSSFWorkbook(fileData); //OutOfMemoryError
        sheet = workbook.getSheetAt(0);
    } else {
        workbook = new XSSFWorkbook(fileData); //OutOfMemoryError
        sheet = workbook.getSheetAt(0);
    }
    return sheet;
}

如此处Apache-POI overview所述,我尝试使用XSSF和SAX(事件API)修改后的代码如下:

private Sheet getSheetForFileType(String filType, InputStream fileData) throws IOException {

    if (filType.equalsIgnoreCase("xls")) {
        ....
    } else {
        OPCPackage opcPackage = OPCPackage.open(fileData);  //OutOfMemoryError
        XSSFReader xssfReader = new XSSFReader(opcPackage);
        SharedStringsTable sharedStringsTable = xssfReader.getSharedStringsTable();
        XMLReader parser = getSheetParser(sharedStringsTable);
        ....
        ....
    }
    return sheet;
}

但是,我无法加载文件并读取它。

我从Input-Stream读取文件数据,目的是ONLYRead-Data,对此没有写操作。

读取文件占用的内存更少,而InputStream需要更多的内存,因为它必须缓冲整个文件。

我看过其他帖子,据我了解:

  • 增加堆内存
  • excel-streaming-reader [无法使用,我必须同时支持这两个(.xlsx / .xls)]
  • 使用SAX解析器读取

Update-1:添加了示例Excel图片。

sample excel

java excel apache-poi xssf
1个回答
0
投票

尝试使用非常高效和高性能的流式SXSSFWorkbook类而不是XSSFWorkbook(它将整个Excel工作簿保留在内存中),如下所示:

SXSSFWorkbook workbook = new SXSSFWorkbook(100);

其中100是将保留在内存中并实时处理的默认行数。

© www.soinside.com 2019 - 2024. All rights reserved.