上一篇文章的补充。解决遗留问题:
对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());
}
重跑,成功得到结果:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。