一、EasyExcel
1.EasyExcel简介
简介: 可以去官网看看,官网介绍文档也很全面。EasyExcel官网
EasyExcel是一个基于Java的简单、省内存的读写Excel的开源项目。在尽可能节约内存的情况下支持读写百M的Excel。(其实总体来说就是占内存小,响应快,写法简单)
1.2.重写POI简化开发
EasyExcel重写了POI对07版Excel的解析,可以把内存消耗从100M左右降低到10M以内,并且再大的Excel不会出现内存溢出,03版仍依赖POI的SAX模式。
在上层做了模型转换的封装,让使用者更加简单方便
1.3. 特点
在数据模型层面进行了封装,使用简单
重写了07版本的Excel的解析代码,降低内存消耗,能有效避免OOM
只能操作Excel
不能读取图片
2. Apache POI简介
简介: Apache POI是Apache软件基金会的开源函式库,提供跨平台的Java API实现Microsoft Office格式档案读写。但是存在如下一些问题:
2.1 学习使用成本较高
对POI有过深入了解的才知道原来POI还有SAX模式(Dom解析模式)。但SAX模式相对比较复杂,excel有03和07两种版本,两个版本数据存储方式截然不同,sax解析方式也各不一样。
学习这两种解析方式,在转换到自己的业务模块是需要好久的学习时间,并且由于代码过于复杂,之后维护成本非常大。
POI的SAX模式的API可以一定程度的解决一些内存溢出的问题,但是POI还是有一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大,一个3M的Excel用POI的SAX解析,依然需要100M左右内存。
2.2 POI的内存消耗较大
大部分使用POI都是使用他的userModel模式。userModel的好处是上手容易使用简单,随便拷贝个代码跑一下,剩下就是写业务转换了,虽然转换也要写上百行代码,相对比较好理解。然而userModel模式最大的问题是在于非常大的内存消耗,一个几兆的文件解析要用掉上百兆的内存。现在很多应用采用这种模式,之所以还正常在跑一定是并发不大,并发上来后一定会OOM或者频繁的full gc。
总体上来说,简单写法重度依赖内存,复杂写法学习成本高。
特点
功能强大
代码书写冗余繁杂
读写大文件耗费内存较大,容易OOM
二、SpringBoot整合EasyExcel
1.创建SpringBoot项目
2.导入依赖坐标
注:easyexcel坐标,最新3.1.1版本,推荐使用,一直在更新的版本。
<dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>3.1.1</version> </dependency>
注:项目全部坐标,这里用到lombok插件,开发更简单。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <scope>provided</scope> </dependency> <!--easyExcel--> <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>3.1.1</version> </dependency>
3.创建实体类
注:创建Student实体类,用来与excel表头映射。 这里实体类顺序必须和excel中表头顺序一致,否则会报错,这里应该是最新版本的问题。也可以用注解映射在后面往excel写的时候会讲。
// 基于lombok @Data @NoArgsConstructor @AllArgsConstructor public class Student { /** * 学生姓名 */ private String name; /** * 学生出生日期 */ private Date birthday; /** * 学生性别 */ private String gender; /** * id */ private String id; }
fillData数据测试类
@Data public class FillData { private String name; private int age; }
4.创建监听器
注:必须继承AnalysisEventListener<> 实现invoke与doAfterAllAnalysed方法。
public class StudentReadListener extends AnalysisEventListener<Student> { // 每读一次,会调用该invoke方法一次,就是想对获取到的数据进行什么操作 @Override public void invoke(Student data, AnalysisContext context) { System.out.println("data = " + data); log.info(data + "保存成功"); } // 全部读完之后,会调用该方法(这个暂时用不到) @Override public void doAfterAllAnalysed(AnalysisContext context) { // TODO...... } }
5.在测试类中加入数据生成方法
// 数据生成 private static List<Student> initData(){ List<Student> students=new ArrayList<>(); for (int i = 0; i < 10; i++) { Student data=new Student(); data.setName("测试"+i+2); data.setGender("男"); data.setBirthday(new Date()); students.add(data); } System.out.println(students); return students; }