简介
Java领域解析,生成Excel比较有名的框架有Apache poi,jxl等,但他们都存在一个严重的问题就是非常的耗内存,如果你的系统并发量不大的话可能还行,但是一旦并发上来后一定会OOM或者JVM频繁的full gc.
EasyExcel是阿里巴巴开源的一个excel处理框架,以使用简单,节省内存著称,EasyExcel能大大减少占用内存的主要原因是在解析Excel时没有将文件数据一次性全部加载到内存中,而是从磁盘上一行行读取数据,逐个解析。
EasyExcel采用一行一行的解析模式,并将一行的解析结果以观察者的模式通知处理(AnalysisEventListener)。
参考官方文档
引入maven依赖
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.17</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.17</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.1.1</version>
</dependency>
<!-- 使用注解方式生成getset方法 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
实现写操作
创建实体类
@Data
public class User {
@ExcelProperty("学生姓名")
private String name;
@ExcelProperty("年龄")
private String age;
private Date createTime;
}
具体实现
public static void main(String[] args) {
// 写法一
// 实现Excel写操作
// 1. 设置写入文件夹地址和Excel文件名称
String filename = "/User/evan/Desktop/01.xlsx";
// 2. 调用easyExcel里面的方法实现写操作
// 文件名称和实体类
EasyExcel.write(filename, User.class).sheet("学生列表").doWrite(getData());
// 方法一会自动关闭流
//===============>>>>>>>>===============
// 写法二
String filename = "/User/evan/Desktop/01.xlsx";
// 指定class进行读写
ExcelWirte excelwriter = EasyExcel.wirte(filename, User.class).build();
WriteSheet writeSheet = EasyExcel.writerSheet("写入方法二").build();
excelwriter.write(data(), writeSheet);
// 关闭流
excelwriter.finish();
}
private static List<User> getData() {
List<User> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
User user = new User();
user.setName("张三");
user.setAge("99" + i);
list.add(user);
}
return list;
}
效果
实现读操作
创建实体类,标记对应的关系
@Data
@ToString
public class User {
@ExcelProperty("学生姓名")
private String name;
@ExcelProperty("年龄")
private String age;
private Date createTime;
}
创建监听器
每次读取都是从监听器那获取数据
默认有两个方法
public class ExcelListener extends AnalysisEventListener<User> {
// 创建list集合封装最终的数据
List<User> list = new ArrayList<>();
// 一行一行读取Excel内容
@Override
public void invoke(User readData, AnalysisContext analysisContext) {
System.out.println("***" + readData);
list.add(readData);
}
// 读取表头内容(在AnalysisEventListener有这个方法)
@Override
public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
System.out.println( "表头信息:"+ headMap);
}
// 读取完后执行
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
}
}
实现
public static void main(String[] args) {
String filename = "/Users/evan/Library/Containers/com.microsoft.Excel/Data/Desktop/01.xlsx";
EasyExcel.read(filename, User.class, new ExcelListener()).sheet().doRead();
}
效果
表头信息:{
0=学生姓名, 1=年龄, 2=createTime}
***User(name=张三, age=990, createTime=null)
***User(name=张三, age=991, createTime=null)
***User(name=张三, age=992, createTime=null)
***User(name=张三, age=993, createTime=null)
***User(name=张三, age=994, createTime=null)
***User(name=张三, age=995, createTime=null)
***User(name=张三, age=996, createTime=null)
***User(name=张三, age=997, createTime=null)