将POI工作簿流式传输到servlet输出流

我在我的Web服务器上构建了一个非常大的POI工作簿。 将整个工作簿保留在内存中,将无法扩展多个并发请求。 有没有办法可以逐步将工作簿写入servlet输出流。 这应该减少响应时间,并使进程内存有效。

如果您要生成Excel 2007(xslx),那么您可以调整BigGridDemo.java的方法,如下所述: http ://web.archive.org/web/20110821054135/http: //www.realdevelopers.com/blog /代码/ EXCEL

解决方案是让POI仅生成容器xslx作为模板,并将实际的电子表格数据作为XML流式传输到zip输出流中。 因此,简化XML生成将取决于您。

不幸的是,当没有顺序数据时,这是不可能的。 我建议寻找另一种格式,例如CSV或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(); } 

如果您使用JExcel它有示例代码从Servlet读取流代码。 http://jexcelapi.sourceforge.net/resources/faq/

这个API的唯一缺点是它只支持Excel 2003。

使用POI – 你能不创建文件并将文件的字节提供给servlet输出流?

您是否尝试使用write方法直接指向HttpServletResponse.getOutputStream()?

请看下面的例子:

  HSSFWorkbook wb = new HSSFWorkbook(); HSSFSheet sheet = wb.createSheet("new sheet"); ... OutputStream out = response.getOutputStream(); wb.write(out); out.close();