请教大佬们,关于 Java 用 poi 的 SXSSFWorkbook 导出大量数据到 excel 文档,能否不生成临时文件,直接写入到响应流中呢 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
goldpumpkin
V2EX    程序员

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

  •  
  •   goldpumpkin 2020-06-08 18:50:29 +08:00 2871 次点击
    这是一个创建于 1952 天前的主题,其中的信息可能已经有所发展或是发生改变。
    11 条回复    2020-06-09 18:19:23 +08:00
    chendy
        1
    chendy  
       2020-06-08 18:53:14 +08:00
    有 write (或者叫 writeTo ?)方法,为啥还要写临时文件
    luckylo
        2
    luckylo  
       2020-06-09 06:58:33 +08:00 via Android
    可以的。如楼上所言。顺便提一句,当心内存问题
    fxxwor99LVHTing
        3
    fxxwor99LVHTing  
       2020-06-09 08:33:23 +08:00
    直接把字节数据写到 response 里面
    xuanbg
        4
    xuanbg  
       2020-06-09 08:52:55 +08:00
    为什么要生成临时文件?直接
    ```
    OutputStream stream = new FileOutputStream(file);
    workbook.write(stream);
    ```
    xyooyx
        5
    xyooyx  
       2020-06-09 08:56:34 +08:00
    当然可以,但是考虑到内存占用,SXSSFWorkbook 还特地提供了类似"滑动窗口"的机制
    goldpumpkin
        6
    goldpumpkin  
    OP
       2020-06-09 10:49:17 +08:00
    @chendy
    @luckylo
    谢谢回复。 其实我的目的是要 流式返回数据,在浏览器的表现是 用户点击完下载文件,后服务器一直返回数据给到浏览器。
    而 SXSSFWorkbook 是在服务器生成临时文件后后,点击下载文件,已下载下来的
    goldpumpkin
        7
    goldpumpkin  
    OP
       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
        8
    wiix  
       2020-06-09 12:23:51 +08:00
    @luckylo
    @lqw3030
    实测调用 write()创不创建临时文件内存占用几乎一样,都很大。40 个字段,10W 行,要占用 1.5G 内存。
    想知道真正能节省内存的方法。
    xyooyx
        9
    xyooyx  
       2020-06-09 13:36:50 +08:00
    @goldpumpkin @wiix
    ```
    new SXSSFWorkbook(int windowSize)
    ```
    可以设置窗口大小,windowSize 即窗口保留行数
    goldpumpkin
        10
    goldpumpkin  
    OP
       2020-06-09 14:27:06 +08:00
    @wiix
    SXSSFWorkbook 就是为了防止内存溢出,才创建的临时文件。它有个窗口设置,超过这设置的行数(默认一百行),就写到临时文件里面,最后一起输出到流。
    @lqw3030
    是的,但是不没符合我的预期。我的预期是,数据分批次,多次 flush 到响应流里面,不生成临时文件。
    而 SXSSFWorkbook,如果不生成临时文件的话,会在内存操作的。
    xinQing
        11
    xinQing  
       2020-06-09 18:19:23 +08:00
    数据分批次从数据库查出,写入 response
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     911 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 18:52 PVG 02:52 LAX 11:52 JFK 14:52
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86