使用EasyExcel根据模板导出文件方式
作者:刘火锅
本文基于EasyExcel库开发ExportUtil工具类,支持模板化导出、列表/离散数据填充、HTTP响应自动配置及异常统一处理,实现结构化报表生成与文件下载功能
概要
在企业级应用开发中,Excel数据导出是一个常见的需求。
本文实现一个基于阿里巴巴EasyExcel库实现的根据模板导出文件的工具类,它通过预定义的Excel模板来生成结构化的数据报表,提高了导出功能的开发效率和灵活性。
工具类核心功能
该ExportUtil工具类主要提供以下功能:
- 模板化导出:基于预定义的Excel模板填充数据
- 灵活数据支持:支持列表数据和离散对象数据的填充
- 自动响应设置:自动处理HTTP响应头,实现文件下载
- 异常处理:统一的异常处理机制,确保导出过程稳定性
核心代码解析
类结构与常量定义
@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); } }); }
该方法接收四个参数:
- templatePath: 模板文件路径
- fileName: 导出文件名(不含后缀)
- list: 列表数据(用于填充模板中的表格区域)
- 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);
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。