7

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

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

那么工作簿或我的 Java 代码有什么遗漏吗?

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

增加 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);

}
4

9 回答 9

10

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

如果您声明为

SXSSFWorkbook workbook= new SXSSFWorkbook(200);

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

于 2014-05-24T08:12:37.797 回答
5

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

SXSSFWorkbook - 应该需要恒定的内存。JMV什么时候抛出OOM?您使用了哪种类型的ResultSet?尝试使用FORWARD_ONLY来限制从数据库中检索到的 JDBC 驱动程序缓存数据。

顺便说一句,修复 OutOfMemoryError 的最佳方法是分析堆转储。使用 -XX:+HeapDumpOnOutOfMemoryError 参数和MAT来了解您的应用程序是如何工作的。

于 2013-01-10T14:44:02.317 回答
2

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

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

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

于 2013-01-10T14:35:16.893 回答
1
Workbook workBook = new SXSSFWorkbook();

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

于 2013-01-11T12:24:55.377 回答
0

从数据库中获取页面结果,而不是一次性读取所有结果。

于 2013-01-10T14:36:52.477 回答
0

很久以前,我在尝试从 R 写入 excel 文件(但使用 XLConnection)时遇到了类似的问题。最后,我通过使用 write.csv 然后用 Excel 打开它并使用“文本到列”按钮来解决。它非常快速和可靠。

于 2013-09-12T15:34:25.303 回答
0

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

  1. 尝试在行级别使用样式表设置。
  2. 如果您需要为每个单元格设置样式表.. 避免为每个单元格设置边框。
于 2015-07-24T21:09:31.960 回答
0

嗨使用最新的 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();
于 2017-12-07T10:16:44.543 回答
0

将 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 循环中使用 sh.flushRows(100); 每 100 行

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

于 2019-08-30T17:16:45.310 回答