上一篇文章的补充。解决遗留问题:

对mergedRegionHelper实现革新之后,不能反对模板配置为一行多个后果集、并且后果集都存在合并单元格的状况。比方:

导出数据,零碎会报错:

剖析了一下,是因为咱们尽管批改mergedRegionHelper的算法,在插入行之后不再对缓存数据做调整、而是记录了插入的行数,然而因为easypoi解决模板的的形式是从上到下、从左到右逐行、逐列解决模板的单元格。

如上图的模板,当解决到第2行第一列的时候碰到foreash,如果咱们给的数据集多于1条数据的话,就会插入行、调用mergedRegionHelper的shiftrow办法从而更新掉咱们新增的属性rowsSfhited。当持续解决到第2行的第二个foreach的时候,调用mergedRegionHelper判断是否是合并单元格的时候就会出问题,因为这个时候mergedRegionHelper的rowsShifted曾经被更新了:

    public boolean isMergedRegion(int row, int col) {        //20230211 new added SHIFTMETHOD_KEEP_MERGEDCACHE        if(shiftMethod == SHIFTMETHOD_KEEP_MERGEDCACHE)            row -= rowsShifted;        return mergedCache.containsKey(row + "_" + col);    }

想要判断的是第2行的数据,然而理论并不是第2行,所以导致谬误。

解决bug

仔细分析一下批改后的mergedRegionHelper逻辑,其实咱们只有能做到当一行数据处理实现、筹备解决下一行数据的时候,更新mergedRegionHelper的rowsShfited属性,就不会有问题了。

所以咱们就找到这个逻辑的地位,在ExcelExportOfTemplateUtil#parseTemplate办法,须要初始化新增变量shiftCache(shiftCache是为了反对单行多个数据集而引入的缓存变量,用来记录每一个foreach行插入了多少行数据):

而后在循环解决以后行所有列完结、要跳转到下一行的循环前,解决mergedRegionHelper:

for (int i = row.getFirstCellNum(); i < row.getLastCellNum(); i++) {                if (row.getCell(i) != null && !tempCreateCellSet                        .contains(row.getRowNum() + "_" + row.getCell(i).getColumnIndex())) {                    setValueForCellByMap(row.getCell(i), map);                }            }            //20230212 check shifed rows from shiftCache and set to mergedRegionHelper            // when we moved to the next row            if(shiftCache.get(row.getRowNum()+1)!=null){                mergedRegionHelper.shiftRows(sheet, row.getRowNum(), shiftCache.get(row.getRowNum()+1), sheet.getLastRowNum());            }

重跑,胜利失去后果:

上一篇 easypoi 模板导出时的公式及foreach合并单元格问题