共计 1428 个字符,预计需要花费 4 分钟才能阅读完成。
上一篇文章的补充。解决遗留问题:
对 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 合并单元格问题