EasyExcel 基础入门
1. 简介:
EasyExcel是一个基于Java的简单、省内存的读写Excel的开源项目。在尽可能节约内存的情况下支持读写百M的Excel。
2.官方网站
https://github.com/alibaba/easyexcel
快速开始:https://www.yuque.com/easyexcel/doc/easyexcel
3. EasyExcel特点
- Java领域解析、生成Excel比较有名的框架有Apache poi、jxl等。但他们都存在一个严重的问题就是非常的耗内存。如果你的系统并发量不大的话可能还行,但是一旦并发上来后一定会OOMZ或者JVM频繁的full gc。
- EasyExcel是阿里巴巴开源的一个excel处理框架,以使用简单、节省内存著称。EasyExcel能大大减少占用内存的主要原因是在解析Excel时没有将文件数据一次性全部加载到内存中,而是从磁盘上一行行读取数据,逐个解析(代码中会有体现)。
- EasyExcel采用一行一行的解析模式,并将一行的解析结果以观察者的模式通知处理(AnalysisEventListener)。
pom.xml 引入依赖
com.alibaba
easyexcel
2.1.7
org.apache.xmlbeans
xmlbeans
3.1.0
org.projectlombok
lombok
1.18.10
junit
junit
4.12
4.最简单的写
1.创建实体类
package com.atguigu.easyexcel.entity;
@Data
public class ExcelStudentData {
@ExcelProperty("姓名")
private String name;
@ExcelProperty("生日")
private Date birthday;
@ExcelProperty("薪资")
private Double salary;
/**
* 忽略这个字段
*/
@ExcelIgnore
private String password;
}
2.测试用例
- 07版本的Excel和03版本的写入方式有所不同
- 03版本的Excel写入最多一次可写65536行 !!!!!(取除表格65535行,其实就怕占用过多内存,让机器宕机)
public class WriteTest {
@Test
public void simpleExcelWrit07(){
String fileName = "G:\\5.项目\\谷粒学院\\java\\aliyunEasyExcel\\test01-07.xlsx";
EasyExcel.write(fileName, ExcelStudentData.class)
.sheet("Sheet1")
.doWrite(data());
}
@Test
public void simpleExcelWrit03(){
String fileName = "G:\\5.项目\\谷粒学院\\java\\aliyunEasyExcel\\test01-03.xls";
EasyExcel.write(fileName, ExcelStudentData.class)
.excelType(ExcelTypeEnum.XLS)
.sheet("Sheet1")
.doWrite(data());
}
public List data(){
List list = new ArrayList();
for (int i = 0; i < 10; i++) {
ExcelStudentData student = new ExcelStudentData();
student.setName("summer"+i);
student.setBirthday(new Date());
student.setSalary(0.232);
list.add(student);
}
return list;
}
}
03写的时候:
EasyExcel.write(fileName, ExcelStudentData.class)
.excelType(ExcelTypeEnum.XLS)
.sheet("Sheet1")
.doWrite(data());
多一个.excelType(ExcelTypeEnum.XLS)
注意:
使用07写的方式确实可以写03版的Excel,但是这样写出的文件再使用03版读不出来了。
我们在写的时候一定要注意文件后缀
03 -> .xls
07 ->.xlsx
3.指定写入列
为列配置 index 属性
package com.atguigu.easyexcel.entity;
@Data
public class ExcelStudentData {
@ExcelProperty(value = "姓名", index = 0)
private String name;
@ExcelProperty(value = "生日", index = 1)
private Date birthday;
/**
* 这里设置3 会导致第二列空的
*/
@ExcelProperty(value = "薪资", index = 3)
private Double salary;
/**
* 忽略这个字段
*/
@ExcelIgnore
private String password;
}
4.自定义格式转换
配置时间格式:@DateTimeFormat
配置数字格式:@NumberFormat
package com.atguigu.easyexcel.entity;
@Data
public class ExcelStudentData {
@ExcelProperty(value = "姓名")
private String name;
@DateTimeFormat("yyyy年MM月dd日HH时mm分ss秒")
@ExcelProperty(value = "生日")
private Date birthday;
@NumberFormat("#.##%")//百分比表示,保留两位小数
@ExcelProperty(value = "薪资")
private Double salary;
/**
* 忽略这个字段
*/
@ExcelIgnore
private String password;
}
5.最简单的读
1、参考文档
https://www.yuque.com/easyexcel/doc/read
2、创建监听器
EasyExcel是阿里巴巴开源的一个excel处理框架,以使用简单、节省内存著称。EasyExcel能大大减少占用内存的主要原因是在解析Excel时没有将文件数据一次性全部加载到内存中,而是从磁盘上一行行读取数据,逐个解析(代码中会有体现)。
public class ExcelStudentDataListener extends AnalysisEventListener {
// 设置阈值当读取行数达到阈值时,就将数据存入数据库
// 避免内占用过多,导致内存溢出
private final static int BASE_COUNT = 3;
// 使用list集合存储数据
private List list = new ArrayList();
/**
* 每读一行就执行一次invoke
* @param data 每行数据
* @param context
*/
public void invoke(ExcelStudentData data, AnalysisContext context) {
System.out.println(data);
list.add(data);
if (list.size()>BASE_COUNT){
System.out.println("数据存入数据库");
System.out.println("清空list");
list.clear();
}
}
/**
* Excel全部数据读取结束执行此方法
* @param context
*/
public void doAfterAllAnalysed(AnalysisContext context) {
System.out.println("将剩余的数据读入数据库");
System.out.println("数据读取结束");
}
}
3、测试用例
public class ReadTest {
/**
* 最简单的读
*/
@Test
public void ReadTest07(){
String fileName = "G:\\5.项目\\谷粒学院\\java\\aliyunEasyExcel\\test01-07.xlsx";
// 这里默认读取第一个sheet
EasyExcel.read(fileName, ExcelStudentData.class, new ExcelStudentDataListener()).sheet().doRead();
}
@Test
public void ReadTest03(){
String fileName = "G:\\5.项目\\谷粒学院\\java\\aliyunEasyExcel\\test01-03.xls";
// 这里默认读取第一个sheet
EasyExcel.read(fileName, ExcelStudentData.class, new ExcelStudentDataListener()).excelType(ExcelTypeEnum.XLS).sheet(0).doRead();
}
}