Java整合EasyExcel实战——3(上下列相同合并单元格策略)
参考:https://juejin.cn/post/7322156759443095561?searchId=202405262043517631094B7CCB463FDA06
https://juejin.cn/post/7322156759443095561?searchId=202405262043517631094B7CCB463FDA06
准备条件
依赖
<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.2.6</version></dependency>
工具类
package co.yixiang.exam.listener;import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;import java.util.List;public class ExcelFillCellMergeStrategy implements CellWriteHandler {private int[] mergeColumnIndex;private int mergeRowIndex;public ExcelFillCellMergeStrategy() {}public ExcelFillCellMergeStrategy(int mergeRowIndex, int[] mergeColumnIndex) {this.mergeRowIndex = mergeRowIndex;this.mergeColumnIndex = mergeColumnIndex;}@Overridepublic void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) {}@Overridepublic void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {}@Overridepublic void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, CellData cellData, Cell cell, Head head, Integer integer, Boolean aBoolean) {}@Overridepublic void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<CellData> list, Cell cell, Head head, Integer integer, Boolean aBoolean) {//当前行int curRowIndex = cell.getRowIndex();//当前列int curColIndex = cell.getColumnIndex();if (curRowIndex > mergeRowIndex) {for (int i = 0; i < mergeColumnIndex.length; i++) {if (curColIndex == mergeColumnIndex[i]) {mergeWithPrevRow(writeSheetHolder, cell, curRowIndex, curColIndex);break;}}}}/*** 当前单元格向上合并** @param writeSheetHolder* @param cell 当前单元格* @param curRowIndex 当前行* @param curColIndex 当前列*/private void mergeWithPrevRow(WriteSheetHolder writeSheetHolder, Cell cell, int curRowIndex, int curColIndex) {//获取当前行的当前列的数据和上一行的当前列列数据,通过上一行数据是否相同进行合并Object curData = cell.getCellTypeEnum() == CellType.STRING ? cell.getStringCellValue() : cell.getNumericCellValue();Cell preCell = cell.getSheet().getRow(curRowIndex - 1).getCell(curColIndex);Object preData = preCell.getCellTypeEnum() == CellType.STRING ? preCell.getStringCellValue() : preCell.getNumericCellValue();// 比较当前行的第一列的单元格与上一行是否相同,相同合并当前单元格与上一行//if (curData.equals(preData)) {Sheet sheet = writeSheetHolder.getSheet();List<CellRangeAddress> mergeRegions = sheet.getMergedRegions();boolean isMerged = false;for (int i = 0; i < mergeRegions.size() && !isMerged; i++) {CellRangeAddress cellRangeAddr = mergeRegions.get(i);// 若上一个单元格已经被合并,则先移出原有的合并单元,再重新添加合并单元if (cellRangeAddr.isInRange(curRowIndex - 1, curColIndex)) {sheet.removeMergedRegion(i);cellRangeAddr.setLastRow(curRowIndex);sheet.addMergedRegion(cellRangeAddr);isMerged = true;}}// 若上一个单元格未被合并,则新增合并单元if (!isMerged) {CellRangeAddress cellRangeAddress = new CellRangeAddress(curRowIndex - 1, curRowIndex, curColIndex, curColIndex);sheet.addMergedRegion(cellRangeAddress);}}}}
ServiceImpl层应用
sql 数据的重复数据,合并单元格
SELECTeq.id,eq.question_title,eo.options_content,eq.options_correct,eq.question_answer,eq.question_score,eq.question_subject,eq.question_title_zi,eq.question_type
FROMex_question eq
LEFT JOINex_options eoon eq.id = eo.question_id where eq.is_del = 0 and eo.is_del = 0;
@Overridepublic R exportExQuestionOptions(HttpServletResponse response) throws IOException {// 定义导出的Excel文件名String fileName = "test.xlsx";// 设置响应的内容类型为二进制流,这是文件下载的标准设置response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);// 设置响应头的Content-Disposition,使用"attachment"指示浏览器这是一个需要下载的文件response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + URLEncoder.encode(fileName, StandardCharsets.UTF_8.toString()));// 查询需要导出的数据 (包含复杂数据)List<ExExcelQuestionOptionsDto> questionsOptionsAll = exQuestionMapper.getQuestionsOptionsAll();// 假设我们要合并第1行和第2列到第4列的数据(索引从0开始)int mergeRowIndex = 0; // 行索引 int[] mergeColumnIndex = new int[]{0,1,2,3,4,5,6}; // 列索引数组 要合并的列ExcelFillCellMergeStrategy excelFillCellMergeStrategy = new ExcelFillCellMergeStrategy(mergeRowIndex, mergeColumnIndex);EasyExcel.write(response.getOutputStream(), ExExcelQuestionOptionsDto.class).registerWriteHandler(excelFillCellMergeStrategy).sheet("测试").doWrite(questionsOptionsAll);return R.success();}
相关文章:

Java整合EasyExcel实战——3(上下列相同合并单元格策略)
参考:https://juejin.cn/post/7322156759443095561?searchId202405262043517631094B7CCB463FDA06https://juejin.cn/post/7322156759443095561?searchId202405262043517631094B7CCB463FDA06 准备条件 依赖 <dependency><groupId>com.alibaba</gr…...

dmdts连接kingbase8报错
dmdts连接kingbase报错 环境介绍1 人大金仓jdbc配置2 dmdts 人大金仓jdbc默认配置3 dmdts 修改jdbc配置4 达梦产品学习使用列表 环境介绍 dts版本 使用dmdts连接kingbase金仓数据库报错 无效的URL 对比jdbc连接串,修改配置解决 1 人大金仓jdbc配置 配置URL模版信息等 类名…...
【算法训练 day44 分割等和子集】
目录 一、分割等和子集-LeetCode 416思路实现代码1.二维dp代码2.一维dp代码 问题总结 一、分割等和子集-LeetCode 416 Leecode链接: leetcode 416 文章链接: 代码随想录 视频链接: B站 给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集&…...

前端实习记录——git篇(一些问题与相关命令)
1、版本控制 (1)版本回滚 git log // 查看版本git reset --mixed HEAD^ // 回滚到修改状态,文件内容没有变化git reset --soft HEAD^ // 回滚暂存区,^的个数代表几个版本git reset --hard HEAD^ // 回滚到修改状态ÿ…...
XML Web 服务技术解析:WSDL 与 SOAP 原理、应用案例一览
XML Web服务是一种用于在网络上发布、发现和使用应用程序组件的技术。它基于一系列标准和协议,如WSDL、SOAP、RDF和RSS。下面是一些相关的内容: WSDL(Web服务描述语言):用于描述Web服务的基于XML的语言,定义…...
解析Java中1000个常用类:FunctionalInterface类,你学会了吗?
Java 8 引入了一系列新的特性和改进,其中之一便是函数式编程。函数式接口(Functional Interface)是函数式编程的核心概念之一。本文将深入探讨 FunctionalInterface 注解,介绍其用法、重要性,并通过示例展示如何在实际开发中应用函数式接口。 什么是函数式接口? 函数式…...

Kafka自定义分区器编写教程
1.创建java类MyPartitioner并实现Partitioner接口 点击灯泡选择实现方法,导入需要实现的抽象方法 2.实现方法 3.自定义分区器的使用 在自定义生产者消息发送时,属性配置上加入自定义分区器 properties.put(ProducerConfig.PARTITIONER_CLASS_CONFIG,&q…...

python移动文件
测试1(直接把B文件夹移动到了A里,成为了A的子文件夹) import os import shutil# 移动文件夹,B文件夹在当前目录没有了,跑到了A的子文件里 ## shutil.move(./example1/B/, ./example1/A/)测试2(B文件不动,将B文件里的所有的子文件夹移动到A内…...

eNSP学习——OSPF的DR与BDR
目录 相关命令 原理概述 实验内容 实验目的 实验拓扑 实验编址 实验步骤 1、基本配置 2、搭建基本的OSPF网络 3、查看默认情况下的DR/BDR状态 4、根据现网需求影响DR/BDR选举 相关命令 [R4]int g0/0/0 [R4-GigabitEthernet0/0/0]ospf network-type p2mp //在接…...

【文献阅读】应用人工智能在Simulink中开发软件
参考文献:《AI用于Simulink模型的降阶方法和应用场景》Mathworks在2024年MATLAB XEPO大会的演讲 文章目录: 1、模型框架 2、数据准备 3、AI建模 4、仿真和测试 5、部署应用 Tips:降阶模型(Reduced Order Modeling࿰…...

【计算机毕设】基于SpringBoot的房产销售系统设计与实现 - 源码免费(私信领取)
免费领取源码 | 项目完整可运行 | v:chengn7890 诚招源码校园代理! 1. 研究目的 随着房地产市场的发展和互联网技术的进步,传统的房产销售模式逐渐向线上转移。设计并实现一个基于Spring Boot的房产销售系统࿰…...

Docker 私有仓库部署和管理
目录 一、案例一 概述 二、案例一 前置知识点 2.1、什么是 Docker Compose 2.2、什么是 Consul 三、案例一 使用 docker Compose 搭建 Consul 集群环境 3.1、案例实验环境 3.2、案例需求 四、案例实施 4.1、Docker 网络通信 1)端口映射 2…...

大模型时代的具身智能系列专题(六)
UCSD 王小龙组 王小龙是UCSD电子与计算机工程系的助理教授。他曾在加州大学伯克利分校与Alexei Efros和Trevor Darrell一起担任博士后研究员,在CMU RI获得了机器人学博士学位,师从Abhinav Gupta。他的研究重点是通过视频和物理机器人交互数据来学习3D和…...

Pytorch入门需要达到的效果
会搭建深度学习环境和依赖包安装 使用Anaconda创建环境、在pytorch官网安装pytorch、安装依赖包 会使用常见操作,例如matmul,sigmoid,softmax,relu,linear matmul操作见文章torch.matmul()的用法 sigmoid࿰…...

数据结构的快速排序(c语言版)
一.快速排序的概念 1.快排的基本概念 快速排序是一种常用的排序算法,它是基于分治策略的一种高效排序算法。它的基本思想如下: 从数列中挑出一个元素作为基准(pivot)。将所有小于基准值的元素放在基准前面,所有大于基准值的元素放在基准后面。这个过程称为分区(partition)操作…...
数据结构基础篇(4)
十六.循环链表 概念 循环链表是一种头尾相接的链表(最后一个结点的指针域指向头结点,整个链表形成一个环)优点 从表任一结点出发均可找到表中其他结点判断终止 由于循环链表中没有NULL指针,所以涉及遍历操作时,终止条…...

使用cad绘制一个螺旋输送机
1、第一步,绘制一个矩形 2、使用绘图中的样条线拟合曲线,绘制螺旋线。 绘制时使用上下辅助线、阵列工具绘制多个竖线保证样条线顶点在同一高度。 3、调整矩形右侧的两个顶点,使其变形。 矩形1和矩形2连接时,使用blend命令&#…...

迭代器模式(行为型)
目录 一、前言 二、迭代器模式 三、总结 一、前言 迭代器模式(Iterator Pattern)是一种行为型设计模式,提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。总的来说就是分离了集合对象的遍历行为,抽象出…...

Django——Admin站点(Python)
#前言: 该博客为小编Django基础知识操作博客的最后一篇,主要讲解了关于Admin站点的一些基本操作,小编会继续尽力更新一些优质文章,同时欢迎大家点赞和收藏,也欢迎大家关注等待后续文章。 一、简介: Djan…...
React 组件通信
1.从父组件向子组件传递参数: 父组件可以通过props将数据传递给子组件。子组件通过接收props来获取这些数据。 // 父组件 const ParentComponent () > {const data Hello, Child!;return <ChildComponent childData{data} />; }; // 子组件 const ChildCompone…...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...

深度学习在微纳光子学中的应用
深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...

【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

ardupilot 开发环境eclipse 中import 缺少C++
目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...

3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...