我自己是阿里的一名普通码农,今年年初通过公司对外开源一个工具easyexcel主要用于解决POI在解析excel时候存在的3个问题。
1、POI非常耗内存(大的Excel需要上G的内存),系统容易OOM。
2、POI使用复杂,需要非常多重复代码。
3、POI一些BUG未修复。
基于以上问题自己写了easyexcel,在阿里内部使用比较多,阿里内部我是基于POI的SAX模式做的,也已经非常稳定,但仍旧存在内存消耗比较大的问题,POI sax并不能完全解决OOM问题。开源版本自己重写07版的解析过程,内存消耗更低,可以从根本上解决OOM的问题,理论无论EXCEL再打内存消耗可以控制在KB的级别。开源4个月左右,使用人数也比较多,大家也在git上提了非常多的bug。虽然自己写了一些框架,在阿里内使用比较多的有2个框架,部但由于自己是一名业务码农,前面大部分时间在做业务,大促无时间进行升级,在本周末也集做了处理,目前稳定版本是1.0.2。在这里还是感谢那些提了建议,bug以及给出优化方案的同学。后面自己周末会投入一部分时间持续升级和开源自己写的感觉还不错的东西,还希望大家多多支持。
git开源地址:https://github.com/alibaba/easyexcel
使用前最好咨询下最新版,或者到mvn仓库搜索先easyexcel的最新版
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>1.0.2</version>
</dependency>
读Excel
使用easyexcel解析03、07版本的Excel只是ExcelTypeEnum不同,其他使用完全相同,使用者无需知道底层解析的差异。
无java模型直接把excel解析的每行结果以List<String>返回 在ExcelListener获取解析结果
读excel代码示例如下:
@Test
public void testExcel2003NoModel() {
InputStream inputStream = getInputStream("loan1.xls");
try {
// 解析每行结果在listener中处理
ExcelListener listener = new ExcelListener();
ExcelReader excelReader = new ExcelReader(inputStream, ExcelTypeEnum.XLS, null, listener);
excelReader.read();
} catch (Exception e) {
} finally {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
ExcelListener示例代码如下:
/* 解析监听器,
* 每解析一行会回调invoke()方法。
* 整个excel解析结束会执行doAfterAllAnalysed()方法
*
* 下面只是我写的一个样例而已,可以根据自己的逻辑修改该类。
* @author jipengfei
* @date 2017/03/14
*/
public class ExcelListener extends AnalysisEventListener {
//自定义用于暂时存储data。
//可以通过实例获取该值
private List<Object> datas = new ArrayList<Object>();
public void invoke(Object object, AnalysisContext context) {
System.out.println("当前行:"+context.getCurrentRowNum());
System.out.println(object);
datas.add(object);//数据存储到list,供批量处理,或后续自己业务逻辑处理。
doSomething(object);//根据自己业务做处理
}
private void doSomething(Object object) {
//1、入库调用接口
}
public void doAfterAllAnalysed(AnalysisContext context) {
// datas.clear();//解析结束销毁不用的资源
}
public List<Object> getDatas() {
return datas;
}
public void setDatas(List<Object> datas) {
this.datas = datas;
}
}
有java模型映射
java模型写法如下:
public class LoanInfo extends BaseRowModel {
@ExcelProperty(index = 0)
private String bankLoanId;
@ExcelProperty(index = 1)
private Long customerId;
@ExcelProperty(index = 2,format = "yyyy/MM/dd")
private Date loanDate;
@ExcelProperty(index =