请教大佬们,关于 Java 用 poi 的 SXSSFWorkbook 导出大量数据到 excel 文档,能否不生成临时文件,直接写入到响应流中呢

2020-06-08 18:50:29 +08:00
 goldpumpkin
2505 次点击
所在节点    程序员
11 条回复
chendy
2020-06-08 18:53:14 +08:00
有 write (或者叫 writeTo ?)方法,为啥还要写临时文件
luckylo
2020-06-09 06:58:33 +08:00
可以的。如楼上所言。顺便提一句,当心内存问题
fxxwor99LVHTing
2020-06-09 08:33:23 +08:00
直接把字节数据写到 response 里面
xuanbg
2020-06-09 08:52:55 +08:00
为什么要生成临时文件?直接
```
OutputStream stream = new FileOutputStream(file);
workbook.write(stream);
```
lqw3030
2020-06-09 08:56:34 +08:00
当然可以,但是考虑到内存占用,SXSSFWorkbook 还特地提供了类似"滑动窗口"的机制
goldpumpkin
2020-06-09 10:49:17 +08:00
@chendy
@luckylo
谢谢回复。 其实我的目的是要 流式返回数据,在浏览器的表现是 用户点击完下载文件,后服务器一直返回数据给到浏览器。
而 SXSSFWorkbook 是在服务器生成临时文件后后,点击下载文件,已下载下来的
goldpumpkin
2020-06-09 10:59:25 +08:00
@fxxwor99LVHTing
@xuanbg
谢谢回复。其实我想要的是增量输出到 outputstream 里面,我试了一下,不得行。
```
try {
ServletResponse responseAsync = asyncContext.getResponse();
responseAsync.setCharacterEncoding("utf-8");

List<List<String>> row = Arrays.asList(CollUtil.newArrayList("订单号", "渠道", "下班时间", "加班时长", "餐补", "车补次数", "车补", "总计"));
ExcelWriter excelWriter = ExcelUtil.getBigWriter();
excelWriter.write(row);
excelWriter.flush(responseAsync.getOutputStream());

responseAsync.getOutputStream().flush();

for (int i = 0; i < 10; i++) {
excelWriter.write(row);
excelWriter.flush(responseAsync.getOutputStream());
Thread.sleep(2000);
}
responseAsync.getOutputStream().flush();

} catch (Exception e) {

}
```
wiix
2020-06-09 12:23:51 +08:00
@luckylo
@lqw3030
实测调用 write()创不创建临时文件内存占用几乎一样,都很大。40 个字段,10W 行,要占用 1.5G 内存。
想知道真正能节省内存的方法。
lqw3030
2020-06-09 13:36:50 +08:00
@goldpumpkin @wiix
```
new SXSSFWorkbook(int windowSize)
```
可以设置窗口大小,windowSize 即窗口保留行数
goldpumpkin
2020-06-09 14:27:06 +08:00
@wiix
SXSSFWorkbook 就是为了防止内存溢出,才创建的临时文件。它有个窗口设置,超过这设置的行数(默认一百行),就写到临时文件里面,最后一起输出到流。
@lqw3030
是的,但是不没符合我的预期。我的预期是,数据分批次,多次 flush 到响应流里面,不生成临时文件。
而 SXSSFWorkbook,如果不生成临时文件的话,会在内存操作的。
xinQing
2020-06-09 18:19:23 +08:00
数据分批次从数据库查出,写入 response

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/679801

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX