SpringBoot(六) - 阿里巴巴的EasyExcel
1、依赖
<!-- 阿里EasyExcel start -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.1.7</version>
</dependency>
2、写入Excel
2.1 实体
@Data
public class Student {
//学号
@ExcelProperty("学号")
private Integer id;
// 姓名
@ExcelProperty("姓名")
private String name;
// 年龄
@ExcelProperty("年龄")
private Integer age;
// 班级
@ExcelProperty("班级")
private String classRoom;
// 性别
@ExcelProperty("性别")
private String sex;
// 院校
@ExcelProperty("院校")
private String graduate;
// 毕业时间
@DateTimeFormat("yyyy年MM月dd日HH时mm分ss秒")
@ExcelProperty("毕业时间")
private Date graduateTime;
// 手机号
@ExcelProperty("手机号")
private String phone;
//@NumberFormat("#.#") //保留1位小数
//@ExcelProperty(value = "薪资", index = 3) //设置表图和指定的列, 将工资放在 第四列
//@ExcelIgnore 忽略字段,比如密码
}
2.2 实体的数据监听器
@Slf4j
public class StudentDataListener extends AnalysisEventListener<Student> {
/**
* 每隔5条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收
*/
private static final int BATCH_COUNT = 5; //实际操作的时候看情况修改
List<Student> list = new ArrayList<>();
/**
* 这个每一条数据解析都会来调用
*
* @param data
* one row value. Is is same as {@link AnalysisContext#readRowHolder()}
* @param context
*/
@Override
public void invoke(Student data, AnalysisContext context) {
log.info("解析到一条数据:{}", data);
list.add(data);
// 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
if (list.size() >= BATCH_COUNT) {
log.info("存数据库");
// 批量插入
// 存储完成清理 list
list.clear();
}
}
/**
* 所有数据解析完成了 都会来调用
*
* @param context
*/
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
log.info("所有数据解析完成!");
}
//为了方便获取读取的数据
public List<Student> getList() {
return list;
}
}
2.3 03版本的Excel写入
@Test
public void testExcel03(){
//要写入的文件的路径
String fileName = "D:\\KEGONGCHANG\\DaiMa\\IDEA\\KH96\\SpringBoot\\SpringBoot\\springboot-03-asyztimer\\excel\\excel03_student.xls";
// 如果这里想使用03 则 传入excelType参数即可
//获取学生信息,实际应用中从数据库中查询出来即可,list集合
Student student = Student.builder().id(19).name("huayu").age(19)
.classRoom("KH96").sex("男").graduate("金科")
.graduateTime(new Date()).phone("13501020304").build();
List<Student> studentList = new ArrayList<>();
studentList.add(student);
//将数据写入文件
EasyExcel.write(fileName, Student.class)
.excelType(ExcelTypeEnum.XLS)
.sheet("学生信息")
.doWrite(studentList);
log.info("学生信息写入完成!!!{}",student);
}
测试结果:
2.4 07版本的Excel 写入
@Test
public void testExcel07(){
//要写入的文件的路径
String fileName = "D:\\KEGONGCHANG\\DaiMa\\IDEA\\KH96\\SpringBoot\\SpringBoot\\springboot-03-asyztimer\\excel\\excel07_student.xls";
//获取学生信息
studentList.add(student);
//07版写入文件
EasyExcel.write(fileName, Student.class)
.sheet("学生信息")
.doWrite(studentList);
log.info("学生信息写入完成!!!{}",student);
}
测试结果:
2.5 写入多个sheet
@Test
public void testWriteSheets(){
String fileName = "D:\\KEGONGCHANG\\DaiMa\\IDEA\\KH96\\SpringBoot\\SpringBoot\\springboot-03-asyztimer\\excel\\excel07_student_sheets.xlsx";
//获取学生信息
studentList.add(student);
// 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
ExcelWriter excelWriter = EasyExcel.write(fileName, Student.class).build();
WriteSheet sheet;
for (int i = 0; i < 2; i++) {
sheet = EasyExcel.writerSheet(i, "学生信息"+(i+1)).build();
excelWriter.write(studentList,sheet);
}
excelWriter.finish();
log.info("学生信息写入完成!!!{}",student);
}
测试结果:
3、读出Excel
3.1 doRead()
3.1.1 sheet1中的数据
sheet1:
3.1.2 doRead() 方法读取
//读取Excel中的学生信息
@Test
public void testReadExcel(){
String fileName = "D:\\KEGONGCHANG\\DaiMa\\IDEA\\KH96\\SpringBoot\\SpringBoot\\springboot-03-asyztimer\\excel\\excel07_student_sheets.xlsx";
// 实例化一个数据监听器
StudentDataListener studentDataListener = new StudentDataListener();
//第一种
//读取后的数据放进list中,所以可以从list中获取数据,(这里的数据是我们处理过的,最多返回5条的数据,可以根据实际境况修改)
EasyExcel.read(fileName, Student.class,studentDataListener)
.sheet() //默认读取第一个sheet
.doRead();
List<Student> list = studentDataListener.getList();
log.info("------ 读取后的数据放进list中,所以可以从list中获取数据,最多返回5条的数据 ------");
list.forEach(ersonData->{
log.info(ersonData.toString());
});
}
3.1.3 测试结果:
3.1.4 分析 doRead() 方法
//没有任何数据返回
public void doRead() {
if (this.excelReader == null) {
throw new ExcelGenerateException("Must use 'EasyExcelFactory.read().sheet()' to call this method");
} else {
this.excelReader.read(new ReadSheet[]{this.build()});
this.excelReader.finish();
}
}
3.2 doReadSync()
3.2.1 sheet2中的数据
sheet2:
3.2.2 doReadSync() 方法读取
//读取Excel中的学生信息
@Test
public void testReadExcel(){
String fileName = "D:\\KEGONGCHANG\\DaiMa\\IDEA\\KH96\\SpringBoot\\SpringBoot\\springboot-03-asyztimer\\excel\\excel07_student_sheets.xlsx";
// 实例化一个数据监听器
StudentDataListener studentDataListener = new StudentDataListener();
//第二种
log.info("------ 同步获取数据,读取到的所有数据 ------");
//同步获取数据,读取到的所有数据
List<Student> list2 = EasyExcel.read(fileName, Student.class,studentDataListener)
.sheet(1) //读取第二个sheet
.doReadSync();
list2.forEach(ersonData->{
log.info(ersonData.toString());
});
}
3.2.3 测试结果:
3.2.4 分析 doReadSync() 方法
//会将读取到的数据返回
public <T> List<T> doReadSync() {
if (this.excelReader == null) {
throw new ExcelAnalysisException("Must use 'EasyExcelFactory.read().sheet()' to call this method");
} else {
SyncReadListener syncReadListener = new SyncReadListener();
this.registerReadListener(syncReadListener);
this.excelReader.read(new ReadSheet[]{this.build()});
this.excelReader.finish();
return syncReadListener.getList();
}
}