java poi导出大批量数据excel

1 篇文章 0 订阅
1 篇文章 0 订阅

前言 

之前遇到一个需求,将数据以excel文件的形式导出。首先想到的是用poi进行导出。

了解poi的都知道,poi有两个类,HSSFWorkbook用来导出.lsx的excel文件,也就是excel2003以前的版本,XSSFWorkbook用来导出.xlsx的excel文件,也就是excel2007以上的版本。(poi的具体使用方法就不细说了,网上很多实例。)

开发的时候使用的是几百条数据,写完,测试,没有问题。

后来将数据量提高到1万条的时候就出问题了,总是出现内存溢出的情况。分析了一下原因,poi在导出excel文件的时候,1万条数据一次性写到HSSFWorkbook或者XSSFWorkbook这个类的对象中,然后以流的形式输出到前端。也就是说,从写第一条数据开始,内存是不断增加的,直到所有的数据全部写完,输出到前端之后,内存才会得到释放。而jvm的内存是固定的,一般512吧。所以才会出现内存溢出的情况。

解决方案

SXSSFWorkbook这个类可以解决此问题。

先看下官方对这个类的描述

Streaming version of XSSFWorkbook implementing the "BigGridDemo" strategy. This allows to write very large files without running out of memory as only a configurable portion of the rows are kept in memory at any one time. You can provide a template workbook which is used as basis for the written data. See https://poi.apache.org/spreadsheet/how-to.html#sxssf for details. Please note that there are still things that still may consume a large amount of memory based on which features you are using, e.g. merged regions, comments, ... are still only stored in memory and thus may require a lot of memory if used extensively. SXSSFWorkbook defaults to using inline strings instead of a shared strings table. This is very efficient, since no document content needs to be kept in memory, but is also known to produce documents that are incompatible with some clients. With shared strings enabled all unique strings in the document has to be kept in memory. Depending on your document content this could use a lot more resources than with shared strings disabled. Carefully review your memory budget and compatibility needs before deciding whether to enable shared strings or not.

大概意思就是此类可以不需要把所有数据都放在内存中,但是仅仅是数据,一些合并表格注释等信息还是要在内存中的。至于为什么可以只存部分数据在内存,如何实现没有说明。

看下构造方法

SXSSFWorkbook对象在生成excel的时候,会边生成边记录row,当row达到一定数量的时候,就会将之前的row写入到硬盘的临时路径中,然后内存中的row将会重新记录,如此反复,直到全部写完。

参数rowAccessWindowSize就是控制内存中保留的条数,默认是100.

参数compressTmpFiles是说硬盘中的临时文件是否需要压缩

参数workbook就是XSSFWorkbook对象,也可以不填

使用Demo

  SXSSFWorkbook wb = new SXSSFWorkbook(100); // 在内存当中保持 100 行 , 超过的数据放到硬盘中
        Sheet sh = wb.createSheet();
        for (int rownum = 0; rownum < 10000; 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);
            }

        }
        FileOutputStream out = new FileOutputStream("C:/Users/infodba/Desktop/sxssf.xlsx");
        wb.write(out);
        out.close();
        // dispose of temporary files backing this workbook on disk
        wb.dispose();


        System.out.println("");

可以看到,SXSSFWorkbook的构造方法很多,选其中一个只需填写rowAccessWindowSize的。

其他的用法和XSSFWorkbook基本一致。

最后执行了一个dispose方法,是删除硬盘中的临时文件。

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值