EasyExcel 优雅实现Excel导入导出
一、简介
传统操作Excel大多都是利用Apach POI进行操作的,但是POI框架并不完善,使用过程非常繁琐且有较多的缺陷。
- 动态操作Excel非常繁琐,对于新手来说,很难在短时间内上手;
- 读写时需要占用较大的内存,当数据量大时容易发生内存溢出问题(OOM);
而EasyExcel 是一个基于 Java 的、快速、简洁、解决大文件内存溢出的 Excel 处理工具。它能让你在不用考虑性能、内存的等因素的情况下,快速完成 Excel 的读、写等功能。
注意:easyExcel底层也是使用POI实现的;
官网地址:https://developer.aliyun.com/article/787306
相关依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.1.3</version>
</dependency>
Excel相关结构说明:
二、EasyExcel导出数据
2.1 定义实体类
在EasyExcel中,以面向对象思想来实现导入导出,无论是导入数据还是导出数据都可以想象成具体某个对象的集合,所以为了实现导出用户信息功能,首先创建一个用户对象UserDO实体类,用于封装用户信息:
@Data
public class UserDO {
@ExcelProperty("用户编号")
@ColumnWidth(20)
private Long id;
@ExcelProperty(value = {"用户名"},index = 1)
@ColumnWidth(20)
private String username;
@ExcelIgnore
private String password;
@ExcelProperty("生日")
@ColumnWidth(20)
@DateTimeFormat("yyyy-MM-dd")
private Date birthday;
@ExcelProperty("身高(米)")
@NumberFormat("#.##")
@ColumnWidth(20)
private Double height;
@ExcelProperty(value = "性别", converter = GenderConverter.class)
@ColumnWidth(10)
private Integer gender;
}
类属性上使用了EasyExcel核心注解解释:
- @ExcelProperty:核心注解,value属性可用来设置表头名称,converter属性可以用来设置类型转换器,index是排序规则,值越大 越靠近右边;
- @ColumnWidth:用于设置表格列的宽度;
- @DateTimeFormat:用于设置日期转换格式;
- @NumberFormat:用于设置数字转换格式。
- @ExcelIgnore:忽略指定表头信息,就不会到处此字段。
2.2 合并表头
添加合并表头信息:
@Data
public class User implements Serializable {
@ExcelProperty(value = {"用户基本信息","用户名"},index = 1)
private String userName;
@ExcelProperty(value = {"用户基本信息","年龄"},index = 2)
private Integer age;
@ExcelProperty(value = {"用户基本信息","地址"} ,index = 4)
private String address;
@ExcelProperty(value = {"用户基本信息","生日"},index = 3)
//注意:日期格式注解由alibaba.excel提供
@DateTimeFormat("yyyy/MM/dd HH:mm")
private Date birthday;
}
2.3 设置单元格大小
@Data
@HeadRowHeight(value = 35) // 表头行高
@ContentRowHeight(value = 25) // 内容行高
@ColumnWidth(value = 50) // 列宽
public class User implements Serializable {
....
}
- @HeadRowHeight:表头行高
- @ContentRowHeight:内容行高
- @ColumnWidth:列宽
2.4 定义导出接口
//EasyExcel.write("C:\\Users\\46035\\Desktop\\ex\\用户.xls",User.class).sheet("用户信息").doWrite(users);
List<UserDO> userList = this.getUserList();
EasyExcel.write(response.getOutputStream())
.head(UserDO.class) //出入的对象类
.excelType(ExcelTypeEnum.XLSX) //导出的文档类型
.sheet("用户列表") //文档名称
.doWrite(userList); //传入的对象
2.5 web数据写出
@GetMapping("download")
public void download(HttpServletResponse response) throws IOException {
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
String fileName = URLEncoder.encode("数据写出", "UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
EasyExcel.write(response.getOutputStream(), DownloadData.class).sheet("模板").doWrite(data());
}
二、EasyExcel导入数据
/**
* excel数据格式必须与实体类定义一致,否则数据读取不到
*/
@Test
public void readExcel(){
ArrayList<User> users = new ArrayList<>();
//读取数据
EasyExcel.read("C:\\Users\\46035\\Desktop\\ex\\用户.xls", User.class, new AnalysisEventListener<User>() {
//开始解析
@Override
public void invoke(User o, AnalysisContext analysisContext) {
System.out.println(o);
users.add(o);
}
//解析完成
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
System.out.println("完成。。。。");
}
}).sheet().doRead();
}
批量导入导出教程:http://t.csdnimg.cn/Zw6ir