SpringBoot使用FastExcel实现多级表头动态数据填充导出

 更新时间:2025年12月24日 08:57:20   作者:愿你天黑有灯下雨有伞  
这篇文章主要为大家详细介绍了SpringBoot如何使用FastExcel实现多级表头动态数据填充导出功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下

1:依赖(Maven)

<!-- FastExcel 官网最新版 -->
<dependency>
    <groupId>cn.idev.excel</groupId>
    <artifactId>fastexcel</artifactId>
    <version>1.0.0</version>
</dependency>

2:动态表头实体类

package com.fantaibao.module.vo.target;

import cn.idev.excel.annotation.ExcelProperty;
import cn.idev.excel.annotation.write.style.ColumnWidth;
import cn.idev.excel.annotation.write.style.ContentStyle;
import cn.idev.excel.annotation.write.style.HeadFontStyle;
import cn.idev.excel.annotation.write.style.HeadStyle;
import cn.idev.excel.enums.poi.FillPatternTypeEnum;
import cn.idev.excel.enums.poi.HorizontalAlignmentEnum;
import cn.idev.excel.enums.poi.VerticalAlignmentEnum;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@HeadFontStyle(fontName = "黑体", fontHeightInPoints = 12)
@HeadStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER, verticalAlignment = VerticalAlignmentEnum.CENTER,
        fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 44)
@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER, verticalAlignment = VerticalAlignmentEnum.CENTER)
public class TargetIndexExportStoreStaVo {
    /**
     * 年份(2025)
     */
    @ColumnWidth(15)
    @ExcelProperty({"${indexName}", "年度"})
    private Integer year;

    /**
     * 门店名称
     */
    @ColumnWidth(20)
    @ExcelProperty({"${indexName}", "门店名称"})
    private String storeName;
    /**
     * 年目标
     */
    @ColumnWidth(15)
    @ExcelProperty({"${indexName}", "年目标"})
    private String totalTarget;
    /**
     * 当前进度
     */
    @ColumnWidth(20)
    @ExcelProperty({"${indexName}", "当前进度"})
    private String progress;
    /**
     * 目标完成率
     */
    @ColumnWidth(20)
    @ExcelProperty({"${indexName}", "目标完成率"})
    private String finishRate;
}
package com.fantaibao.module.vo.target;

import cn.idev.excel.annotation.ExcelProperty;
import cn.idev.excel.annotation.write.style.*;
import cn.idev.excel.enums.poi.FillPatternTypeEnum;
import cn.idev.excel.enums.poi.HorizontalAlignmentEnum;
import cn.idev.excel.enums.poi.VerticalAlignmentEnum;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@HeadFontStyle(fontName = "黑体", fontHeightInPoints = 12)
@HeadStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER, verticalAlignment = VerticalAlignmentEnum.CENTER,
        fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 44)
@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER, verticalAlignment = VerticalAlignmentEnum.CENTER)
@ContentFontStyle(fontName = "黑体", fontHeightInPoints = 10)
public class TargetIndexExportStoreMonthStaVo {
    /**
     * 年份(2025)
     */
    @ColumnWidth(15)
    @ExcelProperty({"${indexName}", "年度"})
    private Integer year;

    /**
     * 门店名称
     */
    @ColumnWidth(25)
    @ExcelProperty({"${indexName}", "门店名称"})
    private String storeName;

    /**
     * 月目标
     */
    @ColumnWidth(15)
    @ExcelProperty({"${indexName}", "${month}月目标"})
    private String totalTarget;

    /**
     * 当前进度
     */
    @ColumnWidth(20)
    @ExcelProperty({"${indexName}", "当前进度"})
    private String progress;

    /**
     * 目标完成率
     */
    @ColumnWidth(20)
    @ExcelProperty({"${indexName}", "目标完成率"})
    private String finishRate;
}

3:动态表头数据填充策略

package com.fantaibao.handler;

import cn.hutool.core.collection.CollUtil;
import cn.idev.excel.metadata.Head;
import cn.idev.excel.write.handler.CellWriteHandler;
import cn.idev.excel.write.metadata.holder.WriteSheetHolder;
import cn.idev.excel.write.metadata.holder.WriteTableHolder;
import org.apache.poi.ss.usermodel.Cell;

public class CustomHeaderWriteHandler implements CellWriteHandler {

    private final String indexName;

    public CustomHeaderWriteHandler(String indexName) {
        this.indexName = indexName;
    }

    @Override
    public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,
                                Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
        // 处理表头
        if (CollUtil.isNotEmpty(head.getHeadNameList())) {
            // 处理一级表头
            if (CollUtil.isNotEmpty(head.getHeadNameList())) {
                String replace = head.getHeadNameList().get(0).replace("${indexName}", indexName);
                head.getHeadNameList().set(0, replace);
            }
        }
    }

}

public class CustomMonthHeaderWriteHandler implements CellWriteHandler {

    private final String indexName;
    private final int month;

    public CustomMonthHeaderWriteHandler(String indexName, int month) {
        this.indexName = indexName;
        this.month = month;
    }


    @Override
    public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,
                                Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
        if (isHead && head != null) {
            // 处理表头
            if (CollUtil.isNotEmpty(head.getHeadNameList())) {
                // 处理一级表头
                String indexName = head.getHeadNameList().get(0).replace("${indexName}", this.indexName);
                head.getHeadNameList().set(0, indexName);
                // 处理二级表头
                String monthStr = head.getHeadNameList().get(1);
                if (!monthStr.contains("${month}")) {
                    return;
                }
                String month = monthStr.replace("${month}", String.valueOf(this.month));
                head.getHeadNameList().set(1, month);
            }
        }
    }
}

4:导出工具类

/**
     * 按单个指标生成年度-月度汇总数据
     *
     * @param zipOut               ZIP输出流
     * @param fileNamePrefix        文件名前缀
     * @param storeTargetYearList  门店年目标集合
     * @param storeMonthTargetList 门店月目标集合
     * @param enums                指标
     * @param storeMap             门店集合
     * @throws IOException 抛出的异常
     */
    public static void generateSingleIndexStaExcelFile(ZipOutputStream zipOut, String fileNamePrefix, List<StoreIndexYearStaVo> storeTargetYearList,
                                                       List<StoreIndexMonthStaVo> storeMonthTargetList, IndicatorsTypeEnums enums,
                                                       Map<String, StoreInfoListVO> storeMap) throws IOException {
        ZipEntry zipEntry = new ZipEntry(enums.getName() + "门店" + fileNamePrefix + "目标汇总.xlsx");
        zipOut.putNextEntry(zipEntry);
        try (ExcelWriter excelWriter = EasyExcel.write(zipOut).autoCloseStream(false).build()) {
            // Sheet1: 门店指标年目标汇总
            WriteSheet yearSheet = EasyExcel.writerSheet(0, enums.getName() + "门店年目标")
                    .head(TargetIndexExportStoreStaVo.class)
                    .registerWriteHandler(new CustomHeaderWriteHandler(StrUtil.isNotBlank(enums.getUnit()) ? enums.getName() + "(" + enums.getUnit() + ")" : enums.getName()))
                    .build();
            excelWriter.write(getYearSheetData(enums, storeTargetYearList, storeMap), yearSheet);
            // Sheet2: 门店指标月目标汇总
            for (int month = 1; month <= 12; month++) {
                WriteSheet monthSheet = EasyExcel.writerSheet(month, "门店" + month + "月目标")
                        .head(TargetIndexExportStoreMonthStaVo.class)
                        .registerWriteHandler(new CustomMonthHeaderWriteHandler(StrUtil.isNotBlank(enums.getUnit()) ? enums.getName() + "(" + enums.getUnit() + ")" : enums.getName(), month))
                        .build();
                excelWriter.write(getMonthSheetDataByMonth(enums, storeMonthTargetList, month, storeMap), monthSheet);
            }
            excelWriter.finish();
        } catch (Exception e) {
            try {
                zipOut.closeEntry();
            } catch (IOException ignored) {
            }
            throw e;
        }
        zipOut.closeEntry();
    }

5:样例

以上就是SpringBoot使用FastExcel实现多级表头动态数据填充导出的详细内容,更多关于SpringBoot FastExcel数据填充导出的资料请关注脚本之家其它相关文章!

相关文章

  • Java CountDownLatch的源码硬核解析

    Java CountDownLatch的源码硬核解析

    对于并发执行,Java中的CountDownLatch是一个重要的类。为了更好的理解CountDownLatch这个类,本文将通过例子和源码带领大家深入解析这个类的原理,感兴趣的可以学习一下
    2022-10-10
  • 关于RocketMQ使用事务消息

    关于RocketMQ使用事务消息

    RocketMQ是一种提供消息队列服务的中间件,也称为消息中间件,是一套提供了消息生产、存储、消费全过程API的软件系统。消息即数据。一般消息的体量不会很大,需要的朋友可以参考下
    2023-05-05
  • SpringBoot整合Lettuce redis过程解析

    SpringBoot整合Lettuce redis过程解析

    这篇文章主要介绍了SpringBoot整合Lettuce redis过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-10-10
  • Java利用布隆过滤器实现快速检查元素是否存在

    Java利用布隆过滤器实现快速检查元素是否存在

    布隆过滤器是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。本文就来详细说说实现的方法,需要的可以参考一下
    2022-10-10
  • JAVA实现DOC转PDF的示例代码

    JAVA实现DOC转PDF的示例代码

    Word作为目前主流的文本编辑软件之一,功能十分强大,但是在传输的时候不稳定,那么如何从DOC转PDF,本文就来介绍一下,感兴趣的可以了解一下
    2021-08-08
  • Java8中接口的新特性使用指南

    Java8中接口的新特性使用指南

    接口改动一下就要修改对应的实现类,为了兼容老接口,Java8新增了默认方法和静态方法,下面这篇文章主要给大家介绍了关于Java8中接口新特性的相关资料,需要的朋友可以参考下
    2021-11-11
  • Mybatis实现指定sql返回值类型

    Mybatis实现指定sql返回值类型

    文章介绍了Mybatis中处理不同返回值情况的方法,包括返回值只有一个和有多个的情况,对于返回值只有一个,可以直接返回该值;对于多个返回值,可以使用POJO对象、List集合或Map集合进行封装,每种方法都有其适用的场景
    2025-12-12
  • springsecurity6配置自定义路径身份认证的实现

    springsecurity6配置自定义路径身份认证的实现

    本文主要介绍了springsecurity6配置自定义路径身份认证的实现,通过使用自定义的AuthorizationManager和MyService,可以实现更灵活的访问控制,感兴趣的可以了解一下
    2025-03-03
  • 使用restTemplate.postForEntity()的问题

    使用restTemplate.postForEntity()的问题

    这篇文章主要介绍了使用restTemplate.postForEntity()的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09
  • Springboot开发OAuth2认证授权与资源服务器操作

    Springboot开发OAuth2认证授权与资源服务器操作

    这篇文章主要介绍了Springboot开发OAuth2认证授权与资源服务器操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06

最新评论