1、導入EasyExcel依賴
<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>4.0.3</version>
</dependency>
2、編寫實體類
@Data
publci class Student{ @ExcelProperty("姓名")private String name;
}
3、具體方法如下
調用方法(除了基礎的模板地址和數據外,增加了合并列索引和分組函數)
/*** 填充模板并合并單元格** @param tempName 模板名稱* @param list 填充數據集合* @param resultMap 特殊數據替換map* @param targetFilePath 導出地址* @param excelTypeEnum ecxcel文件類型* @param mergeColumnIndex sheet中需要合并的列的索引* @param groupFunction 分組函數* @param <T>*/public static <T> void buildMergeExcel(String tempName, List<T> list, Map<String, String> resultMap, String targetFilePath, ExcelTypeEnum excelTypeEnum, int[] mergeColumnIndex, Function<T, String> groupFunction) {try {// 獲取模板文件ClassPathResource classPathResource = new ClassPathResource("template/" + tempName);// 行計數,初始值取列頭行數int lineCount = 1;// 分別填充list數據和特殊數據ExcelWriter excelWriter = EasyExcel.write(new File(LocalStoragePropertiesConstants.LOCAL_PROFILE + targetFilePath)).excelType(excelTypeEnum).withTemplate(classPathResource.getInputStream()).build();FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();List<CellRangeAddress> rangeCellList = createCellRange(list, mergeColumnIndex, lineCount, groupFunction);WriteSheet writeSheet = EasyExcel.writerSheet().registerWriteHandler(new MergeCellRangeWriteHandler(rangeCellList)).build();excelWriter.fill(list, fillConfig, writeSheet);excelWriter.fill(resultMap, writeSheet);list.clear();excelWriter.finish();} catch (IOException e) {throw new RuntimeException(e);}}
提前計算合并的單元格,在sheet創建后一次性合并
/*** 生成合并區域** @param detailList 數據列表* @param mergeColumnIndex 要合并的列索引* @param startRowIndex 起始行(含表頭時,表頭行數)* @param groupFunction 分組函數,如 e -> e.get某字段()* @return 合并區域集合*/public static <T> List<CellRangeAddress> createCellRange(List<T> detailList, int[] mergeColumnIndex, int startRowIndex, Function<T, String> groupFunction) {if (detailList == null || detailList.isEmpty()) {return Collections.emptyList();}// 計算每個key下的數量Map<String, Long> groupMap = new LinkedHashMap<>();for (T item : detailList) {String key = groupFunction.apply(item);groupMap.put(key, groupMap.getOrDefault(key, 0L) + 1);}List<CellRangeAddress> rangeCellList = new ArrayList<>();// 當前行數int lineCount = startRowIndex;for (Map.Entry<String, Long> entry : groupMap.entrySet()) {int count = entry.getValue().intValue();if (count > 1) {int endRowIndex = lineCount + count - 1;for (int columnIndex : mergeColumnIndex) {rangeCellList.add(new CellRangeAddress(lineCount, endRowIndex, columnIndex, columnIndex));}}lineCount += count;}return rangeCellList;}
單元格合并策略
/*** easyExcel 合并單元格*/
public class MergeCellRangeWriteHandler implements SheetWriteHandler {private final List<CellRangeAddress> rangeCellList;public MergeCellRangeWriteHandler(List<CellRangeAddress> rangeCellList) {this.rangeCellList = (rangeCellList == null) ? Collections.emptyList() : rangeCellList;}public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {Sheet sheet = writeSheetHolder.getSheet();for (CellRangeAddress cellRangeAddress : this.rangeCellList) {sheet.addMergedRegionUnsafe(cellRangeAddress);}}
}
調用如下:
String sheetTitle = "模板名稱";FileResultVO fileResultVO = ExpandFileUtil.generateFilePath(EXTENSION_XLSX, sheetTitle + UUID.randomUUID(), EXTENSION_XLSX);ExpandEasyExcelUtil.buildMergeExcel("MB.xlsx",dataList, null, fileResultVO.getFilePath(),ExcelTypeEnum.XLSX,new int[]{0, 1, 2, 3, 4},Student::getName);
工作中實測使用,有什么問題歡迎留言交流