Java整合EasyExcel实战——3(上下列相同合并单元格策略)

参考:https://juejin.cn/post/7322156759443095561?searchId=202405262043517631094B7CCB463FDA06icon-default.png?t=N7T8https://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();}

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

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

相关文章

邻接矩阵广度优先遍历

关于图的遍历实际上就两种 广度优先和深度优先&#xff0c;一般关于图的遍历都是基于邻接矩阵的&#xff0c;考试这些&#xff0c;用的也是邻接矩阵。 本篇文章先介绍广度优先遍历的原理&#xff0c;和代码实现 什么是图的广度优先遍历&#xff1f; 这其实和二叉树的层序遍…

新人学习笔记之(数组1)

一、数组的概念 1.数组&#xff08;Array&#xff09;可以把一组相关的数据一起存放&#xff0c;并提供方便的访问&#xff08;获取&#xff09;方式 2.数组是指一组数据的集合&#xff0c;其中的每个数据被称作元素&#xff0c;在数组中可以存放任意类型的元素&#xff0c;数组…

数据结构——二叉树的基本应用

在此之前我们已经初步了解了二叉树&#xff0c;在介绍堆的基本应用时&#xff0c;我们已经具体介绍了完全二叉树的基本应用&#xff0c;本章我们介绍二叉树的基本应用&#xff0c;这个不止指的是完全二叉树&#xff0c;而是指泛型的二叉树。 二叉树的基本应用&#xff0c;由于…

代码随想录算法训练营第54天|● 392.判断子序列 ● 115.不同的子序列

392. 判断子序列 这个微软面试的时候考过 双指针就行 编辑距离入门题&#xff1a; 思路是一样的 相同字符1 否则从前面顺下来 class Solution:def isSubsequence(self, s: str, t: str) -> bool:dp[[0]*(len(t)1) for _ in range(len(s)1)]for i in range(1,len(s)1):f…

aspose-*的使用

文章目录 aspose-*一、依赖--maven二、需求1、word------>pdf2、doc------>docx2、xls------>xlsx aspose-* 一、依赖–maven 备注&#xff1a;第三方的jar包可以从资源中下载&#xff0c;有上传的 <!--aspose依赖--><dependency><groupId>aspose…

刷代码随想录有感(81):贪心算法——分发饼干

题干&#xff1a; class Solution { public:int findContentChildren(vector<int>& g, vector<int>& s) {sort(g.begin(), g.end());sort(s.begin(), s.end());int index s.size() - 1;int res 0;for(int i g.size() - 1; i > 0; i--){if(index >…

GitLab项目中添加用户,并设置其角色权限等

注意&#xff1a;创建用户(new user)&#xff0c;创建完用户然后再项目邀请用户&#xff0c;选择创建过的用户 一、以管理员身份登录GitLab的WebUI并创建用户 1>.使用管理员登录GitLab 使用管理员(root)用户登录成功后&#xff0c;点击如下图所示的小扳手&#xff0c;点击…

java 反射的用法

下面是一个简单的Java反射示例&#xff0c;演示了如何使用反射机制获取类的信息并调用其方法&#xff1a; import java.lang.reflect.Method;class MyClass {private String name;public void setName(String name) {this.name name;}public String getName() {return name;}…

C++数据结构之:链List

摘要&#xff1a; it人员无论是使用哪种高级语言开发东东&#xff0c;想要更高效有层次的开发程序的话都躲不开三件套&#xff1a;数据结构&#xff0c;算法和设计模式。数据结构是相互之间存在一种或多种特定关系的数据元素的集合&#xff0c;即带“结构”的数据元素的集合&am…

在HTML和CSS当中运用显示隐藏

1.显示与隐藏 盒子显示:display:block;盒子隐藏: display:none:隐藏该元素并且该元素所占的空间也不存在了。 visibility:hidden:隐藏该元素但是该元素所占的内存空间还存在&#xff0c;即“隐身效果”。 2.圆角边框 在CSS2中添加圆角&#xff0c;我们不得不使用背景图像&am…

学习笔记——数据通信基础——数据通信网络(网络工程师)

网络工程师 网络工程&#xff0c;就是围绕着网络进行的一系列的活动&#xff0c;包括∶网络规划、设计、实施、调试、排错等。网络工程设计的知识领域很宽广&#xff0c;其中路由和交换是计算机网络的基本。 网络工程师∶是在网络工程领域&#xff0c;掌握专业的网络技术&…

散户如何参与期权交易?

期权就是股票&#xff0c;唯一区别标的物上证指数&#xff0c;会看大盘吧&#xff0c;期权交易两个方向认购做多&#xff0c;认沽做空&#xff0c;双向t0交易没了&#xff0c;期权交易跟期货一样&#xff0c;对的&#xff0c;玩的也是合约&#xff0c;唯一区别没有保证金不会爆…

军工行业运维解决方案

一、引言 随着军工行业的快速发展&#xff0c;信息化建设已成为提高作战效能、保障信息安全的重要支撑。然而&#xff0c;军工行业面临着多战区、跨区域、多阵地、多数据中心的复杂运维挑战。为了满足这些挑战&#xff0c;我们提出了一套基于美信时代的军工行业运维解决方案&am…

127.0.0.1 和 localhost 以及 0.0.0.0 区别

之前用 nginx 的时候&#xff0c;发现用这几个 IP&#xff0c;都能正常访问到 nginx 的欢迎网页。一度认为这几个 IP 都是一样的。 但本质上还是有些区别的。 首先 localhost 就不叫 IP&#xff0c;它是一个域名&#xff0c;就跟 "baidu.com",是一个形式的东西&…

什么是Redis脑裂,如何解决呢

Redis 脑裂问题是指&#xff0c;在 Redis 哨兵模式或集群模式中&#xff0c;由于网络原因&#xff0c;导致主节点&#xff08;Master&#xff09;与哨兵&#xff08;Sentinel&#xff09;和从节点&#xff08;Slave&#xff09;的通讯中断&#xff0c;此时哨兵就会误以为主节点…

方均根为什么等于有效值

方均根值&#xff08;Root Mean Square&#xff0c;简称RMS&#xff09;等于有效值&#xff0c;是因为这种计算方法能够准确地反映周期性波动量&#xff08;如交流电、振动等&#xff09;的平均能量或做功能力。对于交流电而言&#xff0c;其瞬时值随时间变化&#xff0c;直接取…

IdentiFace——多模态人脸识别系统,可捕捉从情绪到性别的所有信息及其潜力

1. 概述 面部识别系统的开发极大地推动了计算机视觉领域的发展。如今&#xff0c;人们正在积极开发多模态系统&#xff0c;将多种生物识别特征高效、有效地结合起来。 本文介绍了一种名为 IdentiFace 的多模态人脸识别系统。该系统利用基于 VGG-16 架构的模型&#xff0c;将人…

【NumPy】NumPy线性代数模块详解:掌握numpy.linalg的核心功能

&#x1f9d1; 博主简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟&#xff0c;欢迎关注。提供嵌入式方向…

多年期货盈利的秘诀就是亏了就跑

不怎么看消息面&#xff0c;尤其期货&#xff0c;外汇。 正大招主账户&#xff1a;欧美4恒指26小恒12 欢迎咨询代理 详YJCFPL 坚持学习&#xff0c;吸收别人的经验&#xff0c;为我所用。 独立思考&#xff0c;培养良好的生活习惯。 我能活到现在的秘诀就是&#xff1a;亏了就赶…

Hexo最新实战:(一)Hexo7.0+GitHub Pages博客搭建

前言 很多平台都能写博客还有创作激励&#xff0c;为什么我又要搭一个&#xff1f;为什么这次要选择用Hexo框架&#xff1f; 对应的原因是流量自由和省钱&#xff0c;第一个&#xff0c;很多平台能写但不是都有收益&#xff0c;而且平台有自身的规则&#xff0c;比如会屏蔽一…