竹笋

注册

 

发新话题 回复该主题

为什么实际业务中不建议使用POI操作Ex [复制链接]

1#

一:使用场景

在日常的系统开发中,系统支持批量数据的操作是一个很常见的功能,其中,最常用的方式是使用excel表格对数据进行批量添加、删除,如:批量新建订单、批量添加商品等。

二:技术选型

现在市面上有很多技术实现来支持excel数据解析如OI、JXL等,但是,这些技术或多或少都存在着一些问题,下面进行具体分析/p>

(一)OI

POI是目前使用最多的用来做excel解析的框架,但这个框架还存在在这个许多问题。现在使用POI技术来解析excel文件的,大多数都是使用到它的userMode模式,好处是上手比较简单,而且网上比较多封装好的代码,虽然复制一下就可以运行,这个对于数据量不大的文件的时候是可以使用,但是当数据量大的时候会存在巨大隐患。

1、userMode模式存在着一个巨大的问题就是内存消耗很大,一个几兆的文件解析需要上百兆的内存,当并发量大的时候就会容易出现OOM(内存溢出)或者频繁进行fullGC回收),导致程序执行缓慢甚至崩溃

2、如果有深入了解过POI的会发现,其他它针对这个情况提供了一种叫SAX的模式,但是,这种模式相对复杂,且对excel03版本和07版本不兼容,两个版本的数据存储方式不一样,所以解析也不一样,这样需要同个功能需要进行两套代码开发,时间周期长,且不易于维护。

3、在大并发情况下,POI还存在着一些未知的错误,如果需要POI团队修复,周期不确定。

JXL

它是纯javaAPI,在跨平台上表现得非常完美,代码可以再windows或者Linux上运行而无需重新编写,但是它也存在着许多缺点。

1、效率低,格式支持比POI还少。

2、支持Excel95-的所有版本,但是excel以后的版本暂时不支持。

(三)EasyExcel(推荐使用)

阿里巴巴出的产品,相信看到这里很多人应该更有信心(毕竟阿里出的东西还是很有质量保障滴)。它是一个基于Java的简单、省内存的读写Excel的开源项目。在尽可能节约内存的情况下支持读写百M的Excel,选择使用它有以下原因:

1、开源,代码放在github上,有问题随时issue

2、解决了POI解析excel非常耗费内存的问题,它是通过磁盘存储,一行一返回,最大程度解决了内存占用大的问题。

3、社区活跃度高,网上的相关文档也比较多。

(四)POI解析模式和EasyExcel解析模型图

三:常用API介绍

(一)监视器(不能被Spring容器管理,每次读取Excel都需要新new一个,如果需要使用Spring容器对象,则通过构造函数传入)/p>

由于默认一行行地读取excel,所以需要创建excel一行一行的回调监听器(这个是必须实现的,所以我们要兼容所有的对象,监听器的泛型使用Object类型)

(二)读Excel/p>

1、EasyExcel.read(...)---》它有三个重载的方法

2、sheet()--》指定读取的sheet,doRead--》执行读取数据的操作

3、ExcelReader.readAll()--》执行读取Excel文件中的所有sheet

4、ExcelReader实例.finish()--》完成读取操作,并关闭流(一定要注意关闭流,因为easyExcel是使用磁盘的方式进行数据解析,所以解析过程中会创建临时文件,如果不关闭,最后可能会导致磁盘崩溃)

(三)写Excel/p>

1、EasyExcel.write(...)---》它有六个重载的方法

2、writeSheet()---》向excel文件中的sheet写入数据

3、ExcelWriter.write(...)---》插入sheet到excel文件中,这样就完成了数据写入,实际上就是嵌套一样,先将数据写入到sheet,再将sheet插入到excel中

4、ExcelWriter实例.finish()--》完成写入操作,并关闭流(一定要注意关闭流,因为easyExcel是使用磁盘的方式进行数据解析,所以解析过程中会创建临时文件,如果不关闭,最后可能会导致磁盘崩溃)

(四)常用注解

1、

ExcelProperty:作用在excel表数据对应的JAVA实体上,有以下属性/p>

(1):value--指定导出时该字段对应的标题名称,或者是读取时匹配excel表格中表头的名称,符合则将表头中对应的数据填充到此处,如果这个名称存在多个,只能读取到一个。

(2):index--指定该字段和excel文件的哪一列对应,默认是0,不推荐和value属性同时指定,如果需要指定,那么value的值最好指定为导出数据对应表头的标题名,index的值则指定为读取excel文件时该字段属性对应的列的位置。

(3):converter属性则是指定对应的转换器,可以自己书写一个转换器,在读取数据的时候进行对数据的格式化,如:给每一列数据都加上自己自定义的东西

2、

ExcelIgnoreUnannotated:默认情况下Java类中的所有属性都添加读写,在类上面加入

ExcelIgnoreUnannotated注解,加入这个注解后只有加了

ExcelProperty才会参与读写。

3、

ExcelIgnore:被标注的属性不参加Excel的读写,相当于直接省略。

四:实战

(一):添加依赖

  //easyExcel坐标dependencygroupId

分享 转发
TOP
发新话题 回复该主题