Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

调用 ExcelWriter 的 fill 方法时,如果传入的 data 参数内含的集合元素类型是 Map,且某些元素中缺失某些 key,就会导致生成的 Excel 文件中数据行错位 #3604

Open
zhuermao opened this issue Dec 14, 2023 · 1 comment
Assignees
Labels
bug Something isn't working developing This feature will be added in future releases development completed Development completed, waiting for release

Comments

@zhuermao
Copy link

zhuermao commented Dec 14, 2023

触发场景描述

调用 ExcelWriterfill 方法时,如果传入的 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 行数据,基本上每行都有 aaabbb 两个 key,值分别为 a1b1, a2b2, ...。 唯独第 5 行,故意删除了 bbb 这个 key。

模板文件很简单:

image

输出结果文件中,从 a5 这一行开始发生了错位,b6 跑到了同一行来。

image

模板文件: 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 行的检查了。像这样:

image

@zhuermao zhuermao added the bug Something isn't working label Dec 14, 2023
@youlingdada youlingdada self-assigned this Dec 16, 2023
@youlingdada youlingdada added the developing This feature will be added in future releases label Dec 16, 2023
youlingdada pushed a commit to youlingdada/my-easyexcel that referenced this issue Dec 16, 2023
…not increased due to blank data appearing during filling.
youlingdada added a commit to youlingdada/my-easyexcel that referenced this issue Dec 16, 2023
…not increased due to blank data appearing during filling.
youlingdada added a commit to youlingdada/my-easyexcel that referenced this issue Dec 16, 2023
…not increased due to blank data appearing during filling.
youlingdada added a commit to youlingdada/my-easyexcel that referenced this issue Dec 16, 2023
…not increased due to blank data appearing during filling.
youlingdada added a commit to youlingdada/my-easyexcel that referenced this issue Dec 17, 2023
…not increased due to blank data appearing during filling
@youlingdada youlingdada added the development completed Development completed, waiting for release label Dec 18, 2023
@QYZX
Copy link

QYZX commented May 9, 2024

为什么最新的release中不包含这个问题的修复?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working developing This feature will be added in future releases development completed Development completed, waiting for release
Projects
None yet
Development

No branches or pull requests

4 participants