EasyExcel是阿里巴巴开源的一个excel处理框架,以使用简单,节省内存著称.(在poi的基础上进行了封装,优化了poi学习成本高,内存消耗大的问题)
/**
*业务场景 我们在开发当中很容易会遇到一种场景就是读写excel
*下面就是最简单的一维excel
*/
//excel数据格式
姓名 出生日期 性别
xx xx xx
// 导入坐标
<!-- EasyExcel -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.1.6</version>
</dependency>
<!-- lombok 简化开发 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
</dependency>
//创建实体类
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
private String name;
private String gender;
private Date birthday;
private String id;
}
//书写监听器,处理产生的数据
public class StudentReadListener extends AnalysisEventListener<Student> {
// 每读一样,会调用该invoke方法一次
@Override
public void invoke(Student data, AnalysisContext context) {
System.out.println("data = " + data);
}
// 全部读完之后,会调用该方法
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
// TODO......
}
}
public class Test {
public static void main(String[] args) throws FileNotFoundException {
// 读取文件,读取完之后会自动关闭
/*
pathName 文件路径;
head 每行数据对应的实体;Student.class
readListener 读监听器,每读一样就会调用一次该监听器的invoke方法
sheet方法参数: 工作表的顺序号(从0开始)或者工作表的名字,不传默认为0
*/
// 封装工作簿对象
//观察其 构造方法发现可以传流的
ExcelReaderBuilder read = EasyExcel.read("C:\\Users\\86183\\Desktop\\info.xlsx", Student.class, new StudentReadListener());
ExcelReaderSheetBuilder sheet = read.sheet();
sheet.doRead();
}
}
@ContentRowHeight() 标注在类上或属性上,指定内容行高
@HeadRowHeight() 标注在类上或属性上,指定列头行高
@ColumnWidth() 标注在类上或属性上,指定列宽
ExcelIgnore` 默认所有字段都会写入excel,这个注解会忽略这个字段
DateTimeFormat
日期转换,将Date
写到excel会调用这个注解。里面的value
参照java.text.SimpleDateFormat
NumberFormat
数字转换,用Number
写excel会调用这个注解。里面的value
参照java.text.DecimalFormat
ExcelIgnoreUnannotated
默认不加 ExcelProperty
的注解的都会参与读写,加了不会参与
package com.itheima.domain;
@Data
@AllArgsConstructor
@NoArgsConstructor
@ColumnWidth(20)
public class Student {
//@ExcelProperty(value = "编号",index = 3)
@ExcelIgnore
private String id;
@ExcelProperty(value = "学生姓名", index = 0)
//@ColumnWidth(30)
private String name;
@ExcelProperty(value = "学生性别", index = 2)
private String gender;
@ExcelProperty(value = "学生出生日期", index = 1)
//@ColumnWidth(20)
private Date birthday;
}
/* 参数说明
String pathName 写入文件的路径
Class head 写入文件的对象类型
默认写入到07的xlsx中,如果想要写入xls,可以指定类型(待验证)
*/
public static void main(String[] args) {
ExcelWriterBuilder write = EasyExcel.write("C:\\Users\\86183\\Desktop\\info-2.xlsx", Student.class);
List<Student> data = getData();
write.sheet().doWrite(data);
}
private static List<Student> getData() {
ArrayList<Student> students = new ArrayList<>();
for (int i = 0; i < 10; i++) {
Student data = new Student();
data.setName("lujun" + i);
data.setBirthday(new Date());
data.setGender("男");
students.add(data);
}
return students;
}
@Component
@Scope("prototype") // 作者要求每次读取都要使用新的Listener
public class StudentReadListener extends AnalysisEventListener<Student> {
@Autowired
private StudentService studentService;
//达到一定的数量就调用数据库的保存方法
private final int BATCH_SAVE_NUM = 5;
ArrayList<Student> students = new ArrayList<>();
private int count = 0;
// 每读一样=行,会调用该invoke方法一次
@Override
public void invoke(Student data, AnalysisContext context) {
students.add(data);
if (++count % BATCH_SAVE_NUM == 0) {
studentService.save(students);
students.clear();
}
}
// 全部读完之后,会调用该方法
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
// TODO......
}
}
@Controller
public class ExcelController {
@PostMapping("upload")
@ResponseBody
public String upload(MultipartFile file) throws IOException {
ExcelReaderBuilder workBook = EasyExcel.read(file.getInputStream(), Student.class, studentReadListener);
workBook.sheet().doRead();
return "xx";
}
1.实体类略过
2.controller
public class WebUploadAndDownload {
@GetMapping("download")
public void download(HttpServletResponse response) throws IOException {
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
// 防止中文乱码
String fileName = URLEncoder.encode("test", "UTF-8");
response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + fileName + ".xlsx");
ExcelWriterBuilder workBook = EasyExcel.write(response.getOutputStream(), Student.class);
ExcelWriterSheetBuilder sheet = workBook.sheet("模板");
sheet.doWrite(getData);
}
}
Excel表格中用{} 来表示包裹要填充的变量,如果单元格文本中本来就有{
、}
左右大括号,需要在括号前面使用斜杠转义\{
、\}
。
代码中被填充数据的实体对象的成员变量名或被填充map集合的key需要和Excel中被{}包裹的变量名称一致。
@Data
public class FillData {
private String name;
private int age;
}
// 两种填充方式一种实体类一种map
public static void main(String[] args) {
// 加载模板
InputStream templateFile = FillData.class.getClassLoader().getResourceAsStream(
"fill_data_template1" +
".xlsx");
// 写入文件
String targetFileName = "填充数据.xlsx";
// 准备对象数据填充
FillData fillData = new FillData();
fillData.setName("demon");
fillData.setAge(10);
// 生成工作簿对象
ExcelWriterBuilder workBookWriter = EasyExcel.write(targetFileName).withTemplate(templateFile);
// 获取工作表并填充
//workBookWriter.sheet().doFill(fillData);
// 使用Map数据填充
HashMap<String, String> mapFillData = new HashMap<>();
mapFillData.put("name", "mapdemon");
mapFillData.put("age", "11");
// 获取第一个工作表填充并自动关闭流
workBookWriter.sheet().doFill(mapFillData);
}
public static void main(String[] args) {
InputStream templateFile = FillData.class.getClassLoader().getResourceAsStream(
"fill_data_template3.xlsx");
// 目标文件
String targetFileName = "组合数据填充.xlsx";
List<FillData> fillDatas = initData();
ExcelWriter excelWriter = EasyExcel.write(targetFileName).withTemplate(templateFile).build();
WriteSheet writeSheet = EasyExcel.writerSheet().build();
// 组合填充时,因为多组填充的数据量不确定,需要在多组填充完之后另起一行
FillConfig fillConfig = FillConfig.builder().forceNewRow(true).build();
// 填充并换行
excelWriter.fill(fillDatas, fillConfig, writeSheet);
HashMap<String, String> otherData = new HashMap<>();
otherData.put("date", "2021-03-14");
otherData.put("total", "130");
excelWriter.fill(otherData, writeSheet);
// 关闭
excelWriter.finish();
}
public static void main(String[] args) {
InputStream templateFile = FillData.class.getClassLoader().getResourceAsStream(
"fill_data_template4.xlsx");
// 写入文件
String targetFileName = "easyExcelDemo\\水平数据填充.xlsx";
List<FillData> fillDatas = initData();
// 生成工作簿对象
ExcelWriter excelWriter = EasyExcel.write(targetFileName).withTemplate(templateFile).build();
// 生成工作表对象
WriteSheet writeSheet = EasyExcel.writerSheet().build();
// 组合填充时,因为多组填充的数据量不确定,需要在多组填充完之后另起一行
FillConfig fillConfig = FillConfig.builder().direction(WriteDirectionEnum.HORIZONTAL).build();
// 填充
excelWriter.fill(fillDatas, fillConfig, writeSheet);
HashMap<String, String> otherData = new HashMap<>();
otherData.put("date", "2021-05-14");
otherData.put("total", "120");
excelWriter.fill(otherData, writeSheet);
// 关闭
excelWriter.finish();
}