7

我正在使用 ColdFusion 将相当数量的行(大约 1000)但大量的列(大约 300)导出到 Excel。它是一个多表 Excel 文件,其中至少有两个具有大量列的表。使用cfspreadsheet会引发 Java 堆错误。更新 JVM 设置值未显示任何改进。在不导致 Java 堆错误的情况下导出到 Excel 的最佳方法是什么?

编辑:我尝试了几种方法来解决程序中的问题。我正在使用 cfsavecontent 中的 xml 工作簿来构建多个工作表并使用 cfcontent 呈现结果。在这种情况下,cfcontent 可能正在使用大量内存,从而导致堆空间错误。

<cfsavecontent variables="REQUEST.xmlData">
<cfoutput>
<xml version="1.0"?>
<?mso-application progid="Excel.sheet"?>
<Workbook>
   ...other contents
</Workbook>
</cfoutput>
</cfsavecontent>

对于第二种解决方法,我使用 querynew 来构建内容并将最终结果转储到使用<Cfspreadsheet action="write">. 对于后续工作表,我使用<cfspreadsheet action="update">. 最终目标是使用 为 excel 服务<cflocation url="excelPath">,但在这种情况下,cfspreadsheet 更新将永远抛出内存错误。

如果更新 jvm 不是一种选择,您建议实施哪些其他方法来克服内存问题。

4

1 回答 1

1

我参加聚会有点晚了...

据我所知,cfspreadsheet在刷新到磁盘之前尝试在内存中实现整个文件。随着cfsavecontent你明确地这样做。

您熟悉构建 Workbook XML,因此您的cfsavecontent方法需要的只是流式传输到磁盘。

这可以通过深入研究底层 Java 库来实现。java.io.FileWriter可以附加到文件而不将整个文件保留在内存中:

var append = true;
var writer = createobject("java", "java.io.FileWriter").init(filename, append);
try {
  writer.append("<xml version=""1.0""?>\n<?mso-application progid=""Excel.sheet""?>\n<Workbook>\n");
  // Build your workbook in chunks
  // for (var row in query)
  //   writer.append(markup)
  writer.append("</Workbook>");
} finally {
  writer.close();
}

从测试来看,我相信 FileWriter会定期调用flush,所以我省略了它,但我找不到任何说明这种情况的文档。我从未见过内存使用率很高,但 YMMV。

于 2018-08-09T17:43:32.520 回答