一、引言
? ? ? ? 在写Java代码的时候,项目常常需要Java解析、生成Excel文件,而目前比较好的操作Excel库主要是阿里巴巴开源的EasyExcel,其
官网地址是:https://www.yuque.com/easyexcel/doc/easyexcel,
github地址是:https://github.com/alibaba/easyexcel,
对于EasyExcel作者是这样做介绍的:
Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大。easyexcel重写了poi对07版Excel的解析,一个3M的excel用POI sax解析依然需要100M左右内存,改用easyexcel可以降低到几M,并且再大的excel也不会出现内存溢出;03版依赖POI的sax模式,在上层做了模型转换的封装,让使用者更加简单方便
64M内存20秒读取75M(46W行25列)的Excel(3.0.2+版本)
? ? ? ? 从中我们可以知道EasyExcel主要解决了poi框架使用复杂、OOM问题,而EasyExcel解决OOM方式主要是通过解压文件的方式加载,采用一行一行的解析模式,并将一行的解析结果以观察者的模式通知处理,并且抛弃样式字体等不重要的数据,降低内存的等方式。
二、EasyExcel导包
<!--EasyExcel-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.2.6</version>
</dependency>
<!--xls-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.17</version>
</dependency>
<!--xlsx-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.17</version>
</dependency>
三、EasyExcel简单写
? ? ? 1、生成无表头Excel文件
String fileName = "E:\\easyexcel\\write1.xlsx";
OutputStream out = new FileOutputStream(fileName);
ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX, false);
Sheet sheet1 = new Sheet(1, 0);
sheet1.setSheetName("模板");
List<List<String>> data = new ArrayList<>();
for (int i = 0; i < 10; i++) {
List<String> item = new ArrayList<>();
item.add("id-" + i);
item.add("姓名-" + i);
item.add("年级-" + i);
data.add(item);
}
writer.write0(data, sheet1);
writer.finish();
? ?2、生成有表头数据
???
? ? ①:编写实体类
public class Person {
@ExcelProperty("id")
private Integer id;
@ExcelProperty("姓名")
private String name;
@ExcelProperty("年龄")
private Integer age;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
? ?②:生成有表头Excel文件方法1:
List<Person> personList = new ArrayList<>();
for (int i = 1; i <= 10; i++) {
Person person = new Person();
person.setId(i);
person.setName("姓名" + i);
person.setAge(i);
personList.add(person);
}
String fileName = "E:\\easyexcel\\write1.xlsx";
//这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
EasyExcel.write(fileName, Person.class)
.sheet("模板")
.doWrite(personList);
?③生成有表头Excel文件方法2:
List<Person> personList = new ArrayList<>();
for (int i = 1; i <= 10; i++) {
Person person = new Person();
person.setId(i);
person.setName("姓名" + i);
person.setAge(i);
personList.add(person);
}
String fileName = "E:\\easyexcel\\write1.xlsx";
ExcelWriter excelWriter = null;
try {
// 这里 需要指定写用哪个class去写
excelWriter = EasyExcel.write(fileName, Person.class).build();
WriteSheet writeSheet = EasyExcel.writerSheet("模板").build();
excelWriter.write(personList, writeSheet);
} finally {
// 千万别忘记finish 会帮忙关闭流
if (excelWriter != null) {
excelWriter.finish();
}
}
四、EasyExcel简单读
Excel文件:
解析效果:
? ①、编写实体列
public class Person {
@ExcelProperty("id")
private Integer id;
@ExcelProperty("姓名")
private String name;
@ExcelProperty("年龄")
private Integer age;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
? ? ②、编写监听类
package com.example.easyexcel.read;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.example.easyexcel.pojo.Person;
import java.util.Map;
/**
* 定义一个Excel数据监听器(继承 AnalysisEventListener 抽象类)。
* 该监听器不交给 Spring 管理,所以如果需要使用 service、dao 相关的类时,需要通过构造方法引入。
*/
public class ExcelDataListener extends AnalysisEventListener<Person> {
// 一行行读取表格内容
@Override
public void invoke(Person person, AnalysisContext analysisContext) {
System.out.println("Excel内容===========" + person.toString());
}
// 读取表头内容
@Override
public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
System.out.println("Excel表头内容========" + headMap);
}
// 读取完成后的操作
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
System.out.println("Excel读取完成========");
}
}
????③、调用
@Test
public void excelReadTest() {
// 读取文件的位置
String fileName = "E:\\easyexcel\\write1.xlsx";
EasyExcel.read(fileName, Person.class, new ExcelDataListener()).sheet().doRead();
}
? ?
|