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 92b828b4..d2ac7135 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 @@ -36,6 +36,7 @@ import com.alibaba.excel.metadata.property.StyleProperty; import com.alibaba.excel.write.metadata.holder.WriteHolder; import lombok.AllArgsConstructor; +import lombok.Data; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; @@ -49,7 +50,7 @@ import org.springframework.cglib.beans.BeanMap; * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 - * + *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -63,11 +64,11 @@ public class ClassUtils { /** * memory cache */ - public static final ConcurrentHashMap, FieldCache> FIELD_CACHE = new ConcurrentHashMap<>(); + public static final Map FIELD_CACHE = new ConcurrentHashMap<>(); /** - * thread local cahe + * thread local cache */ - private static final ThreadLocal, FieldCache>> FIELD_THREAD_LOCAL = new ThreadLocal<>(); + private static final ThreadLocal> FIELD_THREAD_LOCAL = new ThreadLocal<>(); /** * The cache configuration information for each of the class @@ -102,7 +103,8 @@ public class ClassUtils { * @return */ public static ExcelContentProperty declaredExcelContentProperty(Map dataMap, Class headClazz, - String fieldName, ConfigurationHolder configurationHolder) { + String fieldName, + ConfigurationHolder configurationHolder) { Class clazz = null; if (dataMap instanceof BeanMap) { Object bean = ((BeanMap)dataMap).getBean(); @@ -137,7 +139,8 @@ public class ClassUtils { } private static ExcelContentProperty doGetExcelContentProperty(Class clazz, Class headClass, - String fieldName, ConfigurationHolder configurationHolder) { + String fieldName, + ConfigurationHolder configurationHolder) { ExcelContentProperty excelContentProperty = Optional.ofNullable( declaredFieldContentMap(clazz, configurationHolder)) .map(map -> map.get(fieldName)) @@ -277,16 +280,16 @@ public class ClassUtils { public static FieldCache declaredFields(Class clazz, ConfigurationHolder configurationHolder) { switch (configurationHolder.globalConfiguration().getFiledCacheLocation()) { case THREAD_LOCAL: - Map, FieldCache> fieldCacheMap = FIELD_THREAD_LOCAL.get(); + Map fieldCacheMap = FIELD_THREAD_LOCAL.get(); if (fieldCacheMap == null) { fieldCacheMap = MapUtils.newHashMap(); FIELD_THREAD_LOCAL.set(fieldCacheMap); } - return fieldCacheMap.computeIfAbsent(clazz, key -> { + return fieldCacheMap.computeIfAbsent(new FieldCacheKey(clazz, configurationHolder), key -> { return doDeclaredFields(clazz, configurationHolder); }); case MEMORY: - return FIELD_CACHE.computeIfAbsent(clazz, key -> { + return FIELD_CACHE.computeIfAbsent(new FieldCacheKey(clazz, configurationHolder), key -> { return doDeclaredFields(clazz, configurationHolder); }); case NONE: @@ -333,7 +336,7 @@ public class ClassUtils { return fieldCache; } // ignore filed - Map tempSortedFieldMapp = MapUtils.newHashMap(); + Map tempSortedFieldMap = MapUtils.newHashMap(); int index = 0; for (Map.Entry entry : sortedFieldMap.entrySet()) { Integer key = entry.getKey(); @@ -346,18 +349,18 @@ public class ClassUtils { } else { // Mandatory sorted fields if (indexFieldMap.containsKey(key)) { - tempSortedFieldMapp.put(key, field); + tempSortedFieldMap.put(key, field); } else { // Need to reorder automatically // Check whether the current key is already in use - while (tempSortedFieldMapp.containsKey(index)) { + while (tempSortedFieldMap.containsKey(index)) { index++; } - tempSortedFieldMapp.put(index++, field); + tempSortedFieldMap.put(index++, field); } } } - fieldCache.setSortedFieldMap(tempSortedFieldMapp); + fieldCache.setSortedFieldMap(tempSortedFieldMap); // resort field resortField(writeHolder, fieldCache); @@ -406,8 +409,8 @@ public class ClassUtils { // Index sorted map Map filedIndexMap = MapUtils.newHashMap(); int fieldIndex = 0; - for (Integer includeColumnIndexe : includeColumnIndexes) { - filedIndexMap.put(includeColumnIndexe, fieldIndex++); + for (Integer includeColumnIndex : includeColumnIndexes) { + filedIndexMap.put(includeColumnIndex, fieldIndex++); } // rebuild sortedFieldMap @@ -551,6 +554,24 @@ public class ClassUtils { private String fieldName; } + @Data + public static class FieldCacheKey { + private Class clazz; + private Collection excludeColumnFieldNames; + private Collection excludeColumnIndexes; + private Collection includeColumnFieldNames; + private Collection includeColumnIndexes; + + FieldCacheKey(Class clazz, ConfigurationHolder configurationHolder) { + this.clazz = clazz; + WriteHolder writeHolder = (WriteHolder)configurationHolder; + this.excludeColumnFieldNames = writeHolder.excludeColumnFieldNames(); + this.excludeColumnIndexes = writeHolder.excludeColumnIndexes(); + this.includeColumnFieldNames = writeHolder.includeColumnFieldNames(); + this.includeColumnIndexes = writeHolder.includeColumnIndexes(); + } + } + public static void removeThreadLocalCache() { FIELD_THREAD_LOCAL.remove(); CLASS_CONTENT_THREAD_LOCAL.remove(); diff --git a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java index cd120e22..d224c1d6 100644 --- a/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java +++ b/easyexcel-test/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java @@ -4,11 +4,14 @@ import java.io.File; import java.io.InputStream; import java.net.URL; import java.util.ArrayList; +import java.util.Arrays; import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Set; +import com.alibaba.easyexcel.test.core.head.ComplexHeadData; +import com.alibaba.easyexcel.test.demo.read.ConverterData; import com.alibaba.easyexcel.test.util.TestFileUtil; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.ExcelWriter; @@ -409,7 +412,7 @@ public class WriteTest { /** * 列宽、行高 *

- * 1. 创建excel对应的实体对象 参照{@link WidthAndHeightData} + * 1. 创建excel对应的实体对象 参照{@link WidthAndHeightData } *

* 2. 使用注解{@link ColumnWidth}、{@link HeadRowHeight}、{@link ContentRowHeight}指定宽度或高度 *

@@ -703,6 +706,19 @@ public class WriteTest { EasyExcel.write(fileName).head(head()).sheet("模板").doWrite(dataList()); } + @Test + public void sheetCol(){ + String fileName = TestFileUtil.getPath() + "customCol" + System.currentTimeMillis() + ".xlsx"; + try (ExcelWriter excelWriter = EasyExcel.write(fileName, DemoData.class).includeColumnFieldNames(Arrays.asList("string","date","doubleData")).build()) { + // 把sheet设置为不需要头 不然会输出sheet的头 这样看起来第一个table 就有2个头了 + WriteSheet writeSheet = EasyExcel.writerSheet("模板").includeColumnFieldNames(Arrays.asList("string","date")).build(); + excelWriter.write(data(), writeSheet); + writeSheet = EasyExcel.writerSheet(1,"模板1").needHead(false).build(); + // 第二次写如也会创建头,然后在第一次的后面写入数据 + WriteTable string = EasyExcel.writerTable().needHead(true).includeColumnFieldNames(Arrays.asList("string")).build(); + excelWriter.write(data(),writeSheet,string); + } + } private List dataLong() { List list = ListUtils.newArrayList(); for (int i = 0; i < 10; i++) {