EasyExcel文档
我用过Poi和EasyPoi这些工具总体来说:
下面来说说今天的主角EasyExcel,这个项目是阿里巴巴开发的开源的,专门针对大数据批量处理,比如100万+
的Excel数据这种,会比以上几款要快很多并且性能上也不会太占用系统的资源,但是不好的地方就是,处理不了复杂的表单 ,不能像poi那么自由,所以有得有失,基本日常所需都能办到,特殊场景在可以使用模板的方式,或者使用poi也行
主流操作的excel格式
下面演示,基础的入门读和写案例, 需要对数据进行特殊处理,多Sheet,或者同步等需要参考文档,基础会了看文档就简单了
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
<version>2.4.1version>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>easyexcelartifactId>
<version>3.1.0version>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>fastjsonartifactId>
<version>2.0.3.graalversion>
<scope>compilescope>
dependency>
dependencies>
@ExcelProperty
注解可以使用下标和名称的方式来指定读取的列
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class EmployeesEntity {
@ExcelProperty(index = 0)
private Integer no; //工号
@ExcelProperty(index = 1)
private String name;
@ExcelProperty(index = 2)
private Double fund;
@ExcelProperty(index = 3)
private Double postSalary;
@ExcelProperty(index = 4)
private Double performanceOf;
@ExcelProperty(index = 5)
private Double allWork;
@ExcelProperty(index = 6)
private Double violations;
@ExcelProperty(index = 7)
private Double traffic;
@ExcelProperty(index = 8)
private Double communication;
}
一般是异步读取,可以指定同步读取数据(看文档)
public class EmployeesListener extends AnalysisEventListener<EmployeesEntity> {
/**
* 这个每一条数据解析都会来调用
*
* @param data
* one row value. Is is same as {@link AnalysisContext#readRowHolder()}
* @param context
*/
@Override
public void invoke(EmployeesEntity data, AnalysisContext context) {
System.out.println("解析到一条数据:"+JSON.toJSONString(data));
}
/**
* 所有数据解析完成了 都会来调用
*
* @param context
*/
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
}
}
@Test
public void get(){
File file = new File("./src/main/resources/大客户部-薪酬表.xlsx");
String absolutePath = file.getAbsolutePath();
// // 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭
EasyExcel.read(absolutePath, EmployeesEntity.class, new EmployeesListener()).sheet().doRead();
}
写可以指定Sheet进行写,还可以指定列进行写,还可以写入图片,简单的合并单元格…下面教程默认写入第一个Sheet中
@ExcelProperty("字符串标题")
列的标题
@Data
public class DemoData {
@ExcelProperty("字符串标题")
private String string;
@ExcelProperty("日期标题")
private Date date;
@ExcelProperty("数字标题")
private Double doubleData;
/**
* 忽略这个字段
*/
@ExcelIgnore
private String ignore;
}
//生成模拟数据
private List<DemoData> data() {
List<DemoData> list = new ArrayList<DemoData>();
for (int i = 0; i < 10; i++) {
DemoData data = new DemoData();
data.setString("字符串" + i);
data.setDate(new Date());
data.setDoubleData(0.56);
list.add(data);
}
return list;
}
/**
* 最简单的写
* 1. 创建excel对应的实体对象 参照{@link DemoData}
*
2. 直接写即可
*/
@Test
public void simpleWrite() {
// 写
File file = new File("./src/main/resources/DemoData.xlsx");
// 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
// 如果这里想使用03 则 传入excelType参数即可
EasyExcel.write(file.getAbsolutePath(), DemoData.class).sheet("DemoData").doWrite(data());
}
一般特别复杂的excel,比如发票,等, 一般就需要使用模板的方式,如果使用代码的话太复杂了
@Data
public class FillData {
private String name;
private double number;
}
@Test
public void simpleFill() {
// 模板注意 用{} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 用"\{","\}"代替
File templateFileName = new File("./src/main/resources/模板.xlsx");
File fill = new File("./src/main/resources/fillData.xlsx");
// 这里 会填充到第一个sheet, 然后文件流会自动关闭
FillData fillData = new FillData();
fillData.setName("张三");
fillData.setNumber(5.2);
EasyExcel.write(fill.getAbsolutePath()).withTemplate(templateFileName.getAbsolutePath()).sheet().doFill(fillData);
}
如果是统计表,而且标题是非常复杂的情况下,那么我们使用列表填充会很容易解决(自行看文档)