繁体   English   中英

内存不足错误 - 写入Excel时的Java堆空间

[英]Out of Memory Error - Java Heap Space while writing to Excel

我有近100,000条记录的数据,我正在尝试使用XSSFWorkbook通过Java代码将数据写入.xlsx文件。 我能够将数据库中的所有数据提取到ArrayList 通过迭代ArryList ,我将数据逐个单元地写入.xlsx文件。 当它达到8000行时,java代码抛出Out of Memory Heap Space错误。

我已经读过某个地方,与XSSFWorkbook相比, SXSSFWorkbook会更轻,所以我尝试使用SXSSFWorkbook 但我仍面临同样的问题。

那么,我在工作簿或我的Java代码中缺少什么?

最初,当我有60,000条记录数据时,我使用了.xls文件。 相同的java代码能够使用HSSFWorkbook生成.xls文件。

增加Java堆空间根本不是一个选项,因为我的数据将来会大大增加。

任何帮助将不胜感激。

小块代码,我将数据写入Excel的方式。

int rowNum = sheet.getLastRowNum();

Row lastRow = null ;

Cell cell = null;

ReportingHelperVo reportingHelperVo = null; 

for (ReportingVo reportingVo : reportingVos) {

rowNum++;

lastRow = sheet.createRow(rowNum);

reportingHelperVo = reportingVo.reportingHelperVo;

cell = lastRow.createCell(0);

cell.setCellValue(reportingHelperVo.getLocation());

cell.setCellStyle(style);

cell = lastRow.createCell(1);

cell.setCellValue(reportingHelperVo.getCity());

cell.setCellStyle(style);

cell = lastRow.createCell(2);

cell.setCellValue(reportingHelperVo.getCountry());

cell.setCellStyle(style);

}

XSSFWorkbook - 为所有Excel文档创建对象表示(应该像DOM一样工作)。

SXSSFWorkbook - 应该需要恒定的内存。 JMV何时抛出OOM? 你使用什么类型的ResultSet 尝试使用FORWARD_ONLY来限制从DB检索的JDBC驱动程序的缓存数据。

BTW最好修复OutOfMemoryError是分析堆转储。 使用-XX:+ HeapDumpOnOutOfMemoryError参数和MAT来了解应用程序的工作方式。

我正逐个单元地将数据写入.xlsx文件。 当它达到8000行时,java代码抛出内存堆空间错误。

重用现有的java对象,而不是每次迭代都创建new对象。

和/或使用csv文件而不是excel。

SXSSFWorkbook不像重量轻,但这有一个优势。

如果你声明为

SXSSFWorkbook workbook= new SXSSFWorkbook(200);

然后,对于写在工作簿上的每200行,内存将被刷新到磁盘空间,因此堆空间不会有任何负担。

Workbook workBook = new SXSSFWorkbook();

您可以导出超过1万(100000)条记录。

页面结果来自数据库,而不是一次性读取它们。

很久以前我有类似的问题试图从R写入excel文件(但使用XLConnection)。 最后,我通过使用write.csv解决,然后用Excel打开它并使用botton“Text to column”。 它增长迅速可靠。

当我的excel达到3000行时,我遇到了同样的问题。 在我的情况下,POI Excel生成的主要内存相关问题发生在样式表中。 以下是我从代码中删除的内容。

  1. 尝试在行级别中使用样式表设置。
  2. 如果您需要为每个单元格设置样式表,请避免为每个单元格设置边框。

您好使用最新的Apache POI JAR //并使用SXSSF进行流式传输或下载

 SXSSFWorkbook workbook = new SXSSFWorkbook(100); 
            workbook.setCompressTempFiles(true);
            Sheet sh = workbook.createSheet();
            ((SXSSFSheet) sh).setRandomAccessWindowSize(100);

//写你的逻辑

   response.setContentType("application/vnd.ms-excel");
            response.setHeader("Content-Disposition", "attachment; 
       filename="+filename+".xlsx");
            workbook.write(response.getOutputStream());
            workbook.close();
            workbook.dispose();

将XSSFWorkbook写入文件时出现内存不足的问题。
上面的建议帮了很多忙。
http://poi.apache.org/components/spreadsheet/how-to.html#xssf_sax_api

  1. 更改XSSFWorkbook wb = new XSSFWorkbook();
    到SXSSFWorkbook wb = new SXSSFWorkbook(-1);
    SXSSFSheet sh = ...到SXSSFSheet sh = ...
    XSSFRow到SXSSFRow
    XSSFCell到SXSSFCell

  2. 在for循环USE中.sh.flushRows(100); 每100行

  3. 在wb.write(out)之后;
    ADD wb.dispose();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM