easyExcel简介

easyExcel能大大减少占用内存的主要原因是在解析Excel时没有将文件数据一次性全部加载到内存中,而是从磁盘上一行行读取数据,逐个解析。

下图是easyExcel和POI在解析Excel时的对比图。

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

上面简要介绍了easyExcel的特点和原理,关于easyExcel的其他问题可以先参考下这个文章。下面就通过代码来介绍下怎么使用easyExcel。

快速使用指南#

文件上传读取Excel#

下面通过一个读取用户信息的列子来展示下怎么使用easyExcel。

step1:创建用户信息类

Copy
@Data public class UserInfo extends BaseRowModel { @ExcelProperty(index = 0) private String name; @ExcelProperty(index = 1) private int age; @ExcelProperty(index = 2) private String address; }

step2:创建AnalysisEventListener子类

Copy
/** * 每解析一行会回调invoke()方法。 * 整个excel解析结束会执行doAfterAllAnalysed()方法 */ //有个很重要的点 不能被spring管理,要每次读取excel都要new。 //这边就会有一个问题:如果UserInfoDataListener中需要用到Spring中的主键怎么办? public class UserInfoDataListener extends AnalysisEventListener<UserInfo> { Logger logger = LoggerFactory.getLogger(UserInfoDataListener.class); //每次读取100条数据就进行保存操作 private static final int BATCH_COUNT = 100; //由于每次读都是新new UserInfoDataListener的,所以这个list不会存在线程安全问题 List<UserInfo> list = new ArrayList<>(); //这个组件是Spring中的组件,这边推荐两种方法注入这个组件 //第一种就是提供一个UserInfoDataListener的构造方法,这个方法提供一个参数是UserInfoDataListener类型 //另外一种方法就是将 UserInfoDataListener 这个类定义成 UserService 实现类的内部类(推荐这种方式) //private UserService userService; @Override public void invoke(UserInfo data, AnalysisContext analysisContext) { logger.info("解析到一条数据:{}", JSON.toJSONString(data)); list.add(data); if (list.size() >= BATCH_COUNT) { saveData(); // 存储完成清理 list list.clear(); } } @Override public void doAfterAllAnalysed(AnalysisContext analysisContext) { // 这里也要保存数据,确保最后遗留的数据也存储到数据库 saveData(); logger.info("所有数据解析完成!"); } private void saveData() { logger.info("{}条数据,开始存储数据库!", list.size()); //保存数据 //userService.save(list); logger.info("存储数据库成功!"); } }

step3: 读取excel