EasyExcel实现多层表头:注解与列表两种方式详解
在复杂报表场景中,多层表头(如 “基础信息” 包含 “姓名”“手机号” 等子列)能更清晰地组织数据。EasyExcel 提供了简洁的 API 支持多层表头,本文将详细讲解两种实现方式(注解方式和列表方式),并对比其适用场景,帮助你快速实现类似 Excel 数据透视表的表头结构。
多层表头的核心原理
多层表头本质是多级列标题的合并与嵌套,例如 “基础信息” 作为一级标题,其下包含 “姓名”“手机号” 等二级标题。EasyExcel 通过以下方式实现:
- 层级定义:用数组或列表的嵌套结构表示表头层级(如
{"基础信息", "姓名"} 表示两级表头);
- 自动合并:相同的上级标题会自动合并单元格(如 “基础信息” 会跨列合并其所有子列)。
环境准备
引入 EasyExcel 依赖(兼容 2.x 和 3.x 版本):
1 2 3 4 5
| <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>3.3.0</version> </dependency>
|
实现方式详解
注解方式(推荐用于固定表头)
通过 @ExcelProperty 注解的 value 属性定义多层表头,适用于表头结构固定的场景(如实体类与表头一一对应)。
定义实体类
在实体类的字段上使用 @ExcelProperty(value = {一级标题, 二级标题, ...}) 定义多层表头:
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
| import com.alibaba.excel.annotation.ExcelProperty; import lombok.Data;
@Data public class UserInfo { @ExcelProperty(value = {"基础信息", "姓名"}, index = 0) private String name;
@ExcelProperty(value = {"基础信息", "手机号"}, index = 1) private String phone;
@ExcelProperty(value = {"基础信息", "年龄"}, index = 2) private Integer age;
@ExcelProperty(value = {"其他信息", "教育经历"}, index = 3) private String education;
@ExcelProperty(value = {"其他信息", "工作经历"}, index = 4) private String workExperience; }
|
value 属性:数组元素依次表示从一级到 N 级的表头名称;
index 属性:指定列的顺序(0 开始),确保表头按预期排列。
生成 Excel
直接将实体类作为表头类传入 EasyExcel.write() 方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import com.alibaba.excel.EasyExcel; import java.util.ArrayList; import java.util.List;
public class MultiLevelHeaderDemo { public static void main(String[] args) { String filePath = "多层表头_注解方式.xlsx";
List<UserInfo> dataList = new ArrayList<>();
EasyExcel.write(filePath, UserInfo.class) .sheet("用户信息表") .doWrite(dataList);
System.out.println("文件生成成功:" + filePath); } }
|
列表方式(推荐用于动态表头)
通过 List<List<String>> 手动定义表头层级,适用于表头结构动态生成的场景(如根据数据库配置动态调整表头)。
构建表头列表
外层 List 代表列的集合,内层 List 代表每列的多级表头:
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 60 61
| import com.alibaba.excel.EasyExcel; import java.util.ArrayList; import java.util.List;
public class DynamicHeaderDemo { public static void main(String[] args) { String filePath = "多层表头_列表方式.xlsx";
List<List<String>> headers = new ArrayList<>();
List<String> col1 = new ArrayList<>(); col1.add("基础信息"); col1.add("姓名"); headers.add(col1);
List<String> col2 = new ArrayList<>(); col2.add("基础信息"); col2.add("手机号"); headers.add(col2);
List<String> col3 = new ArrayList<>(); col3.add("基础信息"); col3.add("年龄"); headers.add(col3);
List<String> col4 = new ArrayList<>(); col4.add("其他信息"); col4.add("教育经历"); headers.add(col4);
List<String> col5 = new ArrayList<>(); col5.add("其他信息"); col5.add("工作经历"); headers.add(col5);
List<List<Object>> dataList = new ArrayList<>(); List<Object> dataRow = new ArrayList<>(); dataRow.add("张三"); dataRow.add("13800138000"); dataRow.add(25); dataRow.add("本科"); dataRow.add("3年"); dataList.add(dataRow);
EasyExcel.write(filePath) .head(headers) .sheet("用户信息表") .doWrite(dataList);
System.out.println("文件生成成功:" + filePath); } }
|
- 数据结构:
List<List<Object>> 中,内层 List 的元素顺序需与表头列顺序一致;
- 灵活性:可根据业务需求动态增删表头列(如从数据库查询表头配置后构建
headers 列表)。
扩展:三级及以上表头
EasyExcel 支持任意层级的表头,只需在注解数组或列表中增加层级即可。
示例:三级表头
注解方式
1 2 3 4 5 6 7 8 9 10
| @Data public class OrderInfo { @ExcelProperty(value = {"订单信息", "基本信息", "订单号"}, index = 0) private String orderNo;
@ExcelProperty(value = {"订单信息", "金额信息", "总金额"}, index = 1) private BigDecimal totalAmount; }
|
列表方式
1 2 3 4 5 6 7 8
| List<List<String>> headers = new ArrayList<>();
List<String> col1 = new ArrayList<>(); col1.add("订单信息"); col1.add("基本信息"); col1.add("订单号"); headers.add(col1);
|
两种方式的对比与适用场景
| 实现方式 |
优点 |
缺点 |
适用场景 |
| 注解方式 |
代码简洁,与实体类绑定,可读性强 |
表头固定,无法动态修改 |
表头结构固定的报表(如固定模板) |
| 列表方式 |
支持动态生成表头,灵活性高 |
代码较繁琐,需手动维护列顺序 |
表头动态变化的场景(如配置化报表) |
常见问题与解决方案
1. 表头合并异常(上级标题未跨列合并)
- 原因:同级表头的上级标题名称不一致(如 “基础信息” 与 “基础信息 ”(含空格)被视为不同标题);
- 解决:确保同一组的上级标题字符串完全一致(无空格、大小写差异)。
2. 数据与表头列顺序不匹配
- 原因:注解方式中
index 属性未按顺序设置,或列表方式中数据行元素顺序与表头列顺序不一致;
- 解决:
- 注解方式:严格按列顺序设置
index = 0, 1, 2...;
- 列表方式:数据行
List<Object> 的元素顺序必须与 headers 列表的列顺序一一对应。
3. 表头层级显示错乱
- 原因:表头层级深度不一致(如部分列是二级,部分列是三级);
- 解决:确保所有列的表头层级深度统一,或接受不同层级的显示效果(EasyExcel 会自动对齐空白单元格)。
v1.3.10