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

 更新时间:2025年12月24日 11:15:09   作者:愿你天黑有灯下雨有伞  
文章介绍了如何使用Maven管理依赖,创建动态表头实体类,实现动态表头数据填充策略,并提供了一个导出工具类的示例,感兴趣的朋友跟随小编一起看看吧

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:样例

到此这篇关于Spring Boot 使用FastExcel实现多级表头动态数据填充导出的文章就介绍到这了,更多相关Spring Boot FastExcel多级表头数据填充导出内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBoot动态定时任务、动态Bean、动态路由详解

    SpringBoot动态定时任务、动态Bean、动态路由详解

    这篇文章主要介绍了SpringBoot动态定时任务、动态Bean、动态路由详解,之前用过Spring中的定时任务,通过@Scheduled注解就能快速的注册一个定时任务,但有的时候,我们业务上需要动态创建,或者根据配置文件、数据库里的配置去创建定时任务,需要的朋友可以参考下
    2023-10-10
  • SpringCloud之熔断监控Hystrix Dashboard的实现

    SpringCloud之熔断监控Hystrix Dashboard的实现

    这篇文章主要介绍了SpringCloud之熔断监控Hystrix Dashboard的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-09-09
  • Java 中的 Consumer 与 Supplier 接口使用场景与示例

    Java 中的 Consumer 与 Supplier 接口使用场景与

    文章介绍了Java 8中函数式接口的核心概念,Consumer与Supplier接口使用场景与示例,重点对比了Consumer(消费数据)与Supplier(供给数据)的区别,感兴趣的朋友跟随小编一起看看吧
    2025-08-08
  • 深入解析Java中ThreadLocal线程类的作用和用法

    深入解析Java中ThreadLocal线程类的作用和用法

    ThreadLocal为解决多线程程序的并发问题提供了一种新的思路,ThreadLocal并不是一个Thread,而是Thread的局部变量,本文就来深入解析Java中ThreadLocal线程类的作用和用法.
    2016-05-05
  • Idea 中控制启动命令的详细过程 区分环境案例详解

    Idea 中控制启动命令的详细过程 区分环境案例详解

    这篇文章主要介绍了Idea 中控制启动命令的详细过程 区分环境案例详解,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-08-08
  • Java调用python代码的五种方式总结

    Java调用python代码的五种方式总结

    这篇文章主要给大家介绍了关于Java调用python代码的五种方式,在Java中调用Python函数的方法有很多种,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2023-09-09
  • Spring Boot中操作使用Redis实现详解

    Spring Boot中操作使用Redis实现详解

    Spring Boot与Redis结合使用,通过使用Spring Data Redis来实现对Redis的操作,实现数据缓存和高效存储,提高应用程序的性能和响应速度。可以利用Spring Boot自带的Redis Starter方便地集成和配置Redis
    2023-04-04
  • Spring boot集成Go-FastDFS实现图片上传删除等功能实现

    Spring boot集成Go-FastDFS实现图片上传删除等功能实现

    这篇文章主要介绍了Spring boot集成Go-FastDFS实现图片上传删除等功能实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-04-04
  • SpringSecurity的安全过滤器链功能详解

    SpringSecurity的安全过滤器链功能详解

    本文介绍了如何配置SpringSecurity的安全过滤器链,包括定义URL路径的访问权限、用户认证和授权配置、自定义CSRF过滤器等内容,通过这些配置,可以实现对不同URL路径的访问控制以及用户的登录、注销等功能,感兴趣的朋友一起看看吧
    2025-03-03
  • Java 线程相关总结

    Java 线程相关总结

    这篇文章主要介绍了Java 线程的相关资料,帮助大家更好的理解和学习使用Java,感兴趣的朋友可以了解下
    2021-02-02

最新评论