赞
踩
Java处理excel文件导入导出的工具包有很多,比如apache下的poi,alibaba开源的easyexcel,jxl支持的excel版本比较旧,而且功能比较单一,还有github上开源的gridexcel属于个人开发者开发的,就不做比较,下面研究的重点还是比较poi和easyexcel的性能和功能扩展性。
无论导入导出性能(tps响应时间),还是内存消耗,cpu消耗,easyexcel都会全面碾压poi,项目早期我们采用了poi的工具,后续的项目开发中本着灰度迭代的原则从poi慢慢迁移到easyexcel的导入导出上来。
导出测试对比:
名称 | 样本数 | 响应时间(ms) | 内存消耗 |
10000 | 3605 | 50m左右 | |
Easyexcel | 10000 | 1617 | 同上 |
Poi | 100000 | 40785 | 50m左右 |
Easyexcel | 100000 | 6589 | 同上 |
Poi | 500000 | Gc异常了 | 100m左右 |
Easyexcel | 500000 | 31617 | 50m左右 |
Poi导出的内存消耗不大,当样本为50w的时候的poi抛出的gc异常,和easyexcel相比总体内存虽然消耗差别不大,但是处理性能上当数据量越大,easyexcel的处理速度的性能体现的越明显,
注:Poi中gc异常图
注:Easyexcel50w样本的cpu内存消耗图
导入测试对比:
名称 | 样本数 | 响应时间(ms) | 内存消耗 |
Poi | 10000 | 1960 | 50m左右 |
Easyexcel | 10000 | 2073 | 400m左右 |
Poi | 100000 | 24065 | 峰值1G左右 |
Easyexcel | 100000 | 7925 | 峰值600m |
Poi | 500000 | 时间很长(等了20分钟还在运行) | 峰值2G左右 |
Easyexcel | 500000 | 41192 | 峰值1200m |
Poi的导入相比easyexcel在导入量很少的情况下,内存消耗和响应时间占优势,当样本扩大10倍到50倍,poi性能特别差,吃内存cpu特别严重,挤压其他的业务线程,下图中也有所示,响应时间上遥遥无期,反而easyexcel当样本扩大10倍到50倍,业务处理相对平滑,响应时间和内存消耗变化不大。
注:Poi10w样本导入的cpu内存消耗图
注:easyexcel10w样本导入的cpu内存消耗图
注:Poi50w样本导入的cpu内存消耗图
注:easyexcel50w样本导入的cpu内存消耗图
注:Poi50w样本导入时因内存和cpu资源消耗过多导致对erueka心跳线程的挤压图
Easyexcel为什么会如此高效呢,在通过上述测试获得的结论我们知晓了它的性能和处理速度,但是海远远不够,我们还需要知道所以然来,源码中探究发现如下:
easyexcel重写了poi对07版Excel的解析,一个3M的excel用POI sax解析依然需要100M左右内存,改用easyexcel可以降低到几M,并且再大的excel也不会出现内存溢出;03版依赖POI的sax模式,在上层做了模型转换的封装,让使用者更加简单方便。
解析XML的方式是SAX。SAX是Simple API for XML的缩写,它是一种基于流的解析方式,边读取XML边解析,并以事件回调的方式让调用者获取数据。因为是一边读一边解析,所以无论XML有多大,占用的内存都很小。以下是easyexcel处理数据的核心类和回调处理器。
Apache poi默认是采用dom方式读取,这种方式的原理是将整个文件都加入到内存中,形成dom文件树,然后对树上的任意文件进行读入操作。这样子相当消耗内存,如果操作的数据量很大,会造成因虚拟机内存不足而程序卡顿,
Easyexcel不仅仅性能优异,而且相对poi来说,提供了poi实现不了或者比较难于实现的功能,我归纳了一下主要有这几方面
Easyexcel在项目中直接使用agro-base公共包中的EasyExcelUtil这个工具类,里面提供了导入和导出的调用方法,如下图所示:
如果需要使用异步导入方式可以自行实现,也比较简单高效,参考代码见官方文档:
https://easyexcel.opensource.alibaba.com/docs/current/quickstart/read#%E6%9C%80%E7%AE%80%E5%8D%95%E7%9A%84%E8%AF%BB
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。