Java EasyExcel创建复杂表格的完整指南:WriteTable

EasyExcel WriteTable 核心概念解析

WriteTable 是 EasyExcel 库中的一个核心组件,用于在同一个 Excel 表单(Sheet)内创建多个独立的表格区域。与 WriteSheet(代表整个表单)不同,WriteTable 允许您在同一个 Sheet 中构建多个结构化表格,每个表格有自己的表头和数据区域。这种机制特别适用于需要生成复杂报表的场景,如企业数据汇总、财务分析等。

技术要点

  • 相对位置定位 :WriteTable 通过设置 relativeHeadRowIndex 等参数来定义表格的起始位置,确保多个表格不会重叠。
  • 复杂表头支持 :支持多级表头(如三级嵌套表头),通过 @ExcelProperty 注解实现。
  • 样式定制:允许自定义表格样式,包括表头背景色、字体、边框等。
  • 大数据量处理:基于 EasyExcel 的流式写入机制,能高效处理大量数据,避免内存溢出。

环境准备与基础配置

2.1 Maven 依赖配置

在您的 Java 项目中,需添加 EasyExcel 和 Lombok 依赖。Lombok 用于简化实体类定义(可选)。在 pom.xml 文件中添加以下内容:

xml 复制代码
<dependencies>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>easyexcel</artifactId>
        <version>3.3.2</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.24</version>
        <optional>true</optional>
    </dependency>
</dependencies>
2.2 基础实体类定义

定义数据模型实体类,用于表示表格数据。使用 @ExcelProperty 注解指定表头名称。

java 复制代码
@Data
public class Person {
    @ExcelProperty("ID")
    private Integer id;
    
    @ExcelProperty("姓名")
    private String name;
    
    @ExcelProperty("年龄")
    private Integer age;
    
    @ExcelProperty("入职日期")
    private Date joinDate;
}

@Data
public class Department {
    @ExcelProperty("部门ID")
    private Integer deptId;
    
    @ExcelProperty("部门名称")
    private String deptName;
    
    @ExcelProperty("预算(万元)")
    private Double budget;
}

核心实现:多表格创建

3.1 基础多表格实现

在服务类中,使用 WriteTable 创建多个表格。关键步骤包括:

  1. 创建 ExcelWriter:初始化写入器。
  2. 定义 WriteSheet:代表整个表单,可禁用默认表头。
  3. 定义 WriteTable:每个表格指定表头类、位置和样式。
  4. 写入数据:为每个表格提供数据源。
ID 姓名 年龄 入职日期
1 power 22 2024-10-12
2 小明 32 2021-02-21
部门id 部门名称 预算(万元)
b101 财务部 2000

示例代码:

java 复制代码
@Service
public class ComplexExcelService {
    
    public void writeComplexTable() {
    
        /*
         //1.写入io流
        ByteArrayOutputStream outputStream =new ByteArrayOutputStream(1024);
        ExcelWriter excelWriter = EasyExcel.write(outputStream).build();
		*/
		//2。写入文件
		String fileName = "企业数据报表_" + LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE) + ".xlsx"; 
        try (ExcelWriter excelWriter = EasyExcel.write(fileName).build()) {
            // 创建 WriteSheet,禁用默认表头
            //.registerWriteHandler(XXXHandler)  (XXXHandler需实现 CellWriteHandler)
            WriteSheet writeSheet = EasyExcel.writerSheet("企业综合数据")
                .needHead(Boolean.FALSE)
                .build();
            
            // 创建第一个表格:人员信息
            WriteTable personnelTable = EasyExcel.writerTable(0)
                .head(Person.class) // 使用类注解生成表头
                .needHead(Boolean.TRUE)
                .build(); // 可添加 .tableStyle() 自定义样式
            
            // 创建第二个表格:部门信息,定位在第一个表格下方
            WriteTable departmentTable = EasyExcel.writerTable(1)
                .head(Department.class)
                .needHead(Boolean.TRUE)
                .relativeHeadRowIndex(6) // 预留空间,避免重叠
                .build();
            
            // 写入数据
            excelWriter.write(generatePersonData(), writeSheet, personnelTable);
            excelWriter.write(generateDepartmentData(), writeSheet, departmentTable);
            
            logger.info("复杂表格生成完成:{}", fileName);
        }
    }
    
    private List<Person> generatePersonData() {
        // 生成模拟数据,略
    }
    
    private List<Department> generateDepartmentData() {
        // 生成模拟数据,略
    }
}

关键参数解释

  • relativeHeadRowIndex:指定表格表头的起始行索引(从 0 开始),用于定位表格位置。
  • tableStyle:可选参数,用于自定义表格样式(需实现 WriteHandler)。

高级特性:复杂表头与样式定制

4.1 多级表头实现

EasyExcel 支持嵌套表头,通过 @ExcelProperty 的数组参数定义多级结构。

java 复制代码
@Data
@HeadRowHeight(25)
@ContentRowHeight(20)
public class ComplexHeaderData {
    
    @ExcelProperty(value = {"企业信息", "基本信息", "员工编号"})
    private String employeeId;
    
    @ExcelProperty(value = {"企业信息", "基本信息", "姓名"})
    private String name;
    
    @ExcelProperty(value = {"财务数据", "薪资信息", "基本工资"})
    private Double baseSalary;
    
    @ExcelProperty(value = {"财务数据", "薪资信息", "绩效奖金"})
    private Double performanceBonus;
    
    @ExcelProperty(value = {"财务数据", "薪资信息", "年终奖"})
    private Double annualBonus;
}

WriteTable 中,使用此类作为表头,即可自动生成三级表头。

4.2 自定义样式策略

通过实现 WriteHandler 接口,可以定制表头和数据行的样式。

java 复制代码
@Component
public class CustomExcelStyleStrategy implements WriteHandler {
    
    @Override
    public void afterCellCreate(WriteSheetHolder writeSheetHolder, 
                               WriteTableHolder writeTableHolder, Cell cell, Head head, 
                               Integer relativeRowIndex, Boolean isHead) {
        
        Workbook workbook = writeSheetHolder.getSheet().getWorkbook();
        CellStyle style = workbook.createCellStyle();
        
        if (isHead) {
            // 表头样式:蓝色背景,白色文字
            style.setFillForegroundColor(IndexedColors.ROYAL_BLUE.getIndex());
            style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
            
            Font font = workbook.createFont();
            font.setColor(IndexedColors.WHITE.getIndex());
            font.setBold(true);
            style.setFont(font);
            
            // 边框设置
            style.setBorderBottom(BorderStyle.THIN);
            style.setBorderLeft(BorderStyle.THIN);
            style.setBorderRight(BorderStyle.THIN);
            style.setBorderTop(BorderStyle.THIN);
        } else {
            // 数据行样式:灰色边框
            style.setBorderBottom(BorderStyle.THIN);
            style.setBorderLeft(BorderStyle.THIN);
            style.setBorderRight(BorderStyle.THIN);
            style.setBorderTop(BorderStyle.THIN);
        }
        
        cell.setCellStyle(style);
    }
}

WriteTable 构建时,添加此策略:

java 复制代码
WriteTable personnelTable = EasyExcel.writerTable(0)
    .head(Person.class)
    .needHead(Boolean.TRUE)
    .registerWriteHandler(new CustomExcelStyleStrategy()) // 注册自定义样式
    .build();

总结

WriteTable 是 EasyExcel 中实现多表格报表的核心工具,通过相对位置定位和样式定制,能高效生成复杂 Excel 文件。关键步骤包括:

  1. 准备环境:添加依赖,定义实体类。
  2. 构建表格 :使用 WriteTable 定义多个独立区域。
  3. 高级定制:利用多级表头和自定义样式增强可读性。
相关推荐
qq_479875431 小时前
C++ 模板元编程
java·开发语言·c++
爱装代码的小瓶子1 小时前
【cpp知识铺子】map与set的底层AVL树
开发语言·数据结构·c++·b树·算法·链表
IT·小灰灰1 小时前
腾讯HY2.0 Think推理模型深度解析:技术突破、应用场景与实践指南
开发语言·人工智能·python·深度学习·神经网络·算法·数据分析
源代码•宸1 小时前
100 Go Mistakes(#4 过度使用getter和setter、#5 接口污染)
开发语言·经验分享·后端·golang
某空m1 小时前
【Android】浅析DataBinding
android·开发语言
爱学习的小可爱卢2 小时前
编程语言30年:从Java到Rust的进化史
java·开发语言·rust
一个很帅的帅哥2 小时前
three.js和WebGL
开发语言·javascript·webgl
一 乐2 小时前
校园社区系统|基于java+vue的校园悬赏任务平台系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot
吗~喽2 小时前
【C++】模板进阶
c语言·开发语言·c++