【学习总结】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引入的一项功能,它允许你在方法…...
“网站建设流程详解:从概念到上线的每个细节“
以下是网站建设流程的详细步骤,从概念到上线的每个细节: 确定网站目标和定位:明确网站的主题和目标,根据目标受众和市场定位来决定网站的内容和设计风格。考虑网站的目的、目标受众、行业或领域等方面,以及网站的定位…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...
CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...
WebRTC从入门到实践 - 零基础教程
WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC? WebRTC(Web Real-Time Communication)是一个支持网页浏览器进行实时语音…...
Java详解LeetCode 热题 100(26):LeetCode 142. 环形链表 II(Linked List Cycle II)详解
文章目录 1. 题目描述1.1 链表节点定义 2. 理解题目2.1 问题可视化2.2 核心挑战 3. 解法一:HashSet 标记访问法3.1 算法思路3.2 Java代码实现3.3 详细执行过程演示3.4 执行结果示例3.5 复杂度分析3.6 优缺点分析 4. 解法二:Floyd 快慢指针法(…...
虚幻基础:角色旋转
能帮到你的话,就给个赞吧 😘 文章目录 移动组件使用控制器所需旋转:组件 使用 控制器旋转将旋转朝向运动:组件 使用 移动方向旋转 控制器旋转和移动旋转 缺点移动旋转:必须移动才能旋转,不移动不旋转控制器…...
[QMT量化交易小白入门]-六十二、ETF轮动中简单的评分算法如何获取历史年化收益32.7%
本专栏主要是介绍QMT的基础用法,常见函数,写策略的方法,也会分享一些量化交易的思路,大概会写100篇左右。 QMT的相关资料较少,在使用过程中不断的摸索,遇到了一些问题,记录下来和大家一起沟通,共同进步。 文章目录 相关阅读1. 策略概述2. 趋势评分模块3 代码解析4 木头…...
