当前位置: 首页 > news >正文

使用EasyExcel动态合并单元格(模板方法)

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);

工作中实测使用,有什么问题欢迎留言交流

http://www.lryc.cn/news/584302.html

相关文章:

  • Centos 7下使用C++使用Rdkafka库实现生产者消费者
  • Houdini 分布式解算效率瓶颈突破:渲染 101 云集群实战指南
  • 编程实践:单例模式(懒汉模式+饿汉模式)
  • 面试技术问题总结一
  • android TabLayout 标题栏切换 事件拦截
  • 【Linux系统】冯诺依曼体系结构 | 初识操作系统
  • Redis数据安全性分析
  • Spring Boot快速搭建RESTful应用
  • P1722 矩阵 II 题解 DFS深度优先遍历与卡特兰数(Catalan number)解
  • 【WPF实战】MVVM中如何从数据模型反查自定义控件实例(ImageView + Halcon)
  • C++类对象多态底层原理及扩展问题
  • Zotero+zotmoov+坚果云同步
  • 2023年华为杯研究生数学建模竞赛E题脑卒中临床智能分析
  • 我的世界Java版1.21.4的Fabric模组开发教程(十五)方块实体渲染器
  • 北京一家IPO业绩持续性存疑,关联交易频繁独立性堪忧
  • iOS 抓包详细教程:从零搭建、操作到实战调试的全流程指南
  • C++ -- STL -- vector
  • 北斗舞动在线监测装置:电力安全的“智慧守护者”
  • 大健康IP如何借“合规创新”抢占行业新风口|创客匠人
  • 基于Python的程序员数据分析与可视化系统的设计与实现
  • linxu内核的signal fault和arm内核的flault
  • 网络综合实验
  • Flowable21条件事件------------持续更新中
  • 【LeetCode100】--- 2.字母异位词分组【复习回顾】
  • 【LeetCode 热题 100】148. 排序链表——(解法二)分治
  • 数据结构与算法之美:广义表
  • ThinkSound V2版 - 一键给无声视频配音,为AI视频生成匹配音效 支持50系显卡 一键整合包下载
  • LeetCode 1652. 拆炸弹
  • 二分查找篇——寻找旋转排序数组中的最小值【LeetCode】
  • 节点小宝:手机图片备份至电脑功能实测体验