[alibaba/easyexcel]导出文件内列的顺序与类字段定义顺序不一致

2024-05-17 256 views
9

触发场景描述 在使用了includeColumnFiledNames后 Oracle JDK 1.6.0_45下运行下面的代码导出的文件字段与类字段定义顺序不一致 Oracle JDK1.8.0_51下运行下面的代码导出的文件字段与类字段定义顺序一致 即使添加order属性也会触发该问题

触发Bug的代码

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;

public class Main {
    public static void main(final String[] args) throws IOException {
        final ExportItem item = new ExportItem();
        item.setCol17(17);
        item.setCol18(18);
        final List<ExportItem> exportItems = Collections.singletonList(item);

        final ExcelWriterBuilder excelWriterBuilder = EasyExcel.write(new FileOutputStream("./file.xlsx"), ExportItem.class);
        excelWriterBuilder.needHead(true);

        final ExcelWriterSheetBuilder excelWriterSheetBuilder = excelWriterBuilder.sheet();
        excelWriterSheetBuilder.includeColumnFiledNames(Arrays.asList("col17", "col18"));
        excelWriterSheetBuilder.doWrite(exportItems);
    }

    public static class ExportItem {
        private String col1;
        private String col2;
        private String col3;
        private String col4;
        private String col5;
        private String col6;
        private String col7;
        private String col8;
        private String col9;
        private Date col10;
        private int col11;
        private String col12;
        private Date col13;
        private Date col14;
        private Integer col15;
        private Float col16;
        private Integer col17;
        private Integer col18;

        public String getCol1() {
            return col1;
        }
        public void setCol1(final String col1) {
            this.col1 = col1;
        }
        public String getCol2() {
            return col2;
        }
        public void setCol2(final String col2) {
            this.col2 = col2;
        }
        public String getCol3() {
            return col3;
        }
        public void setCol3(final String col3) {
            this.col3 = col3;
        }
        public String getCol4() {
            return col4;
        }
        public void setCol4(final String col4) {
            this.col4 = col4;
        }
        public String getCol5() {
            return col5;
        }
        public void setCol5(final String col5) {
            this.col5 = col5;
        }
        public String getCol6() {
            return col6;
        }
        public void setCol6(final String col6) {
            this.col6 = col6;
        }
        public String getCol7() {
            return col7;
        }
        public void setCol7(final String col7) {
            this.col7 = col7;
        }
        public String getCol8() {
            return col8;
        }
        public void setCol8(final String col8) {
            this.col8 = col8;
        }
        public String getCol9() {
            return col9;
        }
        public void setCol9(final String col9) {
            this.col9 = col9;
        }
        public Date getCol10() {
            return col10;
        }
        public void setCol10(final Date col10) {
            this.col10 = col10;
        }
        public int getCol11() {
            return col11;
        }
        public void setCol11(int col11) {
            this.col11 = col11;
        }
        public String getCol12() {
            return col12;
        }
        public void setCol12(final String col12) {
            this.col12 = col12;
        }
        public Date getCol13() {
            return col13;
        }
        public void setCol13(final Date col13) {
            this.col13 = col13;
        }
        public Date getEnterYuChaiDay() {
            return col14;
        }
        public void setCol14(final Date col14) {
            this.col14 = col14;
        }
        public Integer getCol15() {
            return col15;
        }
        public void setCol15(final Integer col15) {
            this.col15 = col15;
        }
        public Float getCol16() {
            return col16;
        }
        public void setCol16(final Float col16) {
            this.col16 = col16;
        }
        public Integer getCol17() {
            return col17;
        }
        public void setCol17(final Integer col17) {
            this.col17 = col17;
        }
        public Integer getCol18() {
            return col18;
        }
        public void setCol18(final Integer col18) {
            this.col18 = col18;
        }
    }
}

提示的异常或者没有达到的效果 JDK1.8下导出顺序是正常的 Snipaste_2020-10-11_16-50-08 JDK1.6下导出顺序不正确 Snipaste_2020-10-11_16-59-25

**问题定位 com.alibaba.excel.util.ClassUtils#declaredFields(Class, Map<Integer, Field>, Map<Integer, Field>, Map<String, Field>, Boolean, Boolean, Holder) 第56行

for (Map.Entry<Integer, Field> entry : fieldCache.getSortedAllFiledMap().entrySet()) {

entrySet()返回的iterator顺序在不同版本不一致,不要依赖于entrySet返回的顺序

回答

8

请问 什么时候解决呢?

4

这个问题影响很大的,动态导出是一种很常见的功能

9

不用特殊注解,java是拿不到类字段顺序的。java.lang.Class#getDeclaredFields文档有说明:“The elements in the returned array are not sorted and are not in any particular order.” @chen3

5

不用特殊注解,java是拿不到类字段顺序的。java.lang.Class#getDeclaredFields文档有说明:“The elements in the returned array are not sorted and are not in any particular order.” @chen3

感谢解答,不过即使使用Order注解指定了顺序导出也有可能顺序错误的