使用EasyExcel根据模板导出文件方式

 更新时间:2025年09月08日 15:33:36   作者:刘火锅  
本文基于EasyExcel库开发ExportUtil工具类,支持模板化导出、列表/离散数据填充、HTTP响应自动配置及异常统一处理,实现结构化报表生成与文件下载功能

概要

在企业级应用开发中,Excel数据导出是一个常见的需求。

本文实现一个基于阿里巴巴EasyExcel库实现的根据模板导出文件的工具类,它通过预定义的Excel模板来生成结构化的数据报表,提高了导出功能的开发效率和灵活性。

工具类核心功能

该ExportUtil工具类主要提供以下功能:

  1. 模板化导出:基于预定义的Excel模板填充数据
  2. 灵活数据支持:支持列表数据和离散对象数据的填充
  3. 自动响应设置:自动处理HTTP响应头,实现文件下载
  4. 异常处理:统一的异常处理机制,确保导出过程稳定性

核心代码解析

类结构与常量定义

@Slf4j
@Component
public class ExportUtil {
    public static final String TEMPLATE_ROOT_PATH = "template";
    public static final String EXCEL_POSTFIX = "." + CommonConst.EXCEL_TYPE_XLSX;
    // ...
}

使用Lombok注解简化日志管理。定义了模板根路径和Excel文件后缀常量(可自行定义)。

模板导出核心方法

public static void downloadExcelByTemplate(String templatePath, String fileName, 
                                         List<?> list, Object obj) {
    String templateFileName = TEMPLATE_ROOT_PATH + File.separator + templatePath;
    download(fileName + EXCEL_POSTFIX, outputStream -> {
        try (ExcelWriter excelWriter = EasyExcel.write(outputStream)
                .withTemplate(ExportUtil.class.getClassLoader()
                .getResourceAsStream(templateFileName)).build()) {
            WriteSheet writeSheet = EasyExcel.writerSheet().build();
            FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
            excelWriter.fill(list, fillConfig, writeSheet);
            excelWriter.fill(obj, fillConfig, writeSheet);
        } catch (Exception e) {
            log.error("Writing template failed:{}", e.getMessage());
            throw new BusinessException(BusinessExceptionEnum.EXPORT_FAILED);
        }
    });
}

该方法接收四个参数:

  1. templatePath: 模板文件路径
  2. fileName: 导出文件名(不含后缀)
  3. list: 列表数据(用于填充模板中的表格区域)
  4. obj: 离散数据(用于填充模板中的单个字段)

文件下载处理

public static void download(String fileName, Consumer<ServletOutputStream> write) {
    HttpServletResponse response = getHttpServletResponse(fileName);
    ServletOutputStream outputStream;
    try {
        outputStream = response.getOutputStream();
    } catch (IOException e) {
        log.error("Failed to read response and write stream:{}", e.getMessage());
        throw new BusinessException(BusinessExceptionEnum.EXPORT_FAILED);
    }
    write.accept(outputStream);
}

封装了文件下载的通用逻辑,接收一个文件名和一个用于写入输出流的Consumer函数式接口。

HTTP响应设置

@SneakyThrows
public static HttpServletResponse getHttpServletResponse(String fileName) {
    ServletRequestAttributes servletRequestAttributes = 
        (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    if (servletRequestAttributes == null || servletRequestAttributes.getResponse() == null) {
        log.error("Unable to obtain HttpServletResponse.");
        throw new BusinessException(BusinessExceptionEnum.EXPORT_FAILED);
    }
    HttpServletResponse res = servletRequestAttributes.getResponse();
    res.setContentType("application/octet-stream; charset=" + StandardCharsets.UTF_8);
    res.setHeader("Content-disposition", "attachment;filename=" + 
        URLEncoder.encode(fileName, StandardCharsets.UTF_8) + ";" + 
        "filename*=utf-8''" + URLEncoder.encode(fileName, StandardCharsets.UTF_8));
    return res;
}

负责设置HTTP响应头,包括内容类型和内容处置头,确保浏览器正确处理文件下载。使用URLEncoder对文件名进行编码,解决中文文件名乱码问题。

文件下载处理

使用示例

1. 准备Excel模板

  • 在resources/template目录下创建模板文件,例如user_template.xlsx。
  • 在模板中使用{}占位符表示离散数据,使用{.}表示列表数据。

2. 调用导出方法

// 准备数据
UserInfo userInfo = new UserInfo("张三", "技术部");
List<Order> orders = Arrays.asList(
    new Order("订单001", new Date(), 2999.0),
    new Order("订单002", new Date(), 3999.0)
);

// 执行导出
ExportUtil.downloadExcelByTemplate("user_template.xlsx", "用户订单", orders, userInfo);

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 创建Java线程安全类的七种方法

    创建Java线程安全类的七种方法

    线程安全是指某个方法或某段代码,在多线程中能够正确的执行,不会出现数据不一致或数据污染的情况,我们把这样的程序称之为线程安全的,反之则为非线程安全的,下面这篇文章主要给大家介绍了关于创建Java线程安全类的七种方法,需要的朋友可以参考下
    2022-06-06
  • SpringBoot线程池ThreadPoolTaskExecutor异步处理百万级数据

    SpringBoot线程池ThreadPoolTaskExecutor异步处理百万级数据

    本文主要介绍了SpringBoot线程池ThreadPoolTaskExecutor异步处理百万级数据,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-03-03
  • 使用Jenkins Pipeline自动化构建发布Java项目的方法

    使用Jenkins Pipeline自动化构建发布Java项目的方法

    这篇文章主要介绍了使用Jenkins Pipeline自动化构建发布Java项目的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-04-04
  • Java设计模式之状态模式(State模式)介绍

    Java设计模式之状态模式(State模式)介绍

    这篇文章主要介绍了Java设计模式之状态模式(State模式)介绍,本文讲解了何时使用状态模式、如何使用状态模式等内容,需要的朋友可以参考下
    2015-03-03
  • Java访问修饰符原理及代码解析

    Java访问修饰符原理及代码解析

    这篇文章主要介绍了Java访问修饰符原理及代码解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-06-06
  • Mybatis环境搭建和使用实例代码

    Mybatis环境搭建和使用实例代码

    MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。本文重点给大家介绍Mybatis的环境搭建和使用实例代码,需要的朋友参考下吧
    2017-12-12
  • java反射常用方法案例详解

    java反射常用方法案例详解

    Java反射指的是一个机制,这种机制可以在Java程序运行时(动态)实例化对象、读写属性、调用方法,这篇文章主要介绍了java反射常用方法,需要的朋友可以参考下
    2023-06-06
  • 实例分析Java Class的文件结构

    实例分析Java Class的文件结构

    今天把之前在Evernote中的笔记重新整理了一下,发上来供对java class 文件结构的有兴趣的同学参考一下
    2013-04-04
  • IDEA连接MySQL后管理数据库的操作指南

    IDEA连接MySQL后管理数据库的操作指南

    本节就来教大家如何在IDEA连接MySQL后管理数据库(创建/修改/删除数据库、创建/修改/删除表、插入/更新/删除/查询表记录),文中通过图文结合的方式给大家讲解的非常详细,需要的朋友可以参考下
    2024-05-05
  • SpringBoot整合RabbitMQ及原理

    SpringBoot整合RabbitMQ及原理

    这篇文章主要介绍了SpringBoot整合RabbitMQ及其原理分析,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-06-06

最新评论