暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

一款超好用的excel开源框架-Easyexcel

光明和黑暗互相吸引 2019-11-06
2098

How about Easyexcel

一款开源的易使用低内存占用的JAVA解析Excel工具

Easyexcel的优势

在JAVA生态中处理Excel框架有Apache poi、jxl。但他们都有个一很令人头疼的问题,非常消耗内存,在实际场景中就很容易产生OOM,导致系统宕机,虽然poi有一套SAX模式的可以从一定程度的解决这个的问题,但POI还是有一些缺陷,使得内存消耗依然很大(例如07版Excel解压缩以及解压后存储都是在内存中完成的)。而在easyexcel重写了poi对于excel的解析,并且在上层做了模型转换的封装,可以通过更加简单的api来对excel进行处理,相对于poi复杂的api来说,学习和使用成本更低


目前Github Star 11k

Github地址:https://github.com/alibaba/easyexcel

64M内存1分钟内读取75M(46W行25列)的Excel

当然还有急速模式能更快,但是内存占用会在100M多一点

与Apache POI对比

easyexcel要去解决的问题Excel读写时候内存溢出

虽然POI是目前使用最多的用来做excel解析的框架,但这个框架并不那么完美。大部分使用POI都是使用他的userModel模式。userModel的好处是上手容易使用简单,随便拷贝个代码跑一下,剩下就是写业务转换了,虽然转换也要写上百行代码,相对比较好理解。然而userModel模式最大的问题是在于非常大的内存消耗,一个几兆的文件解析要用掉上百兆的内存。现在很多应用采用这种模式,之所以还正常在跑一定是并发不大,并发上来后一定会OOM或者频繁的full gc。

其他开源框架使用复杂

对POI有过深入了解的估计才知道原来POI还有SAX模式。但SAX模式相对比较复杂,excel有03和07两种版本,两个版本数据存储方式截然不同,sax解析方式也各不一样。想要了解清楚这两种解析方式,才去写代码测试,估计两天时间是需要的。再加上即使解析完,要转换到自己业务模型还要很多繁琐的代码。总体下来感觉至少需要三天,由于代码复杂,后续维护成本巨大。

其他开源框架存在一些BUG修复不及时

由于我们的系统大多数都是大并发的情况下运行的,在大并发情况下,我们会发现poi存在一些bug,如果让POI团队修复估计遥遥无期了。所以我们在easyexcel对这些bug做了规避。如下一段报错就是在大并发情况下poi抛的一个异常。


  1. Caused by: java.io.IOException: Could not create temporary directory '/home/admin/dio2o/.default/temp/poifiles'

  2.        at org.apache.poi.util.DefaultTempFileCreationStrategy.createTempDirectory(DefaultTempFileCreationStrategy.java:93) ~[poi-3.15.jar:3.15]

  3.        at org.apache.poi.util.DefaultTempFileCreationStrategy.createPOIFilesDirectory(DefaultTempFileCreationStrategy.java:82) ~[poi-3.15.jar:3.15]

复制

报错地方poi源码如下

  1.    private void createTempDirectory(File directory) throws IOException {

  2.        if (!(directory.exists() || directory.mkdirs()) || !directory.isDirectory()) {

  3.            throw new IOException("Could not create temporary directory '" + directory + "'");

  4.        }

  5.    }

复制


仔细看代码容易明白如果在并发情况下,如果2个线程同时判断directory.exists()都 为false,但执行directory.mkdirs()如果一些线程优先执行完,另外一个线程就会返回false。最终 throw new IOException("Could not create temporary directory '" + directory + "'")。针对这个问题easyexcel在写文件时候首先创建了该临时目录,避免poi在并发创建时候引起不该有的报错。

Excel格式分析格式分析

xls是Microsoft Excel2007前excel的文件存储格式,实现原理是基于微软的ole db是微软com组件的一种实现,本质上也是一个微型数据库,由于微软的东西很多不开源,另外也已经被淘汰,了解它的细节意义不大,底层的编程都是基于微软的com组件去开发的。

xlsx是Microsoft Excel2007后excel的文件存储格式,实现是基于openXml和zip技术。这种存储简单,安全传输方便,同时处理数据也变的简单。

csv 我们可以理解为纯文本文件,可以被excel打开。他的格式非常简单,解析起来和解析文本文件一样。

核心原理

写有大量数据的xlsx文件时,POI为我们提供了SXSSFWorkBook类来处理,这个类的处理机制是当内存中的数据条数达到一个极限数量的时候就flush这部分数据,再依次处理余下的数据,这个在大多数场景能够满足需求。读有大量数据的文件时,使用WorkBook处理就不行了,因为POI对文件是先将文件中的cell读入内存,生成一个树的结构(针对Excel中的每个sheet,使用TreeMap存储sheet中的行)。如果数据量比较大,则同样会产生java.lang.OutOfMemoryError: Java heap space错误。POI官方推荐使用“XSSF and SAX(event API)”方式来解决。分析清楚POI后要解决OOM有3个关键。

1、文件解压文件读取通过文件形式

2、避免将全部全部数据一次加载到内存

采用sax模式一行一行解析,并将一行的解析结果以观察者的模式通知处理。

3、抛弃不重要的数据

Excel解析时候会包含样式,字体,宽度等数据,但这些数据是我们不关心的,如果将这部分数据抛弃可以大大降低内存使用。Excel中数据如下Style占了相当大的空间。

About us社区现状

框架作者:玉霄(姬鹏飞),GithubID:jipengfei-jpf,邮箱:jipengfei.jpf@alibaba-inc.com,现就职于阿里巴巴

维护者:庄家钜,GithubID:zhuangjiaju,邮箱zhuangjiaju@qq.com,现就职于灵犀科技

维护者:怀宇(雷舜宇),GithubID:leishunyu,邮箱:huaifeng@apache.org,现就职于阿里巴巴

社区共建

目前easyexcel还存在很多问题,有很多地方需要优化,还有一些新的功能需要开发,如果你有兴趣,欢迎你加入我们,和我们一起共建easyexcel社区

贡献方式不限,有想法欢迎联系我们哦

我就知道你“在看”

阅读原文,点个star呗~



文章转载自光明和黑暗互相吸引,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论