easyExcel 模版导出 中间数据纵向延伸,并且对指定列进行合并

想要达到的效果

引入maven引用

        <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.2.1</version></dependency>

按照要求创建模版

备注 :

模板注意 用{} 来表示你要用的变量 如果本来就有"{","}" 特殊字符 用"\{","\}"代替
// {} 代表普通变量 {.} 代表是list的变量 {前缀.} 前缀可以区分不同的list

代码部分 :

合并策略代码 :

import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.merge.AbstractMergeStrategy;
import io.jsonwebtoken.lang.Collections;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;import java.util.ArrayList;
import java.util.List;// 自定义合并策略 该类继承了AbstractMergeStrategy抽象合并策略,需要重写merge()方法public class CustomMergeStrategy extends AbstractMergeStrategy {/*** 分组,每几行合并一次*/private List<Integer> exportFieldGroupCountList;/*** 目标合并列index*/private Integer targetColumnIndex;// 需要开始合并单元格的首行indexprivate Integer rowIndex;// exportDataList为待合并目标列的值 public CustomMergeStrategy(List<String> exportDataList, Integer targetColumnIndex) {this.exportFieldGroupCountList = getGroupCountList(exportDataList);this.targetColumnIndex = targetColumnIndex;}@Overrideprotected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) {if (null == rowIndex) {rowIndex = cell.getRowIndex();}// 仅从首行以及目标列的单元格开始合并,忽略其他if (cell.getRowIndex() == rowIndex && cell.getColumnIndex() == targetColumnIndex) {mergeGroupColumn(sheet);}}private void mergeGroupColumn(Sheet sheet) {int rowCount = rowIndex;for (Integer count : exportFieldGroupCountList) {if(count == 1) {rowCount += count;continue ;}// 合并单元格CellRangeAddress cellRangeAddress = new CellRangeAddress(rowCount, rowCount + count - 1, targetColumnIndex, targetColumnIndex);sheet.addMergedRegionUnsafe(cellRangeAddress);rowCount += count;}}// 该方法将目标列根据值是否相同连续可合并,存储可合并的行数 private List<Integer> getGroupCountList(List<String> exportDataList){if (Collections.isEmpty(exportDataList)) {return new ArrayList<>();}List<Integer> groupCountList = new ArrayList<>();int count = 1;for (int i = 1; i < exportDataList.size(); i++) {if (exportDataList.get(i).equals(exportDataList.get(i - 1))) {count++;} else {groupCountList.add(count);count = 1;}}// 处理完最后一条后groupCountList.add(count);return groupCountList;}}

导出部分 :

@Testpublic void complexFillTest() throws IOException {//正式代码时 改成 input或者 file 传入String templateFileName = "D:/模版.xls";//改成导出的output或者其他方式写出 也可String fileName = "D:/下载的文件.xls";// 方案1try (ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).excelType(ExcelTypeEnum.XLS).build()) {//数据准备 改成自己的即可InvoiceInfo invoiceInfo = invoiceInfoService.lambdaQuery().eq(InvoiceInfo::getId, 21).one();List<FreightOrderResponse> freightOrderResponseList = new ArrayList<>();ArrayList<Map<String, String>> dataList = new ArrayList<>();for (int i = 0; i < freightOrderResponseList.size(); i++) {FreightOrderResponse freightOrderResponse = freightOrderResponseList.get(0);Map<String, String> map = new HashMap<>();map.put("companyName",freightOrderResponse.getComName());if (freightOrderResponseList.size() / 2 < i){map.put("companyName",freightOrderResponse.getComName() + "1");}map.put("sendAddr",freightOrderResponse.getSendProvince());map.put("arriveAddr",freightOrderResponse.getReceiveProvince());map.put("goodsName",freightOrderResponse.getGoodsName());map.put("practicalFee",freightOrderResponse.getOrderPrice().toString());dataList.add(map);}WriteSheet writeSheet = EasyExcel.writerSheet()// 合并的单元格 并且将需要合并的那一列数据传入.registerWriteHandler(new CustomMergeStrategy(dataList.stream().map(map -> map.get("companyName")).collect(Collectors.toList()), 0)).build();// 这里注意 入参用了forceNewRow 代表在写入list的时候不管list下面有没有空行 都会创建一行,然后下面的数据往后移动。默认 是false,会直接使用下一行,如果没有则创建。// forceNewRow 如果设置了true,有个缺点 就是他会把所有的数据都放到内存了,所以慎用// 简单的说 如果你的模板有list,且list不是最后一行,下面还有数据需要填充 就必须设置 forceNewRow=true 但是这个就会把所有数据放到内存 会很耗内存// 如果数据量大 list不是最后一行 参照下一个FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();excelWriter.fill(dataList, fillConfig, writeSheet);Map<String, Object> map = MapUtils.newHashMap();BigDecimal reduce = freightOrderResponseList.stream().map(obj -> obj.getOrderPrice() != null ? obj.getOrderPrice() : BigDecimal.ZERO).reduce(BigDecimal.ZERO, BigDecimal::add);map.put("practicalFee", reduce);map.put("customName", invoiceInfo.getCustomName());map.put("sellerComName", invoiceInfo.getSellerComName());excelWriter.fill(map, writeSheet);excelWriter.finish();}}

最终效果 : 

参考资料 : 

官方文档 : 

填充Excel | Easy Excel

合并代码参考 : 

https://www.cnblogs.com/monianxd/p/16359369.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/296368.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C#使用Selenium驱动Chrome浏览器

1.Selenium库依赖安装 Selenium WebDriver是Selenium项目的一部分&#xff0c;用于模拟用户在Web应用程序中的交互操作。它支持多种浏览器&#xff0c;如Chrome、Firefox、IE等&#xff0c;且与各种编程语言&#xff08;如Java、Python、C#等&#xff09;兼容&#xff0c;具有…

RUST语言流控制语句使用示例

1.判断语句 单条件判断: let mut x128;//声明一个32位整数x512;//修改变量原来的值为新值//如果 ... 否则//判断变量x是否大于256if x>256 {println!("x>256,x{}",x);}else {println!("x<256,x{}",x);}let is_ok:bool true;//rust中不用()if i…

pytest--python的一种测试框架--接口测试

接口测试 工具&#xff1a; POSTMAN&#xff1b; 接口选择&#xff1a; 豆瓣电影&#xff0c;进制数据 POSTMAN下载&#xff1a; 1.POSTMAN官网&#xff1a;https://www.postman.com/products/&#xff1b; 2.点product选Download Postman 下载完之后双击打开就可以用的。…

【TI毫米波雷达】IWR6843AOP的官方文件资源名称BUG,选择xwr68xx还是xwr64xx,及需要注意的问题

【TI毫米波雷达】IWR6843AOP的官方文件资源名称BUG&#xff0c;选择xwr68xx还是xwr64xx&#xff0c;及需要注意的问题 文章目录 demo工程out_of_box文件调试bin文件名称需要注意的问题附录&#xff1a;结构框架雷达基本原理叙述雷达天线排列位置芯片框架Demo工程功能CCS工程导…

ETL工具-nifi干货系列 第八讲 处理器PutDatabaseRecord 写数据库(详细)

1、本节通过一个小例子来讲解下处理器PutDatabaseRecord&#xff0c;该处理器的作用是将数据写入数据库。 如下流程通过处理器GenerateFlowFile 生成数据&#xff0c;然后通过处理器JoltTransformJSON转换结构&#xff0c;最后通过处理器PutDatabaseRecord将数据写入数据库。如…

一些题目学习

1.打开文件添加helloworld public class Saier {public static void main(String[] args){String path"C:\\Users\\sjg\\Desktop\\abc.txt";String text"hello world";try {File file new File(path);FileWriter fileWriter new FileWriter(file,true);…

AI绘图:Stable Diffusion WEB UI 详细操作介绍:基础篇

接上一篇《AI绘图体验&#xff1a;Stable Diffusion本地化部署详细步骤》本地部署完了SD后&#xff0c;大家肯定想知道怎么用&#xff0c;接下来补一篇Stable Diffusion WEB UI 详细操作&#xff0c;如果大家还没有完成SD的部署&#xff0c;请参考上一篇文章进行本地化的部署。…

Emacs之解除comment-region绑定C-c C-c快捷键(一百三十四)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

【学习心得】Numpy学习指南或复习手册

本文是自己在学习Numpy过后总是遗忘的很快&#xff0c;反思后发现主要是两个原因&#xff1a; numpy的知识点很多&#xff0c;很杂乱。练习不足&#xff0c;学习过后一段时间不敲代码就会忘记。 针对这两个问题&#xff0c;我写了这篇文章。希望将numpy的知识点织成一张网&…

开源模型应用落地-chatglm3-6b模型小试-入门篇(一)

一、前言 刚开始接触AI时&#xff0c;您可能会感到困惑&#xff0c;因为面对众多开源模型的选择&#xff0c;不知道应该选择哪个模型&#xff0c;也不知道如何调用最基本的模型。但是不用担心&#xff0c;我将陪伴您一起逐步入门&#xff0c;解决这些问题。 在信息时代&#xf…

5.3.1 配置交换机 SSH 管理和端口安全

5.3.1 实验1:配置交换机基本安全和 SSH管理 1、实验目的 通过本实验可以掌握&#xff1a; 交换机基本安全配置。SSH 的工作原理和 SSH服务端和客户端的配置。 2、实验拓扑 交换机基本安全和 SSH管理实验拓扑如图所示。 交换机基本安全和 SSH管理实验拓扑 3、实验步骤 &a…

Nginx从安装到高可用实用教程!

一、Nginx安装 1、去官网http://nginx.org/下载对应的nginx包&#xff0c;推荐使用稳定版本 2、上传nginx到linux系统 3、安装依赖环境 (1)安装gcc环境 yum install gcc-c(2)安装PCRE库&#xff0c;用于解析正则表达式 yum install -y pcre pcre-devel(3)zlib压缩和解压缩…

Linux项目自动化构建工具 --- make/Makefile

文章目录 make/Makefile文件1 背景2 理解2.1 创建执行代码2.2 创建makefile文件2.3 运行make指令2.3.1 依赖关系2.3.2 依赖方法2.3.3 原理 2.4 项目清理 make/Makefile文件 1 背景 会不会写makefile&#xff0c;从一个侧面说明了一个人是否具备完成大型工程的能力一个工程中的…

鸿蒙OS开发实例:【应用事件打点】

简介 传统的日志系统里汇聚了整个设备上所有程序运行的过程流水日志&#xff0c;难以识别其中的关键信息。因此&#xff0c;应用开发者需要一种数据打点机制&#xff0c;用来评估如访问数、日活、用户操作习惯以及影响用户使用的关键因素等关键信息。 HiAppEvent是在系统层面…

分布式链路追踪与云原生可观测性

分布式链路追踪系统历史 Dapper, a Large-Scale Distributed Systems Tracing Infrastructure - Google Dapper&#xff0c;大规模分布式系统的跟踪系统大规模分布式系统的跟踪系统&#xff1a;Dapper设计给我们的启示 阿里巴巴鹰眼技术解密 - 周小帆京东云分布式链路追踪在金…

【机器学习】“强化机器学习模型:Bagging与Boosting详解“

1. 引言 在当今数据驱动的世界里&#xff0c;机器学习技术已成为解决复杂问题和提升决策制定效率的关键工具。随着数据的增长和计算能力的提升&#xff0c;传统的单一模型方法已逐渐无法满足高精度和泛化能力的双重要求。集成学习&#xff0c;作为一种结合多个学习算法以获得比…

Spring Boot中前端通过请求接口下载后端存放的Excel模板

导出工具类 package com.yutu.garden.utils;import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import org.apache.commons.io.IOUtils; import org.apache.poi.hssf.util.HSSFColor; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.slf4j.Logger;…

vue项目引入微信sdk: npm install weixin-js-sdk --save报错

网上查到要用淘宝的镜像 同事告知旧 域名&#xff1a;https://registry.npm.taobao.org/已经不能再使用 使用 npm config set registry http://registry.npmmirror.com

[力扣]根据前中序构造二叉树--详细解析

根据前中序遍历顺序构建一个二叉树 力扣练习链接 过程 总体框架 设preorder的左边界为pleft,右边界为pright[注意这里是闭区间能取到]同时设inorder的左边界为ileft,有边界为iright[同样也是可以取到的索引区间]我们生成每一个区间的树的头结点,然后向上返回,对于他的父亲结点…

基于ssm的轻型卡车零部件销售平台(java项目+文档+源码)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于ssm的轻型卡车零部件销售平台。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 轻型卡车零部件销售平台…