一、介绍

阿里巴巴的EasyExcel是一款基于Java语言的开源Excel操作工具库,它提供了简单易用的API,方便开发者在Java项目中进行Excel文件的读写操作。EasyExcel支持大数据量的导入导出,并且具有较高的性能和易用性。

https://easyexcel.opensource.alibaba.com/

二、如何使用

2.1 导入依赖

pom.xml 文件中导入easyExcel依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<dependencies>
<!-- easyExcel -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.3.2</version>
</dependency>

<!-- lombok依赖 简化实体类 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<!-- 对于编译时注解处理器,通常设置为 provided -->
<scope>provided</scope>
</dependency>
</dependencies>

2.2 创建实体类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package com.shiguang.easyexcel.pojo;

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import lombok.Data;

/**
* Created By Shiguang On 2024/1/12 14:22
*/

@Data
public class Usr {
@ExcelProperty(value = "人员id")
@ColumnWidth(15)

private Long id;

@ExcelProperty(value = "姓名")
@ColumnWidth(20)
private String username;

@ExcelProperty(value = "密码")
@ColumnWidth(20)
private String password;

@ExcelProperty(value = "年龄")
@ColumnWidth(15)
private Integer age;

@ExcelProperty(value = "性别")
@ColumnWidth(15)
private String sex;

@ExcelProperty(value = "邮箱")
@ColumnWidth(40)
private String email;

}

三、练手示例

2.2 入门示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.read.builder.ExcelReaderBuilder;
import com.alibaba.excel.support.ExcelTypeEnum;


/**
* Created By Shiguang On 2024/1/17 22:02
*/
public class EasyExcelTest {
public static void main(String[] args) {
// 读取文件
// 创建ExcelReaderBuilder实例
ExcelReaderBuilder readerBuilder = EasyExcel.read();
// 获取文件对象
readerBuilder.file("D:\\Desktop\\Usr.xlsx");
// 指定要读取的Sheet页,若不指定则默认读取全部Sheet页
readerBuilder.sheet("Usr");
// 自动关闭输入流
readerBuilder.autoCloseStream(true);
// 设置Excel文件格式
readerBuilder.excelType(ExcelTypeEnum.XLSX);
// easyExcel是以观察者模式逐行读取文件,需要注册一个监听器来监听读取结果
readerBuilder.registerReadListener(new AnalysisEventListener() {
int i = 0;

/**
* 一行数据读取完毕后回调
*/
@Override
public void invoke(Object o, AnalysisContext analysisContext) {
System.out.println(o);
i++;
System.out.println("第" + i +"条数据读取完毕");
}

/**
* 所有数据读取完毕后回调
*/
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
System.out.println("所有数据读取完毕!!");
}


});

//构建读取器
ExcelReader excelReader = readerBuilder.build();
//读取数据
excelReader.readAll();
//读取完毕
excelReader.finish();

}
}

Excel 信息如下所示

image-20240126220212449

输出信息如下

image-20240126220220982

其实 invoke回调方法中的Object对象实际为LinkedHashMap对象,可以在方法上加断点调试调试查看数据信息

image-20240117230841332

创建时可以使用泛型指定数据类型 new AnalysisEventListener<LinkedHashMap<Integer, String>>()

1
2
3
4
5
6
7
8
9
10
11
12
13
@Override
public void invoke(LinkedHashMap<Integer, String> row, AnalysisContext analysisContext) {
//System.out.println(row);
Set<Integer> item = row.keySet();
Iterator<Integer> iterator = item.iterator();
while (iterator.hasNext()) {
Integer key = iterator.next();
System.out.print("index_"+key + " : " + row.get(key) + ", ");
}
System.out.println();
//i++;
//System.out.println("第" + i + "条数据读取完毕");
}

输出信息如下

image-20240126220238756

2.3 简化版示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import java.util.*;

/**
* Created By Shiguang On 2024/1/17 23:34
*/
public class Test {
public static void main(String[] args) {
List<LinkedHashMap<Integer, String>> list = new ArrayList<>();
EasyExcel.read().file("D:\\Desktop\\Usr.xlsx").sheet("Usr").registerReadListener(new AnalysisEventListener<LinkedHashMap<Integer, String>>() {
/**
* 一行数据读取完毕后回调
*/
@Override
public void invoke(LinkedHashMap<Integer, String> row, AnalysisContext analysisContext) {
list.add(row);
}

/**
* 所有数据读取完毕后回调
*/
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
System.out.println("所有数据读取完毕!!");
}


}).doRead();

for (LinkedHashMap<Integer, String> integerStringLinkedHashMap : list) {
Set<Integer> item = integerStringLinkedHashMap.keySet();
Iterator<Integer> iterator = item.iterator();
while (iterator.hasNext()) {
Integer key = iterator.next();
System.out.print("index_" + key + " : " + integerStringLinkedHashMap.get(key) + ", ");
}
System.out.println();
}


}
}

2.4 映射实体类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@Test
public void test1(){
List<Usr> list = new ArrayList<>();
EasyExcel.read()
.file("D:\\Desktop\\Usr.xlsx").sheet("Usr")
.head(Usr.class)
.registerReadListener(new AnalysisEventListener<Usr>() {
/**
* 一行数据读取完毕后回调
*/
@Override
public void invoke(Usr row, AnalysisContext analysisContext) {
list.add(row);
}

/**
* 所有数据读取完毕后回调
*/
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
System.out.println("所有数据读取完毕!!");
}


}).doRead();

list.forEach(usr -> System.out.println(usr));

}

执行效果如下

image-20240118012031033

sdf

需调整Excel表头与实体类属性名一致

image-20240118005455298

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
@Test
public void test2() {
//获取Excel数据
List<Usr> excelData = getExcelData();
//写入到Excel文件
EasyExcel.write("D:\\Desktop\\Usr_副本.xlsx")
.head(Usr.class)
.excelType(ExcelTypeEnum.XLSX)
.sheet("用户信息")
.doWrite(excelData);

}

public static List<Usr> getExcelData() {
List<Usr> list = new ArrayList<>();
EasyExcel.read()
.file("D:\\Desktop\\Usr.xlsx").sheet("Usr")
.head(Usr.class)
.registerReadListener(new AnalysisEventListener<Usr>() {
/**
* 一行数据读取完毕后回调
*/
@Override
public void invoke(Usr row, AnalysisContext analysisContext) {
list.add(row);
}

/**
* 所有数据读取完毕后回调
*/
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
System.out.println("所有数据读取完毕!!");
}

}).doRead();
System.out.println(list);

return list;
}

效果如下

image-20240126220305632

相关注解

参考

神器!阿里开源的Excel操作工具

EasyExcel不愧是最好用的的Excel导入导出工具,性能爆表!用起来真优雅!

类 AnalysisEventListener