EasyExcel写入多Sheet页:分组数据的高效处理方案
在实际开发中,经常需要按分组(如城市、部门、日期)将数据分别写入 Excel 的不同 Sheet 页,既便于数据归类,也方便用户查看。EasyExcel 作为阿里巴巴开源的高效 Excel 处理工具,提供了简洁的 API 支持多 Sheet 写入。本文将详细讲解多 Sheet 写入的实现步骤、核心代码及优化技巧,以 “按城市分组写入” 为例展开说明。
核心原理
EasyExcel 写入多 Sheet 页的核心逻辑是:
- 创建一个全局的
ExcelWriter对象,关联目标文件和数据模型(实体类); - 为每个分组创建一个
WriteSheet对象(指定 Sheet 索引和名称); - 通过
ExcelWriter向每个WriteSheet写入对应分组的数据; - 所有 Sheet 写入完成后,调用
finish()方法关闭资源,完成文件生成。
环境准备
依赖配置
在 Maven 项目的 pom.xml 中引入 EasyExcel 依赖:
1 | <dependency> |
完整实现步骤
以 “按城市分组,每个城市的数据写入单独 Sheet 页” 为例,具体步骤如下:
定义数据模型(实体类)
创建与 Excel 列对应的实体类,使用 @ExcelProperty 注解指定列名和顺序:
1 | import com.alibaba.excel.annotation.ExcelProperty; |
分组数据写入多 Sheet 页
假设已通过业务逻辑获取到 “城市 ID - 数据列表” 的映射关系,按城市循环创建 Sheet 并写入数据:
1 | import com.alibaba.excel.EasyExcel; |
关键 API 解析
ExcelWriter
作用:全局写入器,负责管理整个 Excel 文件的生命周期(创建、写入、关闭)。
创建方式:
1
2
3
4
5// 方式1:指定文件路径和数据模型
ExcelWriter writer = EasyExcel.write(filePath, CityData.class).build();
// 方式2:指定输出流(如网络响应流)
ExcelWriter writer = EasyExcel.write(response.getOutputStream(), CityData.class).build();
WriteSheet
作用:代表一个 Sheet 页,包含索引、名称等元信息。
创建方式:
1
2
3// 参数1:Sheet 索引(0 开始,决定 Sheet 在 Excel 中的顺序)
// 参数2:Sheet 名称(显示在底部标签栏)
WriteSheet sheet = EasyExcel.writerSheet(0, "北京数据").build();
写入与关闭
- 写入数据:
excelWriter.write(dataList, writeSheet),支持批量写入 List 数据; - 关闭资源:
excelWriter.finish()必须在所有 Sheet 写入完成后调用,否则文件可能损坏或数据丢失。
扩展技巧
1. 自定义 Sheet 样式
通过 WriteSheet 的 registerWriteHandler 方法添加样式处理器,自定义表头、内容单元格样式:
1 | import com.alibaba.excel.write.handler.WriteHandler; |
2. 动态数据模型(无实体类)
若数据结构不固定,可使用 List<List<String>> 作为数据模型(外层 List 代表行,内层 List 代表列):
1 | // 无实体类时,写入方法如下 |
3. 大数据量分批写入
若单个 Sheet 的数据量过大(如 10 万行),可分批次写入,避免内存溢出:
1 | // 假设 cityDataList 是超大列表,分 1000 条/批写入 |
4. 不同 Sheet 对应不同实体类
若不同 Sheet 的数据结构不同(如 “用户表” 和 “订单表”),可在创建 WriteSheet 时指定实体类:
1 | // 第一个 Sheet 用 User 实体 |
常见问题
1. Sheet 名称重复
- 现象:多个 Sheet 名称相同时,Excel 会自动在名称后加序号(如 “北京”“北京 (2)”);
- 解决:确保
cityNameMap中的城市名称唯一,或在写入前检查并处理重复名称。
2. 数据写入不完整
- 原因:未调用
excelWriter.finish()或中途抛出异常导致资源未关闭; - 解决:将
finish()放在finally块中,确保无论是否异常都会执行。
3. 内存溢出(OOM)
- 原因:单个 Sheet 数据量过大,一次性加载到内存;
- 解决:采用分批写入(见 “扩展技巧 3”),或使用 EasyExcel 的
SAX模式(事件驱动)处理超大文件。