文章目录
- 写在前面
- 1、maven依赖
- 2、导入Excel文件
- 2.1、读取表格文件
- 2.2、如果有多个sheet表格
- 2.3、监听器封装(也可不封装)
- 2.4、读取数据格式化(实体类中添加注解)
- 3、导出Excel文件
- 3.1、导出表格格式(实体类中添加注解)
- 3.2、添加表头样式
- 4、注意事项
- 4.1、实体类字段set方法,不能返回this
- 4.2、EasyExcel 和 EasyExcelFactory 的区别
- 4.3、HSSFWorkbook、XSSFWorkbook、Workbook
写在前面
EasyExcel是阿里巴巴开源的一个excel处理框架,以使用简单、节省内存著称。
github文档: https://github.com/alibaba/easyexcel
1、maven依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.2.3</version>
</dependency>
2、导入Excel文件
常用如下两种读取方式
EasyExcel.read(文件名/文件流,数据实体类.class,监听器).sheet().doRead();
EasyExcel.read(文件名/文件流,数据实体类.class,监听器).build();
2.1、读取表格文件
实例1:
(这里假设已有实体类User)
public void test1() {
EasyExcel.read("D:\\file\\1.xlsx", User.class, new AnalysisEventListener<User>() {
// 每解析一行数据,该方法会被调用一次
@Override
public void invoke(User user, AnalysisContext analysisContext) {
System.out.println("解析数据为:" + user.toString());
}
// 全部解析完成被调用
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
System.out.println("解析完成...");
// 保存到数据库
}
}).sheet().doRead();
}
实例2:spring项目中导入一个excel文件
(这里假设已有实体类User)
// springboot 接口
@PostMapping("/importUser")
public void importUser(@RequestParam("file") MultipartFile file)
ExcelReader excelReader = EasyExcel.read(file.getInputStream(), User.class, new AnalysisEventListener<DemoData>() {
@Override
public void invoke(User user, AnalysisContext analysisContext) {
System.out.println("解析数据为:" + user.toString());
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
System.out.println("解析完成...");
// 保存到数据库
}
}).build();
ReadSheet sheet = EasyExcel.readSheet(0).build(); // 创建sheet对象,读取Excel的第一个sheet, 也可以根据sheet名称获取
excelReader.read(sheet); // 读取sheet表格数据,可以读取多个sheet
excelReader.finish(); // 这里必须手动关闭
}
2.2、如果有多个sheet表格
读取多个sheet表格
// 方式1
EasyExcel.read(...)
// .sheet(0).doRead();
.doReadAll(); // 读取全部sheet
// 方式2
ExcelReader excelReader = EasyExcel.read(...) .build();
ReadSheet sheet = EasyExcel.readSheet(0).build();
//excelReader.read(sheet);
excelReader.readAll(); // 读所有sheet
excelReader.finish();
// 读指定的多个sheet
ExcelReader excelReader = EasyExcel.read(...) .build();
ReadSheet sheet = EasyExcel.readSheet(0).build();
// 读取sheet,有几个就构建几个sheet进行读取
excelReader.read(sheet0);
excelReader.finish();
2.3、监听器封装(也可不封装)
每次调用 EasyExcel.read() 都需要 new 一个 AnalysisEventListener 对象,我们可以将AnalysisEventListener封装为一个对象,方便重复调用
public class EasyExcelUtils<T> {
/**
* 获取读取Excel的监听器对象
* @param consumer 处理解析数据的函数, 一般可以是数据入库逻辑的函数
* @param threshold 阈值,达到阈值就处理一次存储的数据
* @param <T> 数据模型泛型
* @return 返回监听器
*/
public static <T> AnalysisEventListener<T> getReadListener(Consumer<List<T>> consumer, int threshold) {
return new AnalysisEventListener<T>() {
// ArrayList 查询更快
// List<T> dataList = new ArrayList<>(threshold);
// LinkedList 插入和删除更快
List<T> dataList = new LinkedList<>();
/**
* 每解析一行调用, 订阅者1
* @param data 解析的每行数据
* @param context
*/
@Override
public void invoke(T data, AnalysisContext context) {
dataList.add(data);
// 达到阈值就处理一次存储的数据
if (dataList.size() >= threshold) {
consumer.accept(dataList);
dataList.clear();
}
}
/**
* excel文件解析完成后,事件调度中心会通知到该方法, 订阅者2
* @param context
*/
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
// 最后阈值外的数据做处理
if (dataList.size() > 0) {
consumer.accept(dataList);
}
}
};
}
/**
* 获取读取Excel的监听器对象, 不指定阈值, 默认阈值为 2000
*/
public static <T> AnalysisEventListener<T> getReadListener(Consumer<List<T>> consumer) {
return getReadListener(consumer, 2000);
}
}
使用示例
// 读取excel文件
public void test() {
EasyExcel.read("user.xlsx", User.class,EasyExcelUtils.getReadListener(dataProcess())).doReadAll();
}
// 处理数据
public Consumer<List<User>> dataProcess() {
return users -> users.forEach(System.out::println);
}
2.4、读取数据格式化(实体类中添加注解)
在实体类中加入注解可以格式化数据,
与lombok结合使用。
@NoArgsConstructor
@AllArgsConstructor
@Data
@Builder
public class User {
@ExcelProperty(value = "字符串标题", index = 0)
private String name;
@ExcelProperty(value = "日期标题", index = 1)
@DateTimeFormat(value = "yyyy年MM月dd日 HH时mm分ss秒") // 格式化日期类型数据
private Date hireDate;
@ExcelProperty(value = "数字标题", index = 2)
@NumberFormat(value = "###.#") // 格式化数字类型数据,保留一位小数,@NumberFormat不能用在Double类型中
private String salary;
}
3、导出Excel文件
// 1、根据实体对象导出文件
EasyExcel.write(response.getOutputStream(), 实体.class).sheet().doWrite(list<实体>);
// 2、根据List<List<String>>导出文件
EasyExcel.write(response.getOutputStream()).head(表头list对象).sheet().doWrite(数据list对象);
// 3、根据模板文件
ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).withTemplate(new ClassPathResource("模板.xlsx").getInputStream()).build();
WriteSheet writeSheet = EasyExcel.writerSheet().build();
excelWriter.fill(list实体对象, writeSheet); // 填充数据1
excelWriter.fill(map对象, writeSheet); // 填充数据2
excelWriter.finish(); // 关闭流
实例:spring项目中导出excel文件
@PostMapping("/getExcel")
public void getExcel(HttpServletResponse response)
try{
String fileName = "表格文件名.xlsx";
List<数据实体类> data = new ArrayList<>();
fileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8.toString());
response.addHeader("Content-Disposition", "attachment;filename=" + fileName);
EasyExcelFactory.write(response.getOutputStream(), 数据实体类.class)
.sheet("这是一张表名")
.doWrite(data);
response.getOutputStream().flush();
}finally {
response.getOutputStream().close();
}
}
3.1、导出表格格式(实体类中添加注解)
在实体类中定义
@Data
@NoArgsConstructor
//@ContentRowHeight(50)//内容单元格高度
//@HeadRowHeight(50)//表头单元格高度
//@ColumnWidth(50)//单元格宽度
public class User {
@ExcelProperty(value = {"导出台账","序号"})
private Integer no;
@ExcelProperty(value = {"导出台账","编号"})
private String code;
}
3.2、添加表头样式
EasyExcelFactory.write(...).sheet("表名").registerWriteHandler(new 表头样式对象());
表头样式类型必须继承自CellWriteHandler
public class MyCellWriteHandler implements CellWriteHandler {...}
4、注意事项
4.1、实体类字段set方法,不能返回this
实体类字段set方法,不能返回this,否者读表格时,无法写入数据到实体类。
也意味着实体类不能添加链式相关注解,例如:lombok的@Accessors(chain = true)
4.2、EasyExcel 和 EasyExcelFactory 的区别
EasyExcel.read(…) 和 EasyExcelFactory.read(…) 有区别吗?
没区别。
下面是EasyExcel的源码
package com.alibaba.excel;
public class EasyExcel extends EasyExcelFactory {
public EasyExcel() {
}
}
你没有看错,EasyExcel.java的源码就这么点
4.3、HSSFWorkbook、XSSFWorkbook、Workbook
Workbook 是 HSSFWorkbook、XSSFWorkbook的基类
HSSFWorkbook:是操作Excel2003以前(包括2003)的版本,扩展名是.xls
XSSFWorkbook:是操作Excel2007的版本,扩展名是.xlsx