package com.casic.missiles.utils; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.write.metadata.WriteSheet; import com.alibaba.excel.write.metadata.fill.FillConfig; import org.apache.poi.ss.usermodel.Workbook; import java.io.*; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * EasyExcel 模板填充工具类(支持文字填充和列表填充) */ public class EasyExcelTemplateUtil { /** * 使用模板填充数据并返回 Workbook 对象 * * @param templateUrl 模板文件路径 * @param sheetsMap Sheet 页码和对应的参数集合 * @return Workbook 对象 */ public static Workbook fillTemplateToWorkbook(String templateUrl, Map<Integer, Map<String, Object>> sheetsMap) { if (templateUrl == null || sheetsMap == null || sheetsMap.isEmpty()) { throw new IllegalArgumentException("参数不能为空!"); } // 创建字节数组输出流,用于存储生成的 Excel 数据 ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); // 创建 ExcelWriter try (ExcelWriter excelWriter = EasyExcel.write(outputStream) .withTemplate(getTemplateInputStream(templateUrl)) .build()) { boolean fillFlag = true; //证书报告相关的列表填充为非创建新行方式填充 if (sheetsMap.keySet().size() > 1) { fillFlag = false; } // 填充配置(用于列表填充),forceNewRow为是否创建新行方式填充 FillConfig fillConfig = FillConfig.builder().forceNewRow(fillFlag).build(); // 遍历 sheetsMap,逐个填充 Sheet 页 for (Map.Entry<Integer, Map<String, Object>> entry : sheetsMap.entrySet()) { Integer sheetIndex = entry.getKey(); // Sheet 页码 Map<String, Object> dataMap = entry.getValue(); // 当前 Sheet 页的数据 // 创建 WriteSheet WriteSheet writeSheet = EasyExcel.writerSheet(sheetIndex).build(); // 填充文字数据 Map<String, Object> textData = new HashMap<>(); List<Map<String, Object>> listData = new ArrayList<>(); // 区分文字数据和列表数据 for (Map.Entry<String, Object> dataEntry : dataMap.entrySet()) { String key = dataEntry.getKey(); Object value = dataEntry.getValue(); if (value instanceof List) { // 列表数据 listData.addAll((List<Map<String, Object>>) value); } else { // 文字数据 textData.put(key, value); } } // 填充文字数据 if (!textData.isEmpty()) { excelWriter.fill(textData, writeSheet); } // 填充列表数据 if (!listData.isEmpty()) { excelWriter.fill(listData, fillConfig, writeSheet); } } } // 将输出流转换为 Workbook 对象 byte[] excelBytes = outputStream.toByteArray(); try (InputStream inputStream = new ByteArrayInputStream(excelBytes)) { return org.apache.poi.ss.usermodel.WorkbookFactory.create(inputStream); } catch (Exception e) { throw new RuntimeException("生成 Workbook 失败", e); } } /** * 获取模板文件的输入流 * * @param templateUrl 模板文件路径 * @return 模板文件的输入流 */ private static InputStream getTemplateInputStream(String templateUrl) { try { return new FileInputStream(templateUrl); } catch (Exception e) { throw new RuntimeException("模板文件未找到: " + templateUrl, e); } } /** * 测试工具类 */ public static void main(String[] args) throws Exception { // 模板文件路径 String templateUrl = "path/to/template.xlsx"; // 准备数据 Map<Integer, Map<String, Object>> sheetsMap = new HashMap<>(); // Sheet1 数据 Map<String, Object> sheet1Data = new HashMap<>(); // 文字数据 sheet1Data.put("name", "张三"); // 对应模板中的 {name} sheet1Data.put("age", 25); // 对应模板中的 {age} sheet1Data.put("gender", "男"); // 对应模板中的 {gender} // 列表数据(订单列表) List<Map<String, Object>> orderList = new ArrayList<>(); Map<String, Object> order1 = new HashMap<>(); order1.put("orderId", "1001"); // 对应模板中的 {.orderId} order1.put("productName", "商品A"); // 对应模板中的 {.productName} order1.put("quantity", 2); // 对应模板中的 {.quantity} orderList.add(order1); Map<String, Object> order2 = new HashMap<>(); order2.put("orderId", "1002"); // 对应模板中的 {.orderId} order2.put("productName", "商品B"); // 对应模板中的 {.productName} order2.put("quantity", 3); // 对应模板中的 {.quantity} orderList.add(order2); sheet1Data.put("order", orderList); // 占位符名称 "order" sheetsMap.put(0, sheet1Data); // 第一个 Sheet 页 // 调用工具类生成 Workbook Workbook workbook = fillTemplateToWorkbook(templateUrl, sheetsMap); // 将 Workbook 写入文件(测试用) try (FileOutputStream fileOut = new FileOutputStream("path/to/output.xlsx")) { workbook.write(fileOut); } System.out.println("Excel 文件生成成功!"); } }