将 POI 工作簿流式传输到 Servlet 输出流
2022-09-02 01:43:18
我在我的 Web 服务器上构建了一个非常大的 POI 工作簿。将整个工作簿保存在内存中 不会针对多个并发请求进行缩放。有没有办法我可以逐步将工作簿写入servlet输出流。这应该会减少响应时间,并使进程内存高效。
我在我的 Web 服务器上构建了一个非常大的 POI 工作簿。将整个工作簿保存在内存中 不会针对多个并发请求进行缩放。有没有办法我可以逐步将工作簿写入servlet输出流。这应该会减少响应时间,并使进程内存高效。
如果您即将生成Excel 2007(xslx),那么您可以调整BigGridDemo的方法.java如下所述:http://web.archive.org/web/20110821054135/http://www.realdevelopers.com/blog/code/excel
解决方案是让 POI 仅生成一个容器 xslx 作为模板,并将实际的电子表格数据作为 XML 流式传输到 zip 输出流中。然后,简化 XML 生成由您决定。
自从编写了其余答案以来,情况已经大大改善 - 流媒体现在是Apache Poi的一部分。
请参阅 SXSSFWorkbook 类和此处的文档。它在工作表上使用流窗口,将窗口外的旧行刷新为临时文件。
这是基于hlg答案中使用的方法,但现在是官方分发的一部分。BigGridDemo
下面是文档中的示例:
public static void main(String[] args) throws Throwable {
// keep 100 rows in memory, exceeding rows will be flushed to disk
SXSSFWorkbook wb = new SXSSFWorkbook(100);
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);
}
}
// Rows with rownum < 900 are flushed and not accessible
for(int rownum = 0; rownum < 900; rownum++){
Assert.assertNull(sh.getRow(rownum));
}
// ther last 100 rows are still in memory
for(int rownum = 900; rownum < 1000; rownum++){
Assert.assertNotNull(sh.getRow(rownum));
}
FileOutputStream out = new FileOutputStream("/temp/sxssf.xlsx");
wb.write(out);
out.close();
// dispose of temporary files backing this workbook on disk
wb.dispose();
}