poi导出excel

JavaPOI导出Excel有三种形式,他们分别是

1.HSSFWorkbook

2.XSSFWorkbook

3.SXSSFWorkbook。

HSSFWorkbook:是操作Excel2003以前(包括2003)的版本,扩展名是.xls;

XSSFWorkbook:是操作Excel2007后的版本,扩展名是.xlsx;

SXSSFWorkbook:是操作Excel2007后的版本,扩展名是.xlsx;

第一种:HSSFWorkbook

poi导出excel最常用的方式;但是此种方式的局限就是导出的行数至多为65535行,超出65536条后系统就会报错。此方式因为行数不足七万行所以一般不会发生内存不足的情况(OOM)。

第二种:XSSFWorkbook

这种形式的出现是为了突破HSSFWorkbook的65535行局限。其对应的是excel2007(1048576行,16384列)扩展名为“.xlsx”,最多可以导出104万行,不过这样就伴随着一个问题—OOM内存溢出,原因是你所创建的book sheet row cell等此时是存在内存的并没有持久化。

第三种:SXSSFWorkbook

从POI 3.8版本开始,提供了一种基于XSSF的低内存占用的SXSSF方式。对于大型excel文件的创建,一个关键问题就是,要确保不会内存溢出。其实,就算生成很小的excel(比如几Mb),它用掉的内存是远大于excel文件实际的size的。如果单元格还有各种格式(比如,加粗,背景标红之类的),那它占用的内存就更多了。对于大型excel的创建且不会内存溢出的,就只有SXSSFWorkbook了。它的原理很简单,用硬盘空间换内存(就像hash map用空间换时间一样)。

SXSSFWorkbook是streaming版本的XSSFWorkbook,它只会保存最新的excel rows在内存里供查看,在此之前的excel rows都会被写入到硬盘里(Windows电脑的话,是写入到C盘根目录下的temp文件夹)。被写入到硬盘里的rows是不可见的/不可访问的。只有还保存在内存里的才可以被访问到。

原有的导出excel方式采用的是HSSFWorkbook方式,经测试当选择的高度很多时,生成ecxel的列很多,无法生成excel,页面一直等待进程无法结束;

然后改用XSSFWorkbook方式,此方式当写入的行和列很多时比较耗内存,有时出现无法生成excel的现象;

最后选择SXSSFWorkbook方式,经测试此种方式生成excel文件速度较快,内存消耗较少,生成27M的文件大概用时2S左右,生成55M的文件大概用时4S左右,生成85M的文件大概用时9S左右可以满足需求;

最终决定选用SXSSFWorkbook方式生成Excel文件;

第一组数据导出测试

数据量10月一整月数据,高度间隔7.5m,最大高度6000m,因子数三因子(消光、退偏、颗粒物),常规方式读取;读取处理数据用时208s,生成excel用时81s,生成文件大小496M;

修改成多sheet模式

10月整月数据,高度间隔7.5m,最大高度6000m,三因子,读取用时208s,生成用时52s,生成文件大小475M;

10月1号到7号数据导出,间隔7.5m,最大高度6000m,三因子,读取50s,生成用时8s,

文件大小98M;

10月整月数据,单因子导出,间隔7.5m,最大高度6000m,读取142s,生成用时11s,文件大小143M

方法改良

原有的方法为先读取雷达数据到一个jsonObject中,然后在把jsonObject中的数据生成excel对象,这种方式消耗的内存较大;改良后每读取一条数据生成一条excel记录,该方式消耗内存较少,生成excel速度优于原有方式,所以采用新方式生成excel

新方式:

10月整月数据导出,高度间隔7.5,最大高度6000m,单因子,总用时31s,比原方式快122s,生成文件大小143M

12000m,导出用时96s,单因子,导出文件大小241M

显示导出进度问题

1、通过在session中存导出进度的方式,经测试该方式严重影响导出效率;

2、通过在redis中存导出进度的方式,经测试该方式相比在session中导出效率有所提高,但还是不理想

3、最终决定把数据最大分成100份,然后最多设置100个进度值,经测试导出效率大大提升,接近不使用进度的效果,故采用此方式解决;

停止导出问题

当点击导出停止时,出现空页面的现象;解决方案:通过返回一个空的excel对象来解决,最终会生成一个空的excel;

解决方式二:

通过window.location.href = window.location.href对页面进行刷新来解决返回空的excel问题,此方式会明显感觉到页面的刷新体验不好;

解决方式三:

通过创建iframe的方式解决

var elemIF = document.createElement(‘iframe’);

elemIF.src = url;

elemIF.style.display = ‘none’;

document.body.appendChild(elemIF);

此方式完美解决了导出停止时的空excel对象问题;

最后把iframe移除document.body.removeChild(elemIF);

//冻结第一行第一列

sheet.createFreezePane(1, 1, 1, 1);

    原文作者:mettle_heng
    原文地址: https://blog.csdn.net/mettle_heng/article/details/123072051
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞