【问题标题】:JAVA - Apache POI OutOfMemoryError while writing Excel FileJAVA - 编写 Excel 文件时出现 Apache POI OutOfMemoryError
【发布时间】:2010-07-06 11:39:57
【问题描述】:

我正在使用 Apache POI 编写 Excel 文件。

我想把myResultSet的所有数据都写进去

字段名(列)存储在 String[] 字段名中。

我有 70000 行和 27 列

我的代码:

String xlsFilename = "myXLSX.xlsx";
org.apache.poi.ss.usermodel.Workbook myWorkbook = new XSSFWorkbook();
org.apache.poi.ss.usermodel.Sheet mySheet = myWorkbook.createSheet("myXLSX");
Row currentRow = mySheet.createRow(0);
for (int k = 0; k < fieldNames.length; k++) {
    // Add Cells Of Title Of ResultsTable In Excel File
    currentRow.createCell(k).setCellValue(fieldNames[k]);
}

for (int j = 0; j < countOfResultSetRows; j++) {
    myResultSet.next();
    currentRow = mySheet.createRow(j + 1);
    for (int k = 0; k < fieldNames.length; k++) {
        currentRow.createCell(k).setCellValue(myResultSet.getString(fieldNames[k]));
        System.out.println("Processing Row " + j);
    }
}

FileOutputStream myFileOutputStream = new FileOutputStream(xlsFilename);
myWorkbook.write(myFileOutputStream);
myFileOutputStream.close();

我的问题是,在编写行时,程序变得越来越慢。

当它到达第 3500 行时,它会因异常而停止:

线程“Thread-3”java.lang.OutOfMemoryError 中的异常:Java 堆空间 在 java.lang.AbstractStringBuilder.(AbstractStringBuilder.java:45) 在 java.lang.StringBuffer.(StringBuffer.java:79)

我好像没有记忆了。

我该如何解决这个问题。

有没有办法将我的数据每 1000 个存储到一个临时文件中(例如)?

你有什么建议?

我在使用 jxl 时遇到了同样的问题,但也从未解决过 (JAVA - Out Of Memory Error while writing Excel Cells in jxl)

现在我无论如何都需要 xlsx 文件,所以我必须使用 POI。

【问题讨论】:

  • 您使用的是哪个应用服务器?

标签: excel memory memory-management excel-2007 apache-poi


【解决方案1】:

似乎有一种方法可以先创建 XML 格式的数据文件,然后用现有的模板 xlsx 文件替换该 XML。

http://svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/BigGridDemo.java

这不适用于 xls 格式的文件。

【讨论】:

  • 您最好使用较新的 SXSSF 而不是 Big Grid Demo,因为前者比后者为您做更多的工作
  • 如果您想修改现有的电子表格,BigGridDemo 非常有用。普通 SXSSF 是一种只写格式(从空白工作簿或打开的 XSSFWorkbook 对象开始。基于 SAX 事件的模型是只读的。要拥有一个可以编辑现有文件而不将整个工作簿加载到内存中的类,您将需要使用较低级别的 API 来编写 XML 文件并重新打包工作簿。
【解决方案2】:

让您的应用使用更多内存(例如 -Xmx500m 占用 500 MB)怎么样?

【讨论】:

    【解决方案3】:

    在运行程序时为堆分配更多内存:

    $ java -Xms256m -Xmx1024m NameOfYourClass
    

    【讨论】:

      【解决方案4】:

      我去过不止一次。

      您是否在应用程序服务器上运行此程序?

      正如 Pablo 所提到的,我过去所做的是增加堆空间,但要确保它正在为您正在运行的应用程序服务器增加。

      在执行此操作时,我还必须真正优化代码。

      由于您要输出到.xlsx 文件,XML 会占用相当多的内存。不确定在这种情况下它是否适合您,但如果您可以创建一个普通的.xls,然后在最后将其转换为.xlsx 文件(当然使用 Apache POI)。

      【讨论】:

        【解决方案5】:

        使用 SXSSFWorkbook 代替 XSSFWorkbook,这是用于流式传输用户模型 Api

        来源:https://coderanch.com/t/612234/Write-Huge-Excel-file-Xlsx

        希望这会对你有所帮助。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-07-23
          • 1970-01-01
          • 2014-12-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多