Open zhuermao opened 7 months ago
调用 ExcelWriter 的 fill 方法时,如果传入的 data 参数内含的集合元素类型是 Map,且某些元素中缺失某些 key,就会导致生成的 Excel 文件中数据行错位。
ExcelWriter
fill
data
Map
easyexcel 版本 3.3.3。
public static void main(String[] args) { // 准备 10 行数据,基本上每行都有 aaa 和 bbb 两个 key,值分别为 a1 和 b1, a2 和 b2, ... // 唯独第 5 行,故意删除掉 bbb 这个 key List<Map<String, Object>> dataLineList = new ArrayList<>(); for (int i = 1; i <= 10; i++) { Map<String, Object> m = new HashMap<>(); m.put("aaa", "a" + i); m.put("bbb", "b" + i); if (i == 5) { m.remove("bbb"); } dataLineList.add(m); } ExcelWriter excelWriter = EasyExcel.write("./run/result3.xlsx").withTemplate("./run/template3.xlsx").build(); WriteSheet writeSheet = EasyExcel.writerSheet().build(); FillConfig fillConfig = FillConfig.builder().direction(WriteDirectionEnum.VERTICAL).build(); excelWriter.fill(new FillWrapper("dataLine", dataLineList), fillConfig, writeSheet); excelWriter.writeContext().writeWorkbookHolder().getWorkbook().setForceFormulaRecalculation(true); excelWriter.finish(); }
上述代码准备了 10 行数据,基本上每行都有 aaa 和 bbb 两个 key,值分别为 a1 和 b1, a2 和 b2, ...。 唯独第 5 行,故意删除了 bbb 这个 key。
aaa
bbb
a1
b1
a2
b2
模板文件很简单:
输出结果文件中,从 a5 这一行开始发生了错位,b6 跑到了同一行来。
a5
b6
模板文件: template3.xlsx 输出结果文件: result3.xlsx
我自行修改了 easyexcel 的源代码,主要是把 ExcelWriteFillExecutor 类中的 215 行以及 250 行给删除掉:
ExcelWriteFillExecutor
if (!dataKeySet.contains(variable)) { continue; }
我对上述代码的写法不太理解。在 203 行,根据传入参数 Map 的 keySet 创建了 dataKeySet:
keySet
dataKeySet
Set<String> dataKeySet = new HashSet<>(dataMap.keySet());
然后这个 dataKeySet 的作用也仅仅就是后续 215 行以及 250 行的:
为什么要这么麻烦创建 dataKeySet?不能直接使用 dataMap.containsKey(variable) 吗?
dataMap.containsKey(variable)
如果直接使用 dataMap.containsKey(variable) 的话,我就不用修改 easyexcel 源代码了。我可以对传入的 Map 对象做个包装,包装成一个 containsKey 方法直接返回 true 的特殊 Map 对象,这样就能回避掉 215 行以及 250 行的检查了。像这样:
containsKey
true
为什么最新的release中不包含这个问题的修复?
触发场景描述
调用
ExcelWriter
的fill
方法时,如果传入的data
参数内含的集合元素类型是Map
,且某些元素中缺失某些 key,就会导致生成的 Excel 文件中数据行错位。easyexcel 版本 3.3.3。
触发Bug的代码
上述代码准备了 10 行数据,基本上每行都有
aaa
和bbb
两个 key,值分别为a1
和b1
,a2
和b2
, ...。 唯独第 5 行,故意删除了bbb
这个 key。模板文件很简单:
输出结果文件中,从
a5
这一行开始发生了错位,b6
跑到了同一行来。模板文件: template3.xlsx 输出结果文件: result3.xlsx
临时解决办法
我自行修改了 easyexcel 的源代码,主要是把
ExcelWriteFillExecutor
类中的 215 行以及 250 行给删除掉:一些疑问和探讨
我对上述代码的写法不太理解。在 203 行,根据传入参数 Map 的
keySet
创建了dataKeySet
:然后这个
dataKeySet
的作用也仅仅就是后续 215 行以及 250 行的:为什么要这么麻烦创建
dataKeySet
?不能直接使用dataMap.containsKey(variable)
吗?如果直接使用
dataMap.containsKey(variable)
的话,我就不用修改 easyexcel 源代码了。我可以对传入的Map
对象做个包装,包装成一个containsKey
方法直接返回true
的特殊Map
对象,这样就能回避掉 215 行以及 250 行的检查了。像这样: