使用EasyExcel导入导出
一,为什么要使用EasyExcel
1.1 EasyExcel与Poi的区别
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模式,在上层做了模型转换的封装,让使用者更加简单方便
具体详细可参考官方文档
- 官方网站:https://easyexcel.opensource.alibaba.com/
- github地址:https://github.com/alibaba/easyexcel
- gitee地址:https://gitee.com/easyexcel/easyexcel
二,简单使用EasyExcel完成导入导出功能
2.1 导入EasyExcel依赖
在pom.xml文件中引入相关依赖
<!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.1.1</version>
</dependency>
2.2 导出
2.2.1 编写相关的工具类
在util包下创建一个ExportFileUtil(名字可任取)里边是导出Excel文件的默认地址
public class ExportFileUtil {
//文件导出地址设置为D盘 你自己可以设置 方法有很多
public static String getPath() {
return "E:/";
}
}
2.2.2 编写Pojo实体类
这个类需要和你导出的Excel表相对应,每个属性就是你的Excel表的字段
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@EqualsAndHashCode
/**
* 导出的学生表实体对象
* */
public class ExportStudent implements Serializable {
@ExcelIgnore // Excel表忽略此属性
private String id;
@ExcelProperty("姓名") // 生成Excel表的字段名
@ColumnWidth(20) // Excel表格的宽度
private String name;
@ExcelProperty("性别")
@ColumnWidth(20)
private String sex;
@ExcelProperty("学号")
@ColumnWidth(20)
private String studentID;
@ExcelProperty("班级")
@ColumnWidth(20)
private String className;
@ExcelProperty("楼宇")
@ColumnWidth(20)
private String building;
@ExcelProperty("宿舍号")
@ColumnWidth(20)
private String room;
@ExcelProperty("邮箱")
@ColumnWidth(20)
private String email;
@ExcelProperty("电话")
@ColumnWidth(20)
private String phone;
@ExcelProperty("入住时间")
@ColumnWidth(20)
private String livedTime;
}
这里有一个地方需要注意:如果你用了Hutool工具,请不要用@Accessors(chain = true)链式写法,否词导入的时候会报空指针错误
2.2.3 编写Controller控制层
/**
* 导出数据
* */
@RequestMapping("exportStudent")
@ResponseBody
public R exportStudent(){
// 生成相应的文件名
String fileName = ExportFileUtil.getPath()+"ExportStudent"+ System.currentTimeMillis()+".xlsx";
// 这里需要指定写用哪个class去写,然后写到第一个sheet,名字为用户表 然后文件流会自动关闭
List<Student> studentList = studentService.findStudent();
EasyExcel.write(fileName,ExportStudent.class).sheet("学生信息表").doWrite(studentList);
return R.ok("导出成功!请在E盘下查看!");
}
2.2.4 测试
前面的工作已经准备好就可以进行导出Excel表数据了,前端的代码就不献丑了。
导出后的Excel表就在你设置的路径下。
2.3 导入
导出其实也不难,与导入也差不多。
2.3.1 编写Controller层
由于我这里是多个表联合,所以需要进行转换,自行分辨拿取所需代码。
在进行数据写入数据库前应进行处理,如果数据库已存在该数据则不进行写入,或者修改原有数据而不是新增一条数据
@RequestMapping("importExcel")
@ResponseBody
public R upload(MultipartFile file) throws IOException {
// 这里 需要指定读用哪个class去读,然后读取第一个sheet,文件流会自动关闭
// 这里每次会读取3000条数据,然后返回过来,直接调用使用数据就行
if (file!=null) {
EasyExcel.read(file.getInputStream(), ExportStudent.class, new PageReadListener<ExportStudent>(
exportStudentList -> {
//将导入的数据用mybatisPlus一个个添加进数据库,其实最好的方法是自己写一个sql语句一次性插入多条数据
for (ExportStudent exportStudent : exportStudentList) {
if(!studentService.findStudentByStudentID(exportStudent.getStudentID())) {
Building building = buildingService.findBuildingByName(exportStudent.getBuilding());
Room room = roomService.findRoomByRoomAndBuildingId(exportStudent.getRoom(), building.getId());
SchoolClass className = schoolClassService.findClassByClassName(exportStudent.getClassName());
Student student = new Student();
student.setName(exportStudent.getName()).setSex(exportStudent.getSex()).setStudentID(exportStudent.getStudentID())
.setEmail(exportStudent.getEmail()).setRoomId(room.getId()).setLivedTime(exportStudent.getLivedTime())
.setPassword(exportStudent.getStudentID()).setPhone(exportStudent.getPhone()).setClassId(className.getId());
studentService.save(student);
}
}
}
)).sheet().doRead();
return R.ok("导入成功!");
}
return R.ok("导入失败!");
}
在导入之前应提示下载导入模板,这样给用户的体验会更加友好,我这里就不展示自己写了一个Excel表进行导入,表的字段也需对应Excel实体类
到这里简单的EasyExcel导入导出就可以实现了,新手分享一下自己的学习,各位大佬勿喷!!!