[alibaba/easyexcel]当类的属性没有按照ExcelProperty的属性index顺序排序的时候,写数据出现错乱

2024-05-23 813 views
7

触发场景描述 当类的属性没有按照ExcelProperty注解的属性index排序的时候,写数据出现错乱顺序 触发Bug的代码

   public class EasyExcelFound {

    /**
     * 写数据
     */
    @Test
    public void indexNotSort() {
        Path path = Paths.get("/home/liuxu/Public/not-sort.xlsx");
        ExcelWriter excelWriter = EasyExcel.write(path.toFile())
                .build();
        WriteSheet writeSheet = EasyExcel.writerSheet("出现不排序的情况")
                .head(head())
                .build();

        excelWriter.write(data(),writeSheet);
        excelWriter.finish();
    }

    private List<List<String>> head() {
        List<List<String>> head = new ArrayList<>();
        head.add(Collections.singletonList("名字"));
        head.add(Collections.singletonList("ID编号"));
        return head;
    }

    public List<CluesDto> data() {
        return IntStream.rangeClosed(0, 3)
                .boxed()
                .map(integer -> {
                    CluesDto cluesDto = new CluesDto();
                    cluesDto.setId(integer);
                    cluesDto.setName("线索名字-" + integer);
                    cluesDto.setCreateDate(new Date());
                    return cluesDto;
                })
                .collect(Collectors.toList());
    }
}

@ExcelIgnoreUnannotated
class CluesDto {
    @ExcelProperty(index = 1)
    private Integer id;

    @ExcelProperty(index = 0)
    private String name;

    private Date createDate;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Date getCreateDate() {
        return createDate;
    }

    public void setCreateDate(Date createDate) {
        this.createDate = createDate;
    }
}

提示的异常或者没有达到的效果 写入结果为: not-sort

可以看到excel中的:名字和ID编号两列写反了。

目前的解决方案:在CluesDto类中,把id,name属性按照index的增长顺序写就行,也就是调整为:

@ExcelIgnoreUnannotated
class CluesDto {
    @ExcelProperty(index = 0)
    private String name;

    @ExcelProperty(index = 1)
    private Integer id;

    private Date createDate;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Date getCreateDate() {
        return createDate;
    }

    public void setCreateDate(Date createDate) {
        this.createDate = createDate;
    }
}

跟踪了下源码,发现: com.alibaba.excel.util.ClassUtils类中获取declaredFields的方法,获取allFieldList没有按照ExcelProperty的index进行排序。导致后面写入数据的时候获取fieldList只是按照反射拿取的字段顺序为准,并没有按照index排序。

回答

6

忘记了测试版本:2.1.3和2.1.4均会出现此问题(2.1.4,我是从maven中央仓库拉取的,不知道为啥github上没有2.1.4的发行版本)

7

已经合并

3

有没有能直接定义列字段顺序的方式,出了注解比如"id"绑定顺序index=0?

7

有没有能直接定义列字段顺序的方式,出了注解比如"id"绑定顺序index=0?

这个直接定义列字段顺序是什么意思?使用ExcelProperty就可以直接定义列的顺序了

9

我是说除了ExcelProperty这种注解方式,比如我excel要显示 "id","name","age" 这种顺序, 然后我定义excel列明"主键ID", " 姓名","年龄"; 我直接传对应的这两个String[] keysArr , String[] namesArr ,这样参数, 然后能按照我这种格式来输出Excel中~ 这样我们输出excle时候会更灵活~