【学习总结】EasyExcel合并同列不同行,表格数据相同的行

2023-11-05

实体类

@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;

    @ExcelIgnore
    private 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<>();

    @Override
    protected 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);

    }
    
    
    
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【学习总结】EasyExcel合并同列不同行,表格数据相同的行 的相关文章

随机推荐

  • kafka介绍,安装以及简单的java调用kafka代码

    Producer 消息生产者 向broker发消息的客户端 Consumer 消息消费者 向broker取消息的客户端 Topic 一个队列 主题 Message 消息是kafka处理的对象 在kafka中 消息是被发布到broker的to
  • 【R】【纽约人口数量分析】

    文章目录 1 实验说明 2 实验环境 3 实验目的 4 实验内容 5 实验步骤 下载并导入数据 对生成的时间序列对象可视化 a 思考 b 由上述三种变量查看各个波动趋势数据 c 由上述结果可知 使用 plot 函数 修正数据 6 实验分析
  • Cadence学习六:ORCAD里怎么增加和删除Offpage connector

    ORCAD里怎么增加和删除Offpage connector 注 本文是个人再学习cadence17 4的时候遇到的问题小结 任何人不得商用 如有侵权 请联系本人删除 问题概述 对于ORCAD有多个页面的原理图 off page担当着在不同
  • error: C2248: “QObject::QObject”: 无法访问 private 成员(在“QObject”类中声明)

    QT中使用的C 对象经常会用到数据类 而存放数据可以选择使用QList lt gt QMap lt gt 等模板类存放指针或是对象 如果是选择存数据对象 考虑好之后的数据最好是静态访问的 很少去修改的 在存放的时候就会报上面的错误 原因是没
  • 各种通信接口的简单对比

    对比表 同步方式与异步方式的主要区别在于 是否传输时钟信号 只要是通訊前雙方需要設定相同波特率的 都是異步傳輸方式 异步传输 Asynchronous Transmission 每次异步传输的信息都以一个起始位开头 它通知接收方数据已经到达
  • 微服务之间调用的异常应该如何处理

    前言 在分布式服务的场景下 业务服务都将进行拆分 不同服务之间都会相互调用 如何做好异常处理是比较关键的 可以让业务人员在页面使用系统报错后 很清楚的看到服务报错的原因 而不是返回代码级别的异常报错 比如NullException Ille
  • datetime 模块详解 -- 基本的日期和时间类型

    转自 https www cnblogs com fclbky articles 4098204 html datetime 模块提供了各种类用于操作日期和时间 该模块侧重于高效率的格式化输出在 Python 中 与时间处理有关的模块包括
  • 6-11 删除字符 (20 分)

    本题要求实现一个删除字符串中的指定字符的简单函数 函数接口定义 void delchar char str char c 其中char str是传入的字符串 c是待删除的字符 函数delchar的功能是将字符串str中出现的所有c字符删除
  • Nginx+FastCGI参数传递

    如果需要将需要将各种参数传递到fcgi 例如传递请求参数 请求方法等到fcgi 需要在nginx中加配置 location fcgi fastcgi pass ip port fastcgi param QUERY STRING query
  • 汉诺塔的相关应用

    汉诺塔的应用 是递归的一种比较例子 题目藐视见下面 就是一个递归的实现 先把a上的n 1个盘同过c移到b 再把a上的最后一只盘移到c 随后再把b上的n 1只盘通过a 移到c 描述就是这样 include
  • 两个接口和一个类的适配器模式

    适配器类实现其中一个接口方法 创建另一个接口的对象和构造方法 在接口方法中调用另一个接口的方法 实例如下 public class shipeiqi public static void main String args ATable aT
  • 基于神经网络的目标检测论文之DenseNet:密集连接的卷积神经网络

    第三章 基于密集连接卷积网络改进的目标分类算法 最近的研究表明 如果卷积网络包含接近输入的层和接近输出的层之间的较短连接 则卷积网络可以更深入 更精确和更有效地进行训练 在本章中 论文首先研究密集卷积网络 DenseNet 的结构和工作原理
  • USB转RS485串口电路设计

    USB转串口芯片的串口信号一般为 TTL CMOS电平 在实现半双工 RS485 串口时需要外接485电平转换芯片 设计中需要有信号来控制 485 转接芯片的发送和接收使能端 建议选择自带485控制引脚的转接芯片 如 CH340 CH342
  • MybatisPlus中removeById删除数据库未变

    removeById Serializable id 传入的是id Integer Long等 不是实体对象 就是对应你表的主键 由于我刚开始建表时未设置主键mybatisplus自动生成未在实体类表中标注主键 后加了主键 所以需在实体类主
  • 各种遥感数据,地理信息数据共享网站

    各种遥感数据 地理信息数据共享网站 至少一百 Online Global Satellite Image and Atlas http library gmu edu resources sci Geog579 htm 可以下载Aster
  • Java开发中的23种设计模式详解

    设计模式 Design Patterns 可复用面向对象软件的基础 设计模式 Design pattern 是一套被反复使用 多数人知晓的 经过分类编目的 代码设计经验的总结 使用设计模式是为了可重用代码 让代码更容易被他人理解 保证代码可
  • word怎么让封面、目录没有页码,页码从正文开始

    word怎么让封面 目录没有页码 页码从正文开始 1 开始插入页码 从第一页开始 如图 二 如果前两页是封面和目录 再从第一页开始就不合适了 解决步骤如下 1 在第三页的文字前面添加分页符 效果如图 2 选中第三页的页码 跳到设置页眉页脚的
  • Windows powershell增设快捷指令(Git版)

    1 创建并修改Windows Powershell 启动执行文件 echo PROFILE 输出的是powershell的执行文件路径 2 切换到WindowPowerShell路径下 创建文件 Microsoft PowerShell p
  • MySQL 数据类型

    目录 数据类型 数据类型分类 数值类型 bit类型 小数类型 float decimal 字符串类型 char varchar char和varchar比较 日期和时间类型 enum和set 集合查询使用find in set函数 afte
  • 【学习总结】EasyExcel合并同列不同行,表格数据相同的行

    实体类 Data HeadRowHeight 50 ContentStyle horizontalAlignment HorizontalAlignmentEnum CENTER verticalAlignment VerticalAlig