【学习总结】EasyExcel合并同列不同行,表格数据相同的行
实体类
@Data
@HeadRowHeight(50)
@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER, verticalAlignment = VerticalAlignmentEnum.CENTER, wrapped = BooleanEnum.TRUE)
public class CriterionDataExportDTO {@ColumnWidth(15)@ExcelProperty(value = "所属街道")private String streetName;@ColumnWidth(25)@ExcelProperty(value = "点位类型")private String pointType;@ColumnWidth(40)@ExcelProperty(value = "测评点位")private String pointName;@ColumnWidth(50)@ExcelProperty(value = "问题明细")private String issueDetails;@ColumnWidth(15)@ExcelProperty(value = "问题笔数")private Integer issueCount;@ColumnWidth(25)@ExcelProperty(value = "二级负责单位")private String responsibleUnit2;@ColumnWidth(25)@ExcelProperty(value = "二级单位接件时间")private String assignTime2;@ColumnWidth(25)@ExcelProperty(value = "三级负责单位")private String responsibleUnit3;@ColumnWidth(25)@ExcelProperty(value = "三级单位接件时间")private String assignTime3;@ExcelIgnoreprivate Integer pushStatus;}
工具类
继承合并单元格,重写合并方法
package com.jeesite.modules.utils.easyExcel;import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.merge.AbstractMergeStrategy;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;import java.util.*;public class EasyExcelUtils extends AbstractMergeStrategy {private Map<String, List<Integer>> nameRowMap = new HashMap<>();@Overrideprotected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) {int columnIndex = cell.getColumnIndex();if (columnIndex == 0) {String currentValue = cell.getStringCellValue();if (currentValue == null || currentValue.isEmpty()) {return;}int currentRowIndex = cell.getRowIndex();List<Integer> rowList = nameRowMap.getOrDefault(currentValue, new ArrayList<>());rowList.add(currentRowIndex);nameRowMap.put(currentValue, rowList);mergeRows(sheet, currentValue, rowList, columnIndex);}if (columnIndex == 2) {String currentValue = cell.getStringCellValue();if (currentValue == null || currentValue.isEmpty()) {return;}int currentRowIndex = cell.getRowIndex();List<Integer> rowList = nameRowMap.getOrDefault(currentValue, new ArrayList<>());rowList.add(currentRowIndex);nameRowMap.put(currentValue, rowList);mergeRows(sheet, currentValue, rowList, columnIndex);}}private void mergeRows(Sheet sheet, String value, List<Integer> rowList, int columnIndex) {if (rowList.size() <= 1) {return;}int startRow = rowList.get(0);int endRow = rowList.get(rowList.size() - 1);// 检查是否存在重叠合并区域CellRangeAddress existingRegion = findOverlappingRegion(sheet, startRow, endRow, columnIndex);if (existingRegion != null) {// 扩展现有合并区域以适应新的合并行startRow = Math.min(existingRegion.getFirstRow(), startRow);endRow = Math.max(existingRegion.getLastRow(), endRow);// 移除现有合并区域removeMergedRegion(sheet, existingRegion);}CellRangeAddress range = new CellRangeAddress(startRow, endRow, columnIndex, columnIndex);sheet.addMergedRegionUnsafe(range);}private CellRangeAddress findOverlappingRegion(Sheet sheet, int startRow, int endRow, int columnIndex) {for (CellRangeAddress region : sheet.getMergedRegions()) {if (region.getFirstColumn() == columnIndex && region.getLastColumn() == columnIndex) {// 只考虑指定列的合并区域if (startRow <= region.getLastRow() && endRow >= region.getFirstRow()) {return region;}}}return null;}private void removeMergedRegion(Sheet sheet, CellRangeAddress region) {int index = -1;for (int i = 0; i < sheet.getNumMergedRegions(); i++) {CellRangeAddress mergedRegion = sheet.getMergedRegion(i);if (mergedRegion.equals(region)) {index = i;break;}}if (index >= 0) {sheet.removeMergedRegion(index);}}
}
调用
public void exportTaskDetails() {List<CriterionDataExportDTO> dataDetails = dataDao.findTaskDataDetails();for (CriterionDataExportDTO item : dataDetails) {//数据处理}}//写入路径String fileName = "D:\\数据测试_" + System.currentTimeMillis() + ".xlsx";WriteCellStyle contentWriteCellStyle = new WriteCellStyle();contentWriteCellStyle.setBorderTop(BorderStyle.THIN);contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);contentWriteCellStyle.setBorderRight(BorderStyle.THIN);WriteCellStyle headWriteCellStyle = new WriteCellStyle();WriteFont headWriteFont = new WriteFont();headWriteFont.setFontHeightInPoints((short)15);headWriteCellStyle.setWriteFont(headWriteFont);HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);EasyExcel.write(fileName, CriterionDataExportDTO.class).registerWriteHandler(new EasyExcelUtils()).registerWriteHandler(horizontalCellStyleStrategy).sheet("模板").doWrite(dataDetails);}相关文章:
【学习总结】EasyExcel合并同列不同行,表格数据相同的行
实体类 Data HeadRowHeight(50) ContentStyle(horizontalAlignment HorizontalAlignmentEnum.CENTER, verticalAlignment VerticalAlignmentEnum.CENTER, wrapped BooleanEnum.TRUE) public class CriterionDataExportDTO {ColumnWidth(15)ExcelProperty(value "所属…...
Tokenview X-ray功能:深入探索EVM系列浏览器的全新视角
Tokenview作为一家领先的多链区块浏览器,为了进一步优化区块链用户的使用体验,我们推出了X-ray(余额透视)功能。该功能将帮助您深入了解EVM系列浏览器上每个地址的交易过程,以一种直观、简洁的方式呈现地址的进出账情况…...
【洛谷 P1364】医院设置 题解(图论+深度优先搜索)
医院设置 题目描述 设有一棵二叉树,如图: 其中,圈中的数字表示结点中居民的人口。圈边上数字表示结点编号,现在要求在某个结点上建立一个医院,使所有居民所走的路程之和为最小,同时约定,相邻接…...
【Java基础】- RMI原理和使用详解
【Java基础】- RMI原理和使用详解 文章目录 【Java基础】- RMI原理和使用详解一、什么RMI二、RMI原理2.1 工作原理图2.2 工作原理 三、RMI远程调用步骤3.1 RMI远程调用运行流程图3.2 RMI 远程调用步骤 四、JAVA RMI简单实现4.1 如何实现一个RMI程序4.2 JAVA实现RMI程序 一、什么…...
无水印免费4K视频素材网站 可商用-Free Stock Video
Free Stock Video是一个在线无水印免费4K视频素材网站,提供各种类型的4k、1080p的视频素材共免费下载,包括美食、水、自然、冬季、无人机、云朵、慢动作、夕阳、动态背景、缩时摄影、旅游和烟火,也可通过关键词搜索方式找到相关视频素材内容&…...
kubesphere中间件部署
微服务部署前中间件部署 一、MySQL部署 1.1 使用Docker实现MySQL主从复制 docker run -p 3307:3306 --name mysql-master \ -v /mydata/mysql/master/log:/var/log/mysql \ -v /mydata/mysql/master/data:/var/lib/mysql \ -v /mydata/mysql/master/conf:/etc/mysql \ -e My…...
使用 AWS S3 SDK 访问 COS-腾讯云国际站代充
腾讯云国际站对象存储(Cloud Object Storage,COS)提供了 AWS S3 兼容的 API,因此当用户的数据从 S3 迁移到 COS 之后,只需要进行简单的配置修改,即可让客户端应用轻松兼容 COS 服务。下面unirech小编主要介…...
c语言每日一练(15)
前言:每日一练系列,每一期都包含5道选择题,2道编程题,博主会尽可能详细地进行讲解,令初学者也能听的清晰。每日一练系列会持续更新,上学期间将看学业情况更新。 五道选择题: 1、程序运行的结果…...
如何利用软文推广进行SEO优化(打造优质软文,提升网站排名)
在当今的互联网时代,SEO优化成为了网站推广的关键。而软文推广作为一种有效的推广方式,其优点不仅仅局限于SEO,还可以带来更多的曝光和用户流量。本文将深入探讨如何做好软文推广,从而提升网站排名和流量。 了解目标受众群体 内容…...
Java线程池ExecutorService和Executors应用(Spring Boot微服务)
记录:476 场景:在Spring Boot微服务中使用ExecutorService管理Java线程池。使用Executors创建线程池。使用Runnable接口实现类提交线程任务到线程池执行。 版本:JDK 1.8,Spring Boot 2.6.3。 1.线程和线程池基础 JDK自带线程和线程池包位…...
机器学习笔记之最优化理论与方法(八)无约束优化问题——常用求解方法(中)
机器学习笔记之最优化理论与方法——基于无约束优化问题的常用求解方法[中] 引言回顾:最速下降算法的缺陷经典牛顿法基本介绍经典牛顿法的问题经典牛顿法的优点与缺陷经典牛顿法示例 修正牛顿法介绍拟牛顿法拟牛顿法的算法过程 矩阵 B k 1 \mathcal B_{k1} Bk1的…...
Django系列:Django简介与MTV架构体系概述
Django系列 Django简介与MTV架构体系概述 作者:李俊才 (jcLee95):https://blog.csdn.net/qq_28550263 邮箱 :291148484163.com 本文地址:https://blog.csdn.net/qq_28550263/article/details/132890054 【介…...
锐捷交换机WEB管理系统EXCU_SHELL密码信息泄漏漏洞
一、漏洞简介 锐捷交换机 WEB 管理系统 EXCU_SHELL存在密码信息泄露漏洞,攻击者可从漏洞获取到管理员账号密码,从而以管理员权限登录。 二、影响版本 锐捷交换机 WEB 管理系统 三、资产测绘 hunterweb.body"img/free_login_ge.gif"&&…...
线性代数(六) 线性变换
前言 《线性空间》定义了空间,这章节来研究空间与空间的关联性 函数 函数是一个规则或映射,将一个集合中的每个元素(称为自变量)映射到另一个集合中的唯一元素(称为因变量)。 一般函数从 “A” 的每个元…...
Python基础运算分享
Python的运算符和其他语言类似 (我们暂时只了解这些运算符的基本用法,方便我们展开后面的内容,高级应用暂时不介绍) 数学运算 >>>print 19 # 加法>>>print 1.3-4 # 减法>>>print 3*5 …...
【MySQL】mysql中有哪几种类型的备份技术?它们各自有什么优缺点?
为什么要备份?备份类型(从类型的角度)备份技术(从技术手段的角度)不同备份方法的比较感谢 💖 为什么要备份? 数据库或它所在的平台可能会出现问题,这时候数据库中的数据可能就遭到了…...
5基于pytorch的多目标粒子群算法,MOPSO,引导种群逼近真实Pareto前沿,算法运行结束后将外部存档中粒子作为获得的Pareto最优解近似。
基于pytorch的多目标粒子群算法,MOPSO,引导种群逼近真实Pareto前沿,算法运行结束后将外部存档中粒子作为获得的Pareto最优解近似。程序已调通,可以直接运行。 5pytorch多目标粒子群算法最优解5pytorch多目标粒子群算法最优解 (xiaohongshu.co…...
002 Linux 权限
前言 本文将会向您介绍关于linux权限方面的内容,包括文件类型,如何切换用户、基本权限、粘滞位等等 Linux具体的用户 超级用户:可以再linux系统下做任何事情,不受限制 普通用户:在linux下做有限的事情。 超级用户的…...
【Java 基础篇】Java可变参数:灵活处理不定数量的方法参数
在Java编程中,可变参数是一项强大的功能,它允许你编写更加灵活的方法,接受不定数量的参数。本文将详细解释Java可变参数的用法、语法以及最佳实践。 什么是可变参数? 可变参数是Java 5引入的一项功能,它允许你在方法…...
“网站建设流程详解:从概念到上线的每个细节“
以下是网站建设流程的详细步骤,从概念到上线的每个细节: 确定网站目标和定位:明确网站的主题和目标,根据目标受众和市场定位来决定网站的内容和设计风格。考虑网站的目的、目标受众、行业或领域等方面,以及网站的定位…...
23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)
宇树机器人多姿态起立控制强化学习框架论文解析 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一) 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...
Python Ovito统计金刚石结构数量
大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...
FFmpeg:Windows系统小白安装及其使用
一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】,注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录(即exe所在文件夹)加入系统变量…...
深入浅出Diffusion模型:从原理到实践的全方位教程
I. 引言:生成式AI的黎明 – Diffusion模型是什么? 近年来,生成式人工智能(Generative AI)领域取得了爆炸性的进展,模型能够根据简单的文本提示创作出逼真的图像、连贯的文本,乃至更多令人惊叹的…...
pycharm 设置环境出错
pycharm 设置环境出错 pycharm 新建项目,设置虚拟环境,出错 pycharm 出错 Cannot open Local Failed to start [powershell.exe, -NoExit, -ExecutionPolicy, Bypass, -File, C:\Program Files\JetBrains\PyCharm 2024.1.3\plugins\terminal\shell-int…...
Kubernetes 节点自动伸缩(Cluster Autoscaler)原理与实践
在 Kubernetes 集群中,如何在保障应用高可用的同时有效地管理资源,一直是运维人员和开发者关注的重点。随着微服务架构的普及,集群内各个服务的负载波动日趋明显,传统的手动扩缩容方式已无法满足实时性和弹性需求。 Cluster Auto…...
Monorepo架构: Nx Cloud 扩展能力与缓存加速
借助 Nx Cloud 实现项目协同与加速构建 1 ) 缓存工作原理分析 在了解了本地缓存和远程缓存之后,我们来探究缓存是如何工作的。以计算文件的哈希串为例,若后续运行任务时文件哈希串未变,系统会直接使用对应的输出和制品文件。 2 …...
Vue 3 + WebSocket 实战:公司通知实时推送功能详解
📢 Vue 3 WebSocket 实战:公司通知实时推送功能详解 📌 收藏 点赞 关注,项目中要用到推送功能时就不怕找不到了! 实时通知是企业系统中常见的功能,比如:管理员发布通知后,所有用户…...
6.计算机网络核心知识点精要手册
计算机网络核心知识点精要手册 1.协议基础篇 网络协议三要素 语法:数据与控制信息的结构或格式,如同语言中的语法规则语义:控制信息的具体含义和响应方式,规定通信双方"说什么"同步:事件执行的顺序与时序…...
