记一次解决poi XSSFWorkbook导出excel内存溢出换成SXSSFWorkbook还是内存溢出的问题

1、需求背景

        工作中同事遇到一个导出excel内存溢出的问题,让我帮忙解决。一个excel大约有800个sheet页。原写法使用的XSSFWorkbook写入导出。百度了下了解到应该替换成SXSSFWorkbook,因为SXSSFWorkbook可以设置写入多少条就会生成临时文件保存到磁盘,释放占用内存以此来控制占用内存大小。但是我看了几个例子更换成SXSSFWorkbook以后,依然内存溢出!!!

2、解决过程

       先是尝试改动窗口大小(百度的全是这个方法,然而并不管用),即new SXSSFWorkbook(40)时候的参数,发现更改了多次甚至改为-1都是一样的结果,差不多200个sheet页的时候就内存溢出了

        然后想到了在生生过程中查看临时文件路径下是否真的生成了临时文件。windows下存放路径为:C:\Users\Administrator\AppData\Local\Temp\poifiles

结果发现全是0kb!!!!虽然生成了一堆临时文件但是大小都是0打开也没数据。

        于是想到了是不是需要自己写下类似刷新到磁盘的过程,是不是不是自动刷新进去的。于是翻找api,在api中找到了一个SXSSFWorkbook对象的()方法,写到程序里发现没这个方法(没研究是真没有还是导入包的版本旧的问题)于是又找了下Sheet的方法,没找到。但是我在程序里点出来了个flushRows()方法,添加上以后,重新运行发现生成的临时文件不全为0k了,也没有出现内存溢出了。

        代码加在创建sheet后并写入完数据后

SXSSFWorkbook workBook1 = new SXSSFWorkbook();
SXSSFSheet sheet1 = workBook1.createSheet("sheetName");
//具体要写入的业务逻辑等
//创建行 设置行样式等
...
//写入数据 设置单元格样式等
...
//不写此句,没有写入磁盘依然占用内存 之前就是没有写这句,生成的临时文件都是0kb,加上即解决了问题
sheet1.flushRows();

        加上以后的临时文件:

3、改为SXSSFWorkbook过程中踩过的坑

        因为我们业务先从已有的一个excel中拿到模板,再将查到的数据库数据写入excel中。在此过程中涉及到读取已有excel并使用sheet的getRow(index)方法获取row进行复制。直接使用SXSSFWorkbook对象的getSheetAt(index)获取到的Sheet再调用getRow(index)获取行为null。解决方法如下:

//正确的获取需要使用getRow的sheet的方法
Sheet sheet = workBook.getXSSFWorkbook().getSheetAt(i);

 3、额外优化

        除了优化使用的工具类,优化数据库取数据的过程也很重要。如果数据库中查出的数据到内存直接内存溢出了往后更没法操作写入excel了,,建议分批处理数据

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值