EasyExcel复杂导出 一对多

news/2024/9/20 17:45:45/文章来源:https://www.cnblogs.com/yzxsx/p/18325337

 将数据一条一条查出来 千万不要用一对多查询 最后用方法进行合并

public class ExcelFileCellMergeStrategy implements CellWriteHandler{

/**
* 合并列的范围索引
*/
private int[] mergeColumnIndex;

/**
* 合并起始行索引
*/
private int mergeRowIndex;

/**
* 合并校验列值
*/
private int colIndex;


public ExcelFileCellMergeStrategy(int[] mergeColumnIndex, int mergeRowIndex, int colIndex) {
this.mergeColumnIndex = mergeColumnIndex;
this.mergeRowIndex = mergeRowIndex;
this.colIndex = colIndex;
}


@Override
public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {

//当前行
int curRowIndex = cell.getRowIndex();
//当前列
int curColIndex = cell.getColumnIndex();
//某行开始合并
if (curRowIndex > mergeRowIndex) {
//判断每行的第一列是否相同,相同时进行合并
if (isSame(cell, curRowIndex)) {
for (int columnIndex : mergeColumnIndex) {
//对应的列进行合并
if (curColIndex == columnIndex) {
mergeWithPrevRow(writeSheetHolder, cell, curRowIndex, curColIndex);
break;
}
}
}
}
}

private Boolean isSame(Cell cell, int curRowIndex){
//获取当前行的某列的数据
Cell curCell = cell.getSheet().getRow(curRowIndex).getCell(colIndex);
//当前行某列值
Object curData = curCell.getCellTypeEnum() == CellType.STRING ? curCell.getStringCellValue() : curCell.getNumericCellValue();
//获取当前行的上一行数据
Cell preCell = cell.getSheet().getRow(curRowIndex - 1).getCell(colIndex);
//上一行某列值
Object preData = preCell.getCellTypeEnum() == CellType.STRING ? preCell.getStringCellValue() : preCell.getNumericCellValue();
// 比较当前行的某列的单元格与上一行是否相同,相同合并当前单元格与上一行
return curData.equals(preData);
}

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> mergedRegions = sheet.getMergedRegions();
boolean isMerged = false;
for (int i = 0; i < mergedRegions.size() && !isMerged; i++) {
CellRangeAddress cellAddresses = mergedRegions.get(i);
//若上 一个单元格已经被合并,则先移出原有的合并单元,再重新添加合并单元
if (cellAddresses.isInRange(curRowIndex - 1 , curColIndex)){
sheet.removeMergedRegion(i);
cellAddresses.setLastRow(curRowIndex);
sheet.addMergedRegion(cellAddresses);
isMerged = true;
}
}
//若上一个单元格未被合并,则新增合并单元
if (!isMerged){
CellRangeAddress cellAddresses = new CellRangeAddress(curRowIndex - 1, curRowIndex, curColIndex, curColIndex);
sheet.addMergedRegion(cellAddresses);
}
}
}

}
这个是进行合并的类方法 到时候导入到类里面直接调用就行
可以直接粘贴复制 不需要修改

 

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

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

相关文章

DASCTF-Tele

首先提示通话流量,那就直接搜索Tele追踪流量发现是UDP的流,那就过滤打开发现了IPDASCTF{171.88.96.93}

Ryujinx(Switch模拟器) v1.1.1361 汉化版

Ryujinx 是一款免费、开源的 Nintendo Switch 模拟器,它可以在电脑上模拟 Nintendo Switch 游戏机的运行环境,让玩家们能够在 PC 上畅玩 Switch 游戏。Ryujinx 支持大部分 Nintendo Switch 游戏,包括 The Legend of Zelda: Breath of the Wild、Super Mario Odyssey 等知名游…

数业智能心大陆:定制你的专属心理健康方案

在快速变化的社会中,随着人们对自我健康认识的不断加深,心理健康已成为影响生活质量的关键因素,许多成年人在其一生中会遇到心理健康问题。在探索人类心理奥秘的旅程中,我们发现,每个人的心理状态和需求都是独一无二的。面对日益增长的心理健康需求,传统的“一刀切”服务…

在KubeSphere 容器中快速部署使用 GitLab 并构建 DevOps 项目

我们先这次的演练创建一个名为devops的企业空间,同时创建一个名为gitlab的项目供GitLabCE部署使用。首先我们还是要先在devops企业空间中添加GitLab的官方HelmChart仓库,推荐用这种自管理的方式来保障仓库内容是得到及时同步的。通过「应用管理」下面的「应用仓库」来添加如下…

梯度回归三步走

模型训练的每个周期内我们会碰到以下固定的代码逻辑组合:optimizer.no_grad()loss.backward()optimizer.step()他们的作用分别为:optimizer.no_grad(): 清空上一轮训练留下来的梯度值。 每一轮梯度训练过程中,针对模型的参数集,都会生成相应的梯度x.grad, 如果不显式清零,…

一文详解 JuiceFS 读性能:预读、预取、缓存、FUSE 和对象存储

在高性能计算场景中,往往采用全闪存架构和内核态并行文件系统,以满足性能要求。随着数据规模的增加和分布式系统集群规模的增加,全闪存的高成本和内核客户端的运维复杂性成为主要挑战。 JuiceFS,是一款全用户态的云原生分布式文件系统,通过分布式缓存大幅提升 I/O 吞吐量,…

EasyExcel简单导出

@ApiOperation("导出历史上送记录")@PostMapping(value = "/exportSend", produces = "application/octet-stream")public void exportExcel(@RequestBody ExportSendVO sendVO, HttpServletResponse response) throws Exception { // 获取数…

华为云对象存储OBS obsutil复制对象定时备份

Linux系统使用 一、下载obsutil安装包安装我这里是x86架构的,ARM架构:wget https://obs-community.obs.cn-north-1.myhuaweicloud.com/obsutil/current/obsutil_linux_arm64.tar.gz执行wget命令下载obsutil工具 wget https://obs-community.obs.cn-north-1.myhuaweicloud.com…

Kruskal 重构树学习笔记

Kruskal 想必大家都不陌生,这是一种求最小生成树的算法。 关于 Kruskal 重构树,就是把一张图转化为一个堆。 具体来说,我们可以处理出来从 \(u\) 到 \(v\) 路径中的点权或边权的极值。比如上面这张图(前为编号,[ ]内为点权),我们可以将它重构为小顶堆,如下请注意,这棵…

搭建.Net WebApi并配置Swagger(一)

C#进阶之WebAPI(一) 那么首先第一点:什么是WebAPI?    首先我们了解一下.net framework 的框架构成: 可以看到,WebAPI和mvc同属于B/S模板框架的一种,官方对于WebApi的定义是:WebAPI是一个框架,可以轻松构建HTTP服务,覆盖广泛的客户端,包括浏览器和移动设备,Web…

财务知识-专票和普票的区别

财务知识-专票和普票的区别