java.lang.OutOfMemoryError:使用jxls编写xlsx时的Java堆空间

时间:2016-04-21 11:34:07

标签: java excel apache-poi jxls

  1. 以下是我用于写入EXCEL(.xlsx)

    的API

    poi 3.9
    poi-ooxml 3.9
    jxls-core 1.0.2

  2. 这是我的源代码

    public ByteArrayOutputStream retrieveFinalReport() {
    
    InputStream is = Thread.currentThread().getContextClassLoader()  
        .getResourceAsStream("Template_Name");  
    try {  
        workbook = transformer.transformXLS(is, beans);  
    } catch (final InvalidFormatException e) {  
        LOG.warn("Error Ocurred", e);  
    }  
    try {   
        workbook.write(outPutStream = new ByteArrayOutputStream());  
    } catch (final IOException e) {  
        LOG.warn("Error Ocurred", e);  
    }  
    return outPutStream;
    
  3. 适用于尺寸较小的文件。(小于1 MB大小.xlsx文件)

  4. 对于较大的文件,它会抛出OOM错误。

  5. PS:之前我们使用的是.xls模板,能够写入所有文件。

    非常感谢您的帮助。

3 个答案:

答案 0 :(得分:0)

使用SXSSF。

点击此链接:How to use Horrible SpreadSheet Format(HSSF) API

以上链接中的代码

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;

public static void main(String[] args) throws Throwable {
        SXSSFWorkbook wb = new SXSSFWorkbook(100); // keep 100 rows in memory, exceeding rows will be flushed to disk
        Sheet sh = wb.createSheet();
        for(int rownum = 0; rownum < 1000; rownum++){
            Row row = sh.createRow(rownum);
            for(int cellnum = 0; cellnum < 10; cellnum++){
                Cell cell = row.createCell(cellnum);
                String address = new CellReference(cell).formatAsString();
                cell.setCellValue(address);
            }

        }

        FileOutputStream out = new FileOutputStream("/temp/sxssf.xlsx");
        wb.write(out);
        out.close();

        // dispose of temporary files backing this workbook on disk
        wb.dispose();
}

而不是address输入您的数据

答案 1 :(得分:0)

您应该升级到支持SXSSF处理的JXLS-2。 然后代码可能看起来像这样

 Transformer transformer = PoiTransformer.createSxssfTransformer(workbook, 100, false);
 AreaBuilder areaBuilder = new XlsCommentAreaBuilder(transformer);
 List<Area> xlsAreaList = areaBuilder.build();
 Area xlsArea = xlsAreaList.get(0);
 xlsArea.applyAt(new CellRef("Result!A1"), context);

如果您不需要公式处理(在SXSSF支持中非常有限),您应该使用

禁用它
context.getConfig().setIsFormulaProcessingRequired(false);

有关完整示例,请参阅jxls-demo project中的SxssfDemo类。

答案 2 :(得分:0)

您可以使用:

-XX:NewRatio=<factor> (try it with 2) 

-XX:NewSize=<value>m

提高年轻一代GC的大小,并能够加载更大的文件。