写在前面
Java 后端程序员应该会遇到读取 Excel 信息到 DB 等相关需求,脑海中可能突然间想起 Apache POI 这个技术解决方案,但是当 Excel 的数据量非常大的时候,你也许发现,POI 是将整个 Excel 的内容全部读出来放入到内存中,所以内存消耗非常严重,如果同时进行包含大数据量的 Excel 读操作,很容易造成内存溢出问题。
但 EasyExcel 的出现很好的解决了 POI 相关问题,原本一个 3M 的 Excel 用 POI 需要100M左右内存, 而 EasyExcel 可以将其降低到几 M,同时再大的 Excel 都不会出现内存溢出的情况,因为是逐行读取 Excel 的内容 (老规矩,这里不用过分关心下图,脑海中有个印象即可,看完下面的用例再回看这个图,就很简单了)
另外 EasyExcel 在上层做了模型转换的封装,不需要 cell 等相关操作,让使用者更加简单和方便,且看
简单读
假设我们 excel 中有以下内容:
我们需要新建 User 实体,同时为其添加成员变量
@Data
public class User {
@ExcelProperty(index = 0)
private String name;
@ExcelProperty(index = 1)
private Integer age;
}
你也许关注到了 @ExcelProperty
注解,同时使用了 index 属性 (0 代表第一列,以此类推),该注解同时支持以「列名」name 的方式匹配,比如:
@ExcelProperty("姓名")
private String name;
按照 github 文档的说明:
不建议 index 和 name 同时用,要么一个对象只用index,要么一个对象只用name去匹配
- 如果读取的 Excel 模板信息列固定,这里建议以 index 的形式使用,因为如果用名字去匹配,名字重复,会导致只有一个字段读取到数据,所以 index 是更稳妥的方式
- 如果 Excel 模板的列 index 经常有变化,那还是选择 name 方式比较好,不用经常性修改实体的注解 index 数值所以大家可以根据自己的情况自行选择
编写测试用例
EasyExcel 类中重载了很多个 read 方法,这里不一一列举说明,请大家自行查看;同时 sheet 方法也可以指定 sheetNo,默认是第一个 sheet 的信息上面代码的new UserExcelListener()
异常醒目,这也是 EasyExcel 逐行读取 Excel 内容的关键所在,自定义UserExcelListener
继承AnalysisEventListener
@Slf4j
public class UserExcelListener extends AnalysisEventListener<User> {