首页 > 其他分享 >easyexcel合并策略

easyexcel合并策略

时间:2024-03-30 17:33:05浏览次数:17  
标签:currentRow 策略 easyexcel 合并 private preData Integer preDataFirstRow currentColDat

1、行合并

@Slf4j
public class ExcelRowHandler implements RowWriteHandler {

    /**
     * 起始行索引
     */
    private Integer startRowIndex = 0;

    /**
     * 结束行索引
     */
    private Integer endRowIndex;

    private Set<Integer> mergeColSet = new HashSet<>();

    public ExcelRowHandler() {}

    public ExcelRowHandler(Integer startRowIndex, Integer endRowIndex) {
        this.startRowIndex = startRowIndex;
        this.endRowIndex = endRowIndex;
    }

    public ExcelRowHandler(Integer startRowIndex, Integer endRowIndex, Set<Integer> mergeColSet) {
        this.startRowIndex = startRowIndex;
        this.endRowIndex = endRowIndex;
        this.mergeColSet = mergeColSet;
    }

    /**
     * 存储列的值
     */
    private Map<Integer, String> columnDataMap = new HashMap<>();

    /**
     * 存储该数据第一次出现行
     */
    private Map<String, Integer> currentDataFirstRowMap = new HashMap<>();


    @Override
    public void afterRowDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Integer relativeRowIndex, Boolean isHead) {
        // 不是表头数据开始处理
        if (!isHead) {
            // 获取表格对象
            Sheet sheet = writeSheetHolder.getSheet();
            // 获取当前行索引
            int currentRow = row.getRowNum();
            // 获取前一行索引
            int preRow = currentRow - 1;
            if (currentRow >= startRowIndex && currentRow <= endRowIndex && null != mergeColSet && mergeColSet.isEmpty()) {
                for (Integer i : mergeColSet) {
                    // 等于起始行 存储当前行的值
                    if (currentRow == startRowIndex) {
                        columnDataMap = new HashMap<>();
                        currentDataFirstRowMap = new HashMap<>();
                        String currentColData = row.getCell(i).getStringCellValue();
                        if (!TextUtil.isEmpty(currentColData)) {
                            currentDataFirstRowMap.put(getKey(currentColData, i), currentRow);
                            columnDataMap.put(i, currentColData);
                        }
                    } else {
                        // 获取当前行当前列的值
                        String currentColData = row.getCell(i).getStringCellValue();
                        // 获取当前列前一行的值
                        String preData = columnDataMap.get(i);
                        // 不为空进行数据处理
                        if (!TextUtil.isEmpty(currentColData)) {
                            // 当前列前一行为空
                            if (TextUtil.isEmpty(preData)) {
                                // 存储当前行当前列第一个出现的位置
                                currentDataFirstRowMap.put(getKey(currentColData, i), currentRow);
                                // 存储当前列正扫描到的值
                                columnDataMap.put(i, currentColData);
                            } else {
                                // 当前行前一列不为空 判断当前行当前列的值是否和前一行当前列的值相等
                                if (!preData.equals(currentColData)) {
                                    // 如果不相等 合并之前的单元格 获取前一个值第一次出现的位置
                                    Integer preDataFirstRow = currentDataFirstRowMap.get(getKey(preData, i));
                                    if (null != preDataFirstRow && preDataFirstRow != preRow) {
                                        // 当前列前一行数据第一次出现的位置不为空 且不是在前一行第一次出现 合并单元格
                                        log.info("合并数据:{},开始行:{},结束行:{},列:{}", preData, preDataFirstRow, preRow, i);
                                        mergeRegion(sheet, preDataFirstRow, preRow, i);
                                    }
                                    currentDataFirstRowMap.remove(getKey(preData, i));
                                    // 清楚当前列扫描到的值
                                    columnDataMap.remove(i);
                                    // 存储当前值第一次出现的位置
                                    currentDataFirstRowMap.put(getKey(currentColData, i), currentRow);
                                    // 存储当前列新扫描到的值
                                    columnDataMap.put(i, currentColData);
                                }
                                // 如果相等 继续判断下一行当前列
                            }
                        } else {
                            // 当前行当前列的值为空 判断前一行当前列的值
                            if (!TextUtil.isEmpty(preData)) {
                                // 前一行当前列的值不为空 获取前一行当前列的数据第一次出现的位置
                                Integer preDataFirstRow = currentDataFirstRowMap.get(getKey(preData, i));
                                if (null != preDataFirstRow && preDataFirstRow != preRow) {
                                    // 第一次出现的位置不为空并且不是在前一行第一次出现
                                    log.info("合并数据:{},开始行:{},结束行:{},列:{}", preData, preDataFirstRow, preRow, i);
                                    mergeRegion(sheet, preDataFirstRow, preRow, i);
                                }
                            }
                            currentDataFirstRowMap.remove(getKey(preData,i));
                            // 清空当前列扫描到的值
                            columnDataMap.remove(i);
                        }
                    }
                }
            }
        }
    }

    private String getKey(String data, int col) {
        return data + "-" + col;
    }

    private void mergeRegion(Sheet sheet, int firstRow, int lastRow, int col) {
        CellRangeAddress cellAddresses = new CellRangeAddress(firstRow, lastRow, col, col);
        sheet.addMergedRegion(cellAddresses);
    }
}

2、列合并

@Slf4j
public class ExcelColHandler implements RowWriteHandler {

    private Integer firstColIndex = 0;

    private Integer lastColIndex = 0;

    public ExcelColHandler() {}

    public ExcelColHandler(Integer firstColIndex, Integer lastColIndex) {
        this.firstColIndex = firstColIndex;
        this.lastColIndex = lastColIndex;
    }

    /**
     * 存储该数据第一次出现的列
     */
    private Map<String, Integer> dataFirstColMap = new HashMap<>();

    @Override
    public void afterRowDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Integer relativeRowIndex, Boolean isHead) {
        if (!isHead) {
            // 获取表格对象
            Sheet sheet = writeSheetHolder.getSheet();
            // 获取当前行索引
            int currentRow = row.getRowNum();
            String preData = null;
            for (Integer i = firstColIndex; i <= lastColIndex; i++) {
                String currentData = row.getCell(i).getStringCellValue();
                if (!TextUtil.isEmpty(currentData)) {
                    // 当前单元格值不为空 是第一列存储当前单元格值
                    if (Objects.equals(firstColIndex, i)) {
                        preData = currentData;
                        dataFirstColMap.put(currentData, i);
                    } else {
                        if (null != preData) {
                            if (!currentData.equals(preData)) {
                                Integer firstCol = dataFirstColMap.get(preData);
                                if (null != firstCol && firstCol != i - 1) {
                                    // 合并数据
                                    mergeRegion(sheet, currentRow, firstCol, i - 1);
                                }
                                preData = currentData;
                                dataFirstColMap.remove(preData);
                                dataFirstColMap.put(currentData, i);
                            }
                        } else {
                            preData = currentData;
                            dataFirstColMap.put(currentData, i);
                        }
                    }
                } else if (!TextUtil.isEmpty(preData)) {
                    Integer firstCol = dataFirstColMap.get(preData);
                    if (null != firstCol && firstCol != i - 1) {
                        // 合并数据
                        mergeRegion(sheet, currentRow, firstCol, i - 1);
                    }
                    dataFirstColMap.remove(preData);
                    preData = null;
                }
            }
        }
    }

    private void mergeRegion(Sheet sheet, int row, int firstCol, int lastCol) {
        CellRangeAddress cellAddresses = new CellRangeAddress(row, row, firstCol, lastCol);
        sheet.addMergedRegion(cellAddresses);
    }
}

标签:currentRow,策略,easyexcel,合并,private,preData,Integer,preDataFirstRow,currentColDat
From: https://blog.csdn.net/a11_11_11/article/details/137119543

相关文章

  • P4556 [Vani有约会] 雨天的尾巴 /【模板】线段树合并
    P4556[Vani有约会]雨天的尾巴/【模板】线段树合并在这题里面讲一下线段树合并。顾名思义就是把多个线段树合并成一个。显然完全二叉线段树(也就是普通线段树)是无法更高效的合并的,只能把所有节点加起来建个新树。但是在动态开点线段树中,有时候一个树只有几条链,这时候我们就是可......
  • 代码随想录训练营Day36:● 435. 无重叠区间 ● 763.划分字母区间 ● 56. 合并区间
    435.无重叠区间题目链接https://leetcode.cn/problems/non-overlapping-intervals/description/题目描述思路直接统计重叠区间的个数,就是需要删除的个数publicinteraseOverlapIntervals(int[][]intervals){Arrays.sort(intervals,(a,b)->Integer.com......
  • KingbaseES行级安全策略
    什么是行级安全策略(RLS)?行安全策略就是对不同用户,不同行数据的可见性,和可修改性。是表权限的一种扩展。默认情况下表没有任何安全策略限制。这样用户根据自身对表持有的权限来操作表数据,对于查询或更新来说其中所有的行都是平等的。当在一个表上启用行安全性时,所有对该表的操......
  • ELK保留策略
    ELK(Elasticsearch,Logstash,Kibana)是一套用于日志管理和分析的开源工具。在Elasticsearch中,数据保留策略通常是通过索引生命周期管理(ILM)来实现的。以下是一个基于ILM的ELK保留策略的示例配置:首先,确保Elasticsearch已经启用了ILM功能。接下来,创建一个ILM策略,定义保留行为:......
  • 深度学习技巧应用39-深度学习模型训练过程中数据均衡策略SMOTE的详细介绍,以及SMOTE的
    大家好,我是微学AI,今天给大家介绍一下深度学习技巧应用39-深度学习模型训练过程中数据均衡策略SMOTE的详细介绍,以及SMOTE的算法原理与实现,本文介绍了一种用于处理分类数据不平衡问题的过采样方法——SMOTE算法。SMOTE算法通过在少数类的样本之间插值来创建新的样本,从而增加少......
  • 在分支10上revert已合并的分支1,在分支11上合并分支1,在新的分支12上拉去分支10,再拉去分
    在分支10上revert已合并的分支1,在分支11上合并分支1,在新的分支12上拉去分支10,再拉去分支11,为什么不能拉去到分支1的更新内容git的版本管理会记录全局所有分支的revert事件,所有分支合并中存在revert事件,后续都会存在,解决方法:revert掉对应分支上的revert事件,再合并;或者根据你的描......
  • YoloV8改进策略:BackBone改进|EfficientVMamba
    摘要https://arxiv.org/pdf/2403.09977.pdf先前的轻量级模型开发努力主要集中在基于CNN和Transformer的设计上,但仍面临持续的挑战。CNN擅长局部特征提取,但会牺牲分辨率,而Transformer提供了全局范围,但会加剧计算需求O......
  • 合并区间 - LeetCode 热题 14
    大家好!我是曾续缘......
  • 综合实验,策略路由(BFD,NAT)
    涉及:VLANVLANIFaccesstrunkDHCPRIPOSPFACLNATBFD策略路由iproute-static[preference]LoopBack  <Huawei>system-view[Huawei]sysnameacsw[acsw]undoinfo-centerenable[acsw]vlanbatch1020[acsw]intg0/0/24[acsw-GigabitEthernet0/0/24]p......
  • 【智能算法改进】混沌映射策略--一网打尽
    目录1.引言2.混沌映射3.分布特征4.混沌映射函数调用5.改进智能算法1.引言基本种群初始化是在整个空间内随机分布,具有较高的随机性和分布不均匀性,会导致种群多样性缺乏,搜索效率低等问题。许多学者利用混沌映射机制来增加种群的多样性,以改善算法的性能,其非线性特性......