EasyExcel 处理 Excel

序言

本文介绍在日常的开发中,如何使用 EasyExcel 高效处理 Excel。

一、EasyExcel 是什么

EasyExcel 是阿里巴巴开源的一个 Java Excel 操作类库,它基于 Apache POI 封装了简单易用的 API,使得我们能够方便地读取、写入 Excel 文件。EasyExcel 支持读写 Excel 的各种操作,包括读取 Excel 内容、写入 Excel 内容、大数据量导出、模板导出等功能。

上图是 EasyExcel 官方给出的 16M 内存 23 秒读取 75M (46W 行 25 列) 的 Excel(3.2.1+版本) 测试效果。我们可以看出 EasyExcel 具有以下特点:

  1. 高性能
  2. 低内存占用

二、EasyExcel 读取 Excel

场景假设:我们需要读取下图 Excel 文件中的内容

2.1 引入依赖

xml 复制代码
<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>easyexcel</artifactId>
  <version>3.3.1</version>
</dependency>

2.2 编写实体类

java 复制代码
@Data
public class ExcelData {
    // 编号
    private int id;
    // 姓名
    private String name;
    // 年龄
    private int age;
}

2.3 EasyExcel 读取 Excel

java 复制代码
// 读取的 Excel 路径
String filePath = "test.xlsx";
// 接收读取的数据
List<ExcelData> dataList = new ArrayList<>();

// 读取数据并将数据放入 dataList
// read() 方法一共三个参数
// 第一个参数是文件路径
// 第二个参数是指定接收数据的实体类
// 第三个参数是一个 ReadListener,用于处理读取到数据之后需要做出的动作
// (此处是将读取到的数据放入 dataList 中)
EasyExcel.read(filePath, ExcelData.class, new PageReadListener<ExcelData>(dataList::addAll))
// sheet() 方法表示需要读取的 sheet,默认是第一个 sheet
// doRead() 方法表示正式执行读取操作
.sheet().doRead();

// 打印读取的结果
dataList.forEach(System.out::println);

读取效果:

三、EasyExcel 写入 Excel

场景假设:我们现在需要将如下数据写入到 Excel 中

编号 姓名 年龄
1 zs 10
2 ls 11
3 ww 12
4 tq 13
5 zl 14

3.1 定义数据实体类

java 复制代码
@Data
public class ExcelData {
    @ExcelProperty("编号")
    private int id;
    @ExcelProperty("姓名")
    private String name;
    @ExcelProperty("年龄")
    private int age;
}

3.2 EasyExcel 写入 Excel

java 复制代码
// 模拟数据
List<ExcelData> dataList = Arrays.asList(
    new ExcelData(1, "zs", 10),
    new ExcelData(2, "ls", 11),
    new ExcelData(3, "ww", 12),
    new ExcelData(4, "tq", 13),
    new ExcelData(5, "zl", 14)
);

// 定义输出路径
String outPath = "out.xlsx";

// 通过 EasyExcel 写入到 Excel
// write() 方法有两个参数
// 第一个参数是输出路径
// 第二个参数是写出数据的实体类
EasyExcel.write(outPath, ExcelData.class)
// sheet() 方法,可以指定 sheet 的名称
.sheet("导出数据")
// doWrite() 方法,执行导出
.doWrite(dataList);

写入效果:

四、EasyExcel 高级读

4.1 读取额外信息

java 复制代码
// 读取路径
String filePath = "test.xlsx";
// 存放读取的内容
List<ExcelData> dataList = new ArrayList<>();

// 读取
EasyExcel.read(filePath, ExcelData.class, new PageReadListener<ExcelData>(dataList::addAll) {

    // 重写这个方法,根据具体业务编写业务规则
    @Override
    public void extra(CellExtra extra, AnalysisContext context) {
        switch (extra.getType()) {
            case COMMENT:
                System.out.println("执行注释的处理逻辑");
                break;
            case HYPERLINK:
                System.out.println("执行超链接的处理逻辑");
                break;
            case MERGE:
                System.out.println("执行合并单元格的处理逻辑");
                break;
        }
    }
})
// 读取批注
.extraRead(CellExtraTypeEnum.COMMENT)
// 读取超链接
.extraRead(CellExtraTypeEnum.HYPERLINK)
// 读取合并单元格
.extraRead(CellExtraTypeEnum.MERGE)
.sheet().doRead();

4.2 读取多个 sheet

java 复制代码
String filePath = "test.xlsx";
List<ExcelData> dataList = new ArrayList<>();

// 获取 ExcelReader
try (ExcelReader excelReader = EasyExcel.read(filePath).build()) {
    // 读取第一个 sheet
    ReadSheet sheet1 = EasyExcel.readSheet(0)
    .head(ExcelData.class)
    .registerReadListener(new PageReadListener<ExcelData>(dataList::addAll))
    .build();

    // 读取第二个 sheet
    ReadSheet sheet2 = EasyExcel.readSheet(1)
    .head(ExcelData.class)
    .registerReadListener(new PageReadListener<ExcelData>(dataList::addAll))
    .build();

    // 执行真正的读取操作
    excelReader.read(sheet1, sheet2);
}

五、EasyExcel 模板填充

如上图所示,有时我们需要导出具有格式的 Excel 文件。如果采用普通的写入,处理格式比较麻烦,EasyExcel 提供了模板填充的方式写入。

5.1 定义模板

5.2 定义实体类

java 复制代码
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Score {
    private String name;
    private int chinese;
    private int math;
    private int english;
}

5.3 模板填充

java 复制代码
// 模拟数据
List<Score> dataList = Arrays.asList(
    new Score("zs", 90, 89, 77),
    new Score("ls", 91, 90, 78),
    new Score("ww", 92, 91, 79),
    new Score("tq", 93, 92, 80),
    new Score("zl", 94, 93, 81)
);

// 定义输出路径
String outPath = "templateOut.xlsx";
// 定义模板路径
String templatePath = "template.xlsx";
// 输出路径
EasyExcel.write(outPath)
// withTemplate() 方法指定使用的模板路径
.withTemplate(templatePath)
// sheet() 方法默认使用模板的第一个 sheet
.sheet()
// doFill() 方法执行填充
.doFill(dataList);

填充效果:

六、监听器

回顾一下之前使用 EasyExcel 读:

java 复制代码
// 第三个参数是一个 ReadListener 对象
EasyExcel.read(filePath, ExcelData.class, new PageReadListener<ExcelData>(dataList::addAll))
.sheet().doRead();

PageReadListener 是 EasyExcel 官方提供的一个 ReadListener。该 ReadListener 会按照每读 100 条的频率处理数据。数据的具体处理逻辑交由开发人员,例如:我们使用 dataList::addAll 将数据添加到 dataList。所以,ReadListener 是 EasyExcel 提供给开发人员进行数据处理的。

以上是 EasyExcel 提供的 ReadListener,这些 ReadListener 应用于不同的使用场景,具体使用方法可参考官方文档

七、FAQ

EasyExcel 是非常强大的 Excel 处理工具,尤其是在性能和内存占用方面。如果在开发过程中,有其他特殊需求大家可以参考官方文档寻找解决方案哦。

往期推荐

  1. 实体映射解决方案-MapStruct
  2. 动态切换数据源的最佳实践
  3. Gateway
  4. 缓存神器-JetCache
  5. Mybatis 缓存机制
  6. 为什么 MySQL 单表数据量最好别超过 2000w
  7. IoC 思想简单而深邃
  8. ThreadLocal
相关推荐
小江的记录本1 分钟前
【MyBatis-Plus】MyBatis-Plus的核心特性、条件构造器、分页插件、乐观锁插件
java·前端·spring boot·后端·sql·tomcat·mybatis
小张会进步2 分钟前
数组:二维数组
java·javascript·算法
vx-程序开发9 分钟前
springboot在线装修管理系统-计算机毕业设计源码56278
java·c语言·spring boot·python·spring·django·php
大傻^13 分钟前
Spring AI Alibaba 可观测性实践:AI应用监控与链路追踪
java·人工智能·后端·spring·springaialibaba
Dxy123931021613 分钟前
js如何把字符串转数字
开发语言·前端·javascript
云烟成雨TD18 分钟前
Spring AI Alibaba 1.x 系列【1】阿里巴巴 AI 生态
java·人工智能·spring
诗人不写诗21 分钟前
spring是如何组织切面的
java·后端·spring
_饭团31 分钟前
字符串函数全解析:12 种核心函数的使用与底层模拟实现
c语言·开发语言·学习·考研·面试·蓝桥杯
Larry_Yanan31 分钟前
Qt网络开发之基于 QWebEngine 实现简易内嵌浏览器
linux·开发语言·网络·c++·笔记·qt·学习
2401_8318249638 分钟前
嵌入式C++驱动开发
开发语言·c++·算法