Browse Source

添加注解`ExcelUnInheritable`,声明不可指定类的`Field`不进行继承,可避免继承结构中字段重复和`Converter`覆盖问题

pull/3724/head
sunshuaiju 11 months ago
parent
commit
aed2b13159
  1. 16
      easyexcel-core/src/main/java/com/alibaba/excel/annotation/ExcelUnInheritable.java
  2. 77
      easyexcel-core/src/main/java/com/alibaba/excel/util/ClassUtils.java

16
easyexcel-core/src/main/java/com/alibaba/excel/annotation/ExcelUnInheritable.java

@ -0,0 +1,16 @@
package com.alibaba.excel.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Declare that this type of field is not inheritable
*
* @author ShuaiJu Sun
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcelUnInheritable {
}

77
easyexcel-core/src/main/java/com/alibaba/excel/util/ClassUtils.java

@ -13,11 +13,13 @@ import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import com.alibaba.excel.annotation.ExcelIgnore; import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.ExcelUnInheritable;
import com.alibaba.excel.annotation.format.DateTimeFormat; import com.alibaba.excel.annotation.format.DateTimeFormat;
import com.alibaba.excel.annotation.format.NumberFormat; import com.alibaba.excel.annotation.format.NumberFormat;
import com.alibaba.excel.annotation.write.style.ContentFontStyle; import com.alibaba.excel.annotation.write.style.ContentFontStyle;
@ -74,25 +76,25 @@ public class ClassUtils {
* The cache configuration information for each of the class * The cache configuration information for each of the class
*/ */
public static final ConcurrentHashMap<Class<?>, Map<String, ExcelContentProperty>> CLASS_CONTENT_CACHE public static final ConcurrentHashMap<Class<?>, Map<String, ExcelContentProperty>> CLASS_CONTENT_CACHE
= new ConcurrentHashMap<>(); = new ConcurrentHashMap<>();
/** /**
* The cache configuration information for each of the class * The cache configuration information for each of the class
*/ */
private static final ThreadLocal<Map<Class<?>, Map<String, ExcelContentProperty>>> CLASS_CONTENT_THREAD_LOCAL private static final ThreadLocal<Map<Class<?>, Map<String, ExcelContentProperty>>> CLASS_CONTENT_THREAD_LOCAL
= new ThreadLocal<>(); = new ThreadLocal<>();
/** /**
* The cache configuration information for each of the class * The cache configuration information for each of the class
*/ */
public static final ConcurrentHashMap<ContentPropertyKey, ExcelContentProperty> CONTENT_CACHE public static final ConcurrentHashMap<ContentPropertyKey, ExcelContentProperty> CONTENT_CACHE
= new ConcurrentHashMap<>(); = new ConcurrentHashMap<>();
/** /**
* The cache configuration information for each of the class * The cache configuration information for each of the class
*/ */
private static final ThreadLocal<Map<ContentPropertyKey, ExcelContentProperty>> CONTENT_THREAD_LOCAL private static final ThreadLocal<Map<ContentPropertyKey, ExcelContentProperty>> CONTENT_THREAD_LOCAL
= new ThreadLocal<>(); = new ThreadLocal<>();
/** /**
* Calculate the configuration information for the class * Calculate the configuration information for the class
@ -103,8 +105,8 @@ public class ClassUtils {
* @return * @return
*/ */
public static ExcelContentProperty declaredExcelContentProperty(Map<?, ?> dataMap, Class<?> headClazz, public static ExcelContentProperty declaredExcelContentProperty(Map<?, ?> dataMap, Class<?> headClazz,
String fieldName, String fieldName,
ConfigurationHolder configurationHolder) { ConfigurationHolder configurationHolder) {
Class<?> clazz = null; Class<?> clazz = null;
if (dataMap instanceof BeanMap) { if (dataMap instanceof BeanMap) {
Object bean = ((BeanMap)dataMap).getBean(); Object bean = ((BeanMap)dataMap).getBean();
@ -116,7 +118,7 @@ public class ClassUtils {
} }
private static ExcelContentProperty getExcelContentProperty(Class<?> clazz, Class<?> headClass, String fieldName, private static ExcelContentProperty getExcelContentProperty(Class<?> clazz, Class<?> headClass, String fieldName,
ConfigurationHolder configurationHolder) { ConfigurationHolder configurationHolder) {
switch (configurationHolder.globalConfiguration().getFiledCacheLocation()) { switch (configurationHolder.globalConfiguration().getFiledCacheLocation()) {
case THREAD_LOCAL: case THREAD_LOCAL:
Map<ContentPropertyKey, ExcelContentProperty> contentCacheMap = CONTENT_THREAD_LOCAL.get(); Map<ContentPropertyKey, ExcelContentProperty> contentCacheMap = CONTENT_THREAD_LOCAL.get();
@ -139,16 +141,16 @@ public class ClassUtils {
} }
private static ExcelContentProperty doGetExcelContentProperty(Class<?> clazz, Class<?> headClass, private static ExcelContentProperty doGetExcelContentProperty(Class<?> clazz, Class<?> headClass,
String fieldName, String fieldName,
ConfigurationHolder configurationHolder) { ConfigurationHolder configurationHolder) {
ExcelContentProperty excelContentProperty = Optional.ofNullable( ExcelContentProperty excelContentProperty = Optional.ofNullable(
declaredFieldContentMap(clazz, configurationHolder)) declaredFieldContentMap(clazz, configurationHolder))
.map(map -> map.get(fieldName)) .map(map -> map.get(fieldName))
.orElse(null); .orElse(null);
ExcelContentProperty headExcelContentProperty = Optional.ofNullable( ExcelContentProperty headExcelContentProperty = Optional.ofNullable(
declaredFieldContentMap(headClass, configurationHolder)) declaredFieldContentMap(headClass, configurationHolder))
.map(map -> map.get(fieldName)) .map(map -> map.get(fieldName))
.orElse(null); .orElse(null);
ExcelContentProperty combineExcelContentProperty = new ExcelContentProperty(); ExcelContentProperty combineExcelContentProperty = new ExcelContentProperty();
combineExcelContentProperty(combineExcelContentProperty, headExcelContentProperty); combineExcelContentProperty(combineExcelContentProperty, headExcelContentProperty);
@ -159,7 +161,7 @@ public class ClassUtils {
} }
public static void combineExcelContentProperty(ExcelContentProperty combineExcelContentProperty, public static void combineExcelContentProperty(ExcelContentProperty combineExcelContentProperty,
ExcelContentProperty excelContentProperty) { ExcelContentProperty excelContentProperty) {
if (excelContentProperty == null) { if (excelContentProperty == null) {
return; return;
} }
@ -188,14 +190,14 @@ public class ClassUtils {
} }
private static Map<String, ExcelContentProperty> declaredFieldContentMap(Class<?> clazz, private static Map<String, ExcelContentProperty> declaredFieldContentMap(Class<?> clazz,
ConfigurationHolder configurationHolder) { ConfigurationHolder configurationHolder) {
if (clazz == null) { if (clazz == null) {
return null; return null;
} }
switch (configurationHolder.globalConfiguration().getFiledCacheLocation()) { switch (configurationHolder.globalConfiguration().getFiledCacheLocation()) {
case THREAD_LOCAL: case THREAD_LOCAL:
Map<Class<?>, Map<String, ExcelContentProperty>> classContentCacheMap Map<Class<?>, Map<String, ExcelContentProperty>> classContentCacheMap
= CLASS_CONTENT_THREAD_LOCAL.get(); = CLASS_CONTENT_THREAD_LOCAL.get();
if (classContentCacheMap == null) { if (classContentCacheMap == null) {
classContentCacheMap = MapUtils.newHashMap(); classContentCacheMap = MapUtils.newHashMap();
CLASS_CONTENT_THREAD_LOCAL.set(classContentCacheMap); CLASS_CONTENT_THREAD_LOCAL.set(classContentCacheMap);
@ -230,7 +232,7 @@ public class ClassUtils {
ContentStyle parentContentStyle = clazz.getAnnotation(ContentStyle.class); ContentStyle parentContentStyle = clazz.getAnnotation(ContentStyle.class);
ContentFontStyle parentContentFontStyle = clazz.getAnnotation(ContentFontStyle.class); ContentFontStyle parentContentFontStyle = clazz.getAnnotation(ContentFontStyle.class);
Map<String, ExcelContentProperty> fieldContentMap = MapUtils.newHashMapWithExpectedSize( Map<String, ExcelContentProperty> fieldContentMap = MapUtils.newHashMapWithExpectedSize(
tempFieldList.size()); tempFieldList.size());
for (Field field : tempFieldList) { for (Field field : tempFieldList) {
ExcelContentProperty excelContentProperty = new ExcelContentProperty(); ExcelContentProperty excelContentProperty = new ExcelContentProperty();
excelContentProperty.setField(field); excelContentProperty.setField(field);
@ -244,7 +246,7 @@ public class ClassUtils {
excelContentProperty.setConverter(converter); excelContentProperty.setConverter(converter);
} catch (Exception e) { } catch (Exception e) {
throw new ExcelCommonException( throw new ExcelCommonException(
"Can not instance custom converter:" + convertClazz.getName()); "Can not instance custom converter:" + convertClazz.getName());
} }
} }
} }
@ -262,9 +264,9 @@ public class ClassUtils {
excelContentProperty.setContentFontProperty(FontProperty.build(contentFontStyle)); excelContentProperty.setContentFontProperty(FontProperty.build(contentFontStyle));
excelContentProperty.setDateTimeFormatProperty( excelContentProperty.setDateTimeFormatProperty(
DateTimeFormatProperty.build(field.getAnnotation(DateTimeFormat.class))); DateTimeFormatProperty.build(field.getAnnotation(DateTimeFormat.class)));
excelContentProperty.setNumberFormatProperty( excelContentProperty.setNumberFormatProperty(
NumberFormatProperty.build(field.getAnnotation(NumberFormat.class))); NumberFormatProperty.build(field.getAnnotation(NumberFormat.class)));
fieldContentMap.put(field.getName(), excelContentProperty); fieldContentMap.put(field.getName(), excelContentProperty);
} }
@ -306,8 +308,14 @@ public class ClassUtils {
// level. // level.
while (tempClass != null) { while (tempClass != null) {
Collections.addAll(tempFieldList, tempClass.getDeclaredFields()); Collections.addAll(tempFieldList, tempClass.getDeclaredFields());
// Get the parent class and give it to yourself // Get the parent class and give it to yourself
tempClass = tempClass.getSuperclass(); tempClass = tempClass.getSuperclass();
ExcelUnInheritable excelUnInheritable = Optional.ofNullable(tempClass)
.map(item -> item.getAnnotation(ExcelUnInheritable.class)).orElse(null);
if (Objects.nonNull(excelUnInheritable)){
break;
}
} }
// Screening of field // Screening of field
Map<Integer, List<FieldWrapper>> orderFieldMap = new TreeMap<>(); Map<Integer, List<FieldWrapper>> orderFieldMap = new TreeMap<>();
@ -328,9 +336,9 @@ public class ClassUtils {
WriteHolder writeHolder = (WriteHolder)configurationHolder; WriteHolder writeHolder = (WriteHolder)configurationHolder;
boolean needIgnore = !CollectionUtils.isEmpty(writeHolder.excludeColumnFieldNames()) boolean needIgnore = !CollectionUtils.isEmpty(writeHolder.excludeColumnFieldNames())
|| !CollectionUtils.isEmpty(writeHolder.excludeColumnIndexes()) || !CollectionUtils.isEmpty(writeHolder.excludeColumnIndexes())
|| !CollectionUtils.isEmpty(writeHolder.includeColumnFieldNames()) || !CollectionUtils.isEmpty(writeHolder.includeColumnFieldNames())
|| !CollectionUtils.isEmpty(writeHolder.includeColumnIndexes()); || !CollectionUtils.isEmpty(writeHolder.includeColumnIndexes());
if (!needIgnore) { if (!needIgnore) {
return fieldCache; return fieldCache;
@ -428,10 +436,10 @@ public class ClassUtils {
} }
private static Map<Integer, FieldWrapper> buildSortedAllFieldMap(Map<Integer, List<FieldWrapper>> orderFieldMap, private static Map<Integer, FieldWrapper> buildSortedAllFieldMap(Map<Integer, List<FieldWrapper>> orderFieldMap,
Map<Integer, FieldWrapper> indexFieldMap) { Map<Integer, FieldWrapper> indexFieldMap) {
Map<Integer, FieldWrapper> sortedAllFieldMap = new HashMap<>( Map<Integer, FieldWrapper> sortedAllFieldMap = new HashMap<>(
(orderFieldMap.size() + indexFieldMap.size()) * 4 / 3 + 1); (orderFieldMap.size() + indexFieldMap.size()) * 4 / 3 + 1);
Map<Integer, FieldWrapper> tempIndexFieldMap = new HashMap<>(indexFieldMap); Map<Integer, FieldWrapper> tempIndexFieldMap = new HashMap<>(indexFieldMap);
int index = 0; int index = 0;
@ -451,8 +459,8 @@ public class ClassUtils {
} }
private static void declaredOneField(Field field, Map<Integer, List<FieldWrapper>> orderFieldMap, private static void declaredOneField(Field field, Map<Integer, List<FieldWrapper>> orderFieldMap,
Map<Integer, FieldWrapper> indexFieldMap, Set<String> ignoreSet, Map<Integer, FieldWrapper> indexFieldMap, Set<String> ignoreSet,
ExcelIgnoreUnannotated excelIgnoreUnannotated) { ExcelIgnoreUnannotated excelIgnoreUnannotated) {
String fieldName = FieldUtils.resolveCglibFieldName(field); String fieldName = FieldUtils.resolveCglibFieldName(field);
FieldWrapper fieldWrapper = new FieldWrapper(); FieldWrapper fieldWrapper = new FieldWrapper();
fieldWrapper.setField(field); fieldWrapper.setField(field);
@ -471,8 +479,8 @@ public class ClassUtils {
return; return;
} }
boolean isStaticFinalOrTransient = boolean isStaticFinalOrTransient =
(Modifier.isStatic(field.getModifiers()) && Modifier.isFinal(field.getModifiers())) (Modifier.isStatic(field.getModifiers()) && Modifier.isFinal(field.getModifiers()))
|| Modifier.isTransient(field.getModifiers()); || Modifier.isTransient(field.getModifiers());
if (excelProperty == null && isStaticFinalOrTransient) { if (excelProperty == null && isStaticFinalOrTransient) {
ignoreSet.add(fieldName); ignoreSet.add(fieldName);
return; return;
@ -485,8 +493,8 @@ public class ClassUtils {
if (excelProperty != null && excelProperty.index() >= 0) { if (excelProperty != null && excelProperty.index() >= 0) {
if (indexFieldMap.containsKey(excelProperty.index())) { if (indexFieldMap.containsKey(excelProperty.index())) {
throw new ExcelCommonException( throw new ExcelCommonException(
"The index of '" + indexFieldMap.get(excelProperty.index()).getFieldName() "The index of '" + indexFieldMap.get(excelProperty.index()).getFieldName()
+ "' and '" + field.getName() + "' must be inconsistent"); + "' and '" + field.getName() + "' must be inconsistent");
} }
indexFieldMap.put(excelProperty.index(), fieldWrapper); indexFieldMap.put(excelProperty.index(), fieldWrapper);
return; return;
@ -579,5 +587,4 @@ public class ClassUtils {
CLASS_CONTENT_THREAD_LOCAL.remove(); CLASS_CONTENT_THREAD_LOCAL.remove();
CONTENT_THREAD_LOCAL.remove(); CONTENT_THREAD_LOCAL.remove();
} }
} }
Loading…
Cancel
Save