easyexcel
easyexcel copied to clipboard
调用 ExcelWriter 的 fill 方法时,如果传入的 data 参数内含的集合元素类型是 Map,且某些元素中缺失某些 key,就会导致生成的 Excel 文件中数据行错位
触发场景描述
调用 ExcelWriter
的 fill
方法时,如果传入的 data
参数内含的集合元素类型是 Map
,且某些元素中缺失某些 key,就会导致生成的 Excel 文件中数据行错位。
easyexcel 版本 3.3.3。
触发Bug的代码
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。
模板文件很简单:
输出结果文件中,从 a5
这一行开始发生了错位,b6
跑到了同一行来。
模板文件: template3.xlsx 输出结果文件: result3.xlsx
临时解决办法
我自行修改了 easyexcel 的源代码,主要是把 ExcelWriteFillExecutor
类中的 215 行以及 250 行给删除掉:
if (!dataKeySet.contains(variable)) {
continue;
}
一些疑问和探讨
我对上述代码的写法不太理解。在 203 行,根据传入参数 Map 的 keySet
创建了 dataKeySet
:
Set<String> dataKeySet = new HashSet<>(dataMap.keySet());
然后这个 dataKeySet
的作用也仅仅就是后续 215 行以及 250 行的:
if (!dataKeySet.contains(variable)) {
continue;
}
为什么要这么麻烦创建 dataKeySet
?不能直接使用 dataMap.containsKey(variable)
吗?
如果直接使用 dataMap.containsKey(variable)
的话,我就不用修改 easyexcel 源代码了。我可以对传入的 Map
对象做个包装,包装成一个 containsKey
方法直接返回 true
的特殊 Map
对象,这样就能回避掉 215 行以及 250 行的检查了。像这样:
为什么最新的release中不包含这个问题的修复?