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方法进行填充list数据时,存在问题会使不同行的数据错乱 #3783

Open
dani3lWong opened this issue Apr 28, 2024 · 1 comment · May be fixed by #3792
Assignees
Labels
bug Something isn't working

Comments

@dani3lWong
Copy link

触发场景描述

1、使用List作为数据源,加上模板(e.g.{.name})进行数据写入时,如果list中其中一个map的数据有不存在的key,那一列的数据会上移。
2、后来经过试验发现,使用继承的VO,当传入的是父类时,对于缺少的属性也会有类似的情况。
简单模板:
image

触发Bug的代码

1、map的Test用例

   import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.resource.ClassPathResource;
import cn.hutool.core.map.MapUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.enums.WriteDirectionEnum;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class TestMap {

    private static final Logger log = LoggerFactory.getLogger(TestMap.class);

    public static void main(String[] args) {

        File targetDir;
        if (args.length > 0 && FileUtil.exist(args[0])) {
            targetDir = FileUtil.file(args[0]);
        } else {
            targetDir = FileUtil.file("");
        }
        File targetFile = new File(targetDir, "targetMap.xlsx");
        if(FileUtil.exist(targetFile)) {
            FileUtil.del(targetFile);
        }
        FileUtil.touch(targetFile);

        List<Map<String, String>> list = new ArrayList<>();

        list.add(MapUtil.builder("name", "张三").put("score", "99").build());
        list.add(MapUtil.builder("name", "张四")/*.put("score", "98")*/.build());
        list.add(MapUtil.builder("name", "张五").put("score", "97").build());

        ExcelWriter writer = EasyExcel.write(targetFile)
                .excelType(ExcelTypeEnum.XLSX)
                .autoCloseStream(true)
                .withTemplate(new ClassPathResource("classpath://test.xlsx").getStream())
                .build();

        WriteSheet writeSheet = EasyExcel.writerSheet(0, "Sheet1")
                .build();

        FillConfig fillConfig = FillConfig.builder()
                .direction(WriteDirectionEnum.VERTICAL)
                .autoStyle(true)
                .build();

        writer.fill(list, fillConfig, writeSheet);
        writer.finish();

        log.info("文件输出至:{}", targetFile.getAbsolutePath());

    }

}

2、VO的测试用例:

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.resource.ClassPathResource;
import cn.hutool.core.map.MapUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.enums.WriteDirectionEnum;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class TestVO {

    private static final Logger log = LoggerFactory.getLogger(TestVO.class);

    public static void main(String[] args) {

        File targetDir;
        if (args.length > 0 && FileUtil.exist(args[0])) {
            targetDir = FileUtil.file(args[0]);
        } else {
            targetDir = FileUtil.file("");
        }
        File targetFile = new File(targetDir, "targetVO.xlsx");
        if(FileUtil.exist(targetFile)) {
            FileUtil.del(targetFile);
        }
        FileUtil.touch(targetFile);

        List<SupVO> list = new ArrayList<>();

        list.add(new SonVO("张三", "99"));
        list.add(new SupVO("张四"));
        list.add(new SonVO("张五", "97"));

        ExcelWriter writer = EasyExcel.write(targetFile)
                .excelType(ExcelTypeEnum.XLSX)
                .autoCloseStream(true)
                .withTemplate(new ClassPathResource("classpath://test.xlsx").getStream())
                .build();

        WriteSheet writeSheet = EasyExcel.writerSheet(0, "Sheet1")
                .build();

        FillConfig fillConfig = FillConfig.builder()
                .direction(WriteDirectionEnum.VERTICAL)
                .autoStyle(true)
                .build();

        writer.fill(list, fillConfig, writeSheet);
        writer.finish();

        log.info("文件输出至:{}", targetFile.getAbsolutePath());

    }

}

提示的异常或者没有达到的效果

以上的测试用例都会得到相似的结果:
image
附测试工作区:
easyexcel-bug.zip

@dani3lWong dani3lWong added the bug Something isn't working label Apr 28, 2024
@psxjoy
Copy link

psxjoy commented May 16, 2024

@zhuangjiaju 我看了一下源码,ExcelWriteFillExecutor中的doFill函数中有这样一个逻辑:

String variable = analysisCell.getVariableList().get(0);
if (!dataKeySet.contains(variable)) {
    continue;
}

这会导致空数据不进行写操作,直接进入下一行的数据操作。
如果可以的话,我希望认领这个问题并修复。
等待你的回复。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants