diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/util/ClassUtils.java b/easyexcel-core/src/main/java/com/alibaba/excel/util/ClassUtils.java index 6bed3052..11644dfa 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/util/ClassUtils.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/util/ClassUtils.java @@ -1,18 +1,5 @@ package com.alibaba.excel.util; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.TreeMap; -import java.util.concurrent.ConcurrentHashMap; - import com.alibaba.excel.annotation.ExcelIgnore; import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import com.alibaba.excel.annotation.ExcelProperty; @@ -29,13 +16,19 @@ import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.metadata.property.FontProperty; import com.alibaba.excel.metadata.property.NumberFormatProperty; import com.alibaba.excel.metadata.property.StyleProperty; +import com.alibaba.excel.write.metadata.holder.AbstractWriteHolder; import com.alibaba.excel.write.metadata.holder.WriteHolder; - import lombok.AllArgsConstructor; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; import org.springframework.cglib.beans.BeanMap; +import org.springframework.util.CollectionUtils; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; /** * Licensed to the Apache Software Foundation (ASF) under one or more @@ -250,6 +243,36 @@ public class ClassUtils { } } } + forceIndexIfNecessary(holder, sortedAllFieldMap); + } + + /** + * it only works when {@link AbstractWriteHolder#getIncludeColumnFieldNames()} has value + * and {@link AbstractWriteHolder#getForceIndex()} is true + **/ + private static void forceIndexIfNecessary(Holder holder, Map sortedAllFieldMap) { + if (!(holder instanceof AbstractWriteHolder)) { + return; + } + AbstractWriteHolder writeHolder = (AbstractWriteHolder) holder; + Collection allCol = writeHolder.getIncludeColumnFieldNames(); + if (!CollectionUtils.isEmpty(allCol) && writeHolder.getForceIndex() != null && writeHolder.getForceIndex()) { + Map colIndexMap = MapUtils.newHashMap(); + Iterator iterator = allCol.iterator(); + int colIndex = 0; + while (iterator.hasNext()) { + String col = iterator.next(); + colIndexMap.put(col, colIndex); + colIndex++; + } + Map temp = MapUtils.newHashMap(); + sortedAllFieldMap.forEach((index, field) -> { + Integer fieldIndex = colIndexMap.get(field.getName()); + temp.put(fieldIndex, field); + }); + sortedAllFieldMap.clear(); + sortedAllFieldMap.putAll(temp); + } } public static void declaredFields(Class clazz, Map sortedAllFieldMap, Boolean needIgnore, @@ -287,10 +310,10 @@ public class ClassUtils { private static Map buildSortedAllFieldMap(Map> orderFieldMap, Map indexFieldMap) { - Map sortedAllFieldMap = new HashMap( + Map sortedAllFieldMap = new HashMap<>( (orderFieldMap.size() + indexFieldMap.size()) * 4 / 3 + 1); - Map tempIndexFieldMap = new HashMap(indexFieldMap); + Map tempIndexFieldMap = new HashMap<>(indexFieldMap); int index = 0; for (List fieldList : orderFieldMap.values()) { for (Field field : fieldList) { diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/write/builder/AbstractExcelWriterParameterBuilder.java b/easyexcel-core/src/main/java/com/alibaba/excel/write/builder/AbstractExcelWriterParameterBuilder.java index f8844a52..bcbbf41c 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/write/builder/AbstractExcelWriterParameterBuilder.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/write/builder/AbstractExcelWriterParameterBuilder.java @@ -1,12 +1,12 @@ package com.alibaba.excel.write.builder; -import java.util.ArrayList; -import java.util.Collection; - import com.alibaba.excel.metadata.AbstractParameterBuilder; import com.alibaba.excel.write.handler.WriteHandler; import com.alibaba.excel.write.metadata.WriteBasicParameter; +import java.util.ArrayList; +import java.util.Collection; + /** * Build ExcelBuilder * @@ -120,4 +120,13 @@ public abstract class AbstractExcelWriterParameterBuilder includeColumnFieldNames; + /** + * head sorted use includeColumnFieldNames sort + */ + private Boolean forceIndex; } diff --git a/easyexcel-core/src/main/java/com/alibaba/excel/write/metadata/holder/AbstractWriteHolder.java b/easyexcel-core/src/main/java/com/alibaba/excel/write/metadata/holder/AbstractWriteHolder.java index b6907e42..b08fbefe 100644 --- a/easyexcel-core/src/main/java/com/alibaba/excel/write/metadata/holder/AbstractWriteHolder.java +++ b/easyexcel-core/src/main/java/com/alibaba/excel/write/metadata/holder/AbstractWriteHolder.java @@ -94,7 +94,10 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ * Only output the custom columns. */ private Collection includeColumnFieldNames; - + /** + * head sorted use {@link #includeColumnFieldNames} sort + */ + private Boolean forceIndex; /** * Write handler */ @@ -184,6 +187,11 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ } else { this.excludeColumnFieldNames = writeBasicParameter.getExcludeColumnFieldNames(); } + if(writeBasicParameter.getForceIndex() == null && parentAbstractWriteHolder != null ){ + this.forceIndex = parentAbstractWriteHolder.getForceIndex(); + }else{ + this.forceIndex = writeBasicParameter.getForceIndex(); + } if (writeBasicParameter.getExcludeColumnIndexes() == null && parentAbstractWriteHolder != null) { this.excludeColumnIndexes = parentAbstractWriteHolder.getExcludeColumnIndexes(); } else { diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/excludeorinclude/ExcludeOrIncludeDataTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/excludeorinclude/ExcludeOrIncludeDataTest.java index 9bf69821..0e638f6f 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/excludeorinclude/ExcludeOrIncludeDataTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/core/excludeorinclude/ExcludeOrIncludeDataTest.java @@ -1,21 +1,20 @@ package com.alibaba.easyexcel.test.core.excludeorinclude; -import java.io.File; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - import com.alibaba.easyexcel.test.util.TestFileUtil; import com.alibaba.excel.EasyExcel; - import org.junit.Assert; import org.junit.BeforeClass; import org.junit.FixMethodOrder; import org.junit.Test; import org.junit.runners.MethodSorters; +import java.io.File; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + /** * @author Jiaju Zhuang */ @@ -34,6 +33,9 @@ public class ExcludeOrIncludeDataTest { private static File includeFieldName07; private static File includeFieldName03; private static File includeFieldNameCsv; + private static File includeFieldNameForceIndex07; + private static File includeFieldNameForceIndex03; + private static File includeFieldNameForceIndexCsv; @BeforeClass public static void init() { @@ -49,6 +51,9 @@ public class ExcludeOrIncludeDataTest { includeFieldName07 = TestFileUtil.createNewFile("includeFieldName.xlsx"); includeFieldName03 = TestFileUtil.createNewFile("includeFieldName.xls"); includeFieldNameCsv = TestFileUtil.createNewFile("includeFieldName.csv"); + includeFieldNameForceIndex07 = TestFileUtil.createNewFile("includeFieldNameForceIndex.xlsx"); + includeFieldNameForceIndex03 = TestFileUtil.createNewFile("includeFieldNameForceIndex.xls"); + includeFieldNameForceIndexCsv = TestFileUtil.createNewFile("includeFieldNameForceIndex.csv"); } @Test @@ -112,6 +117,21 @@ public class ExcludeOrIncludeDataTest { includeFieldName(includeFieldNameCsv); } + @Test + public void t41IncludeFieldName07() { + includeFieldNameForce(includeFieldNameForceIndex07); + } + + @Test + public void t42IncludeFieldName03() { + includeFieldNameForce(includeFieldNameForceIndex03); + } + + @Test + public void t43IncludeFieldNameCsv() { + includeFieldNameForce(includeFieldNameForceIndexCsv); + } + private void excludeIndex(File file) { Set excludeColumnIndexes = new HashSet(); excludeColumnIndexes.add(0); @@ -171,6 +191,21 @@ public class ExcludeOrIncludeDataTest { Assert.assertEquals("column3", record.get(1)); } + + private void includeFieldNameForce(File file) { + List includeColumnFieldNames = new ArrayList<>(); + includeColumnFieldNames.add("column3"); + includeColumnFieldNames.add("column2"); + EasyExcel.write(file, ExcludeOrIncludeData.class).includeColumnFieldNames(includeColumnFieldNames) + .forceIndex(true).sheet().doWrite(data()); + List> dataMap = EasyExcel.read(file).sheet().doReadSync(); + Assert.assertEquals(1, dataMap.size()); + Map record = dataMap.get(0); + Assert.assertEquals(2, record.size()); + Assert.assertEquals("column3", record.get(0)); + Assert.assertEquals("column2", record.get(1)); + } + private List data() { List list = new ArrayList(); ExcludeOrIncludeData excludeOrIncludeData = new ExcludeOrIncludeData();