@@ -167,5 +167,16 @@ public @interface Excel { | |||||
*/ | */ | ||||
public boolean isColumnHidden() default false; | public boolean isColumnHidden() default false; | ||||
/** | |||||
* 枚举导出使用的字段 | |||||
* @return | |||||
*/ | |||||
public String enumExportField() default ""; | |||||
/** | |||||
* 枚举导入使用的函数 | |||||
* @return | |||||
*/ | |||||
public String enumImportMethod() default ""; | |||||
} | } |
@@ -161,4 +161,6 @@ public class ExcelBaseEntity { | |||||
public void setFixedIndex(Integer fixedIndex) { | public void setFixedIndex(Integer fixedIndex) { | ||||
this.fixedIndex = fixedIndex; | this.fixedIndex = fixedIndex; | ||||
} | } | ||||
} | } |
@@ -75,6 +75,10 @@ public class ExcelExportEntity extends ExcelBaseEntity implements Comparable<Exc | |||||
* 是否隐藏列 | * 是否隐藏列 | ||||
*/ | */ | ||||
private boolean isColumnHidden; | private boolean isColumnHidden; | ||||
/** | |||||
* 枚举导出属性字段 | |||||
*/ | |||||
private String enumExportField; | |||||
public boolean isColumnHidden() { | public boolean isColumnHidden() { | ||||
return isColumnHidden; | return isColumnHidden; | ||||
@@ -209,6 +213,14 @@ public class ExcelExportEntity extends ExcelBaseEntity implements Comparable<Exc | |||||
this.numFormat = numFormat; | this.numFormat = numFormat; | ||||
} | } | ||||
public String getEnumExportField() { | |||||
return enumExportField; | |||||
} | |||||
public void setEnumExportField(String enumExportField) { | |||||
this.enumExportField = enumExportField; | |||||
} | |||||
@Override | @Override | ||||
public int compareTo(ExcelExportEntity prev) { | public int compareTo(ExcelExportEntity prev) { | ||||
return this.getOrderNum() - prev.getOrderNum(); | return this.getOrderNum() - prev.getOrderNum(); | ||||
@@ -48,6 +48,11 @@ public class ExcelImportEntity extends ExcelBaseEntity { | |||||
*/ | */ | ||||
private boolean importField; | private boolean importField; | ||||
/** | |||||
* 枚举导入静态方法 | |||||
*/ | |||||
private String enumImportMethod; | |||||
private List<ExcelImportEntity> list; | private List<ExcelImportEntity> list; | ||||
public String getClassType() { | public String getClassType() { | ||||
@@ -106,4 +111,11 @@ public class ExcelImportEntity extends ExcelBaseEntity { | |||||
this.importField = importField; | this.importField = importField; | ||||
} | } | ||||
public String getEnumImportMethod() { | |||||
return enumImportMethod; | |||||
} | |||||
public void setEnumImportMethod(String enumImportMethod) { | |||||
this.enumImportMethod = enumImportMethod; | |||||
} | |||||
} | } |
@@ -403,7 +403,7 @@ public abstract class BaseExportService extends ExportCommonService { | |||||
if (excelParams.get(i).getList() != null) { | if (excelParams.get(i).getList() != null) { | ||||
List<ExcelExportEntity> list = excelParams.get(i).getList(); | List<ExcelExportEntity> list = excelParams.get(i).getList(); | ||||
for (int j = 0; j < list.size(); j++) { | for (int j = 0; j < list.size(); j++) { | ||||
sheet.setColumnHidden(index,list.get(i).isColumnHidden()); | |||||
sheet.setColumnHidden(index,list.get(j).isColumnHidden()); | |||||
index++; | index++; | ||||
} | } | ||||
} else { | } else { | ||||
@@ -206,6 +206,9 @@ public class ExportCommonService { | |||||
if (StringUtils.isNotEmpty(entity.getSuffix()) && value != null) { | if (StringUtils.isNotEmpty(entity.getSuffix()) && value != null) { | ||||
value = value + entity.getSuffix(); | value = value + entity.getSuffix(); | ||||
} | } | ||||
if (value != null && StringUtils.isNotEmpty(entity.getEnumExportField())){ | |||||
value = PoiReflectorUtil.fromCache(value.getClass()).getValue(value,entity.getEnumExportField()); | |||||
} | |||||
return value == null ? "" : value.toString(); | return value == null ? "" : value.toString(); | ||||
} | } | ||||
@@ -249,6 +252,7 @@ public class ExportCommonService { | |||||
excelEntity.setNumFormat(excel.numFormat()); | excelEntity.setNumFormat(excel.numFormat()); | ||||
excelEntity.setColumnHidden(excel.isColumnHidden()); | excelEntity.setColumnHidden(excel.isColumnHidden()); | ||||
excelEntity.setDict(excel.dict()); | excelEntity.setDict(excel.dict()); | ||||
excelEntity.setEnumExportField(excel.enumExportField()); | |||||
if (excelGroup != null) { | if (excelGroup != null) { | ||||
excelEntity.setGroupName(PoiPublicUtil.getValueByTargetId(excelGroup.name(), targetId, null)); | excelEntity.setGroupName(PoiPublicUtil.getValueByTargetId(excelGroup.name(), targetId, null)); | ||||
} else { | } else { | ||||
@@ -28,6 +28,7 @@ import java.util.List; | |||||
import java.util.Map; | import java.util.Map; | ||||
import cn.afterturn.easypoi.handler.inter.IExcelDictHandler; | import cn.afterturn.easypoi.handler.inter.IExcelDictHandler; | ||||
import cn.afterturn.easypoi.util.PoiReflectorUtil; | |||||
import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
import org.apache.poi.ss.usermodel.Cell; | import org.apache.poi.ss.usermodel.Cell; | ||||
import org.apache.poi.ss.usermodel.CellType; | import org.apache.poi.ss.usermodel.CellType; | ||||
@@ -191,11 +192,13 @@ public class CellValueService { | |||||
String titleString, IExcelDictHandler dictHandler) throws Exception { | String titleString, IExcelDictHandler dictHandler) throws Exception { | ||||
ExcelImportEntity entity = excelParams.get(titleString); | ExcelImportEntity entity = excelParams.get(titleString); | ||||
String xclass = "class java.lang.Object"; | String xclass = "class java.lang.Object"; | ||||
Class clazz = null; | |||||
if (!(object instanceof Map)) { | if (!(object instanceof Map)) { | ||||
Method setMethod = entity.getMethods() != null && entity.getMethods().size() > 0 | Method setMethod = entity.getMethods() != null && entity.getMethods().size() > 0 | ||||
? entity.getMethods().get(entity.getMethods().size() - 1) : entity.getMethod(); | ? entity.getMethods().get(entity.getMethods().size() - 1) : entity.getMethod(); | ||||
Type[] ts = setMethod.getGenericParameterTypes(); | Type[] ts = setMethod.getGenericParameterTypes(); | ||||
xclass = ts[0].toString(); | xclass = ts[0].toString(); | ||||
clazz = (Class) ts[0]; | |||||
} | } | ||||
Object result = getCellValue(xclass, cell, entity); | Object result = getCellValue(xclass, cell, entity); | ||||
if (entity != null) { | if (entity != null) { | ||||
@@ -207,7 +210,7 @@ public class CellValueService { | |||||
} | } | ||||
} | } | ||||
result = handlerValue(dataHandler, object, result, titleString); | result = handlerValue(dataHandler, object, result, titleString); | ||||
return getValueByType(xclass, result, entity); | |||||
return getValueByType(xclass, result, entity, clazz); | |||||
} | } | ||||
/** | /** | ||||
@@ -231,7 +234,7 @@ public class CellValueService { | |||||
result = hanlderSuffix(entity.getSuffix(), result); | result = hanlderSuffix(entity.getSuffix(), result); | ||||
result = replaceValue(entity.getReplace(), result); | result = replaceValue(entity.getReplace(), result); | ||||
result = handlerValue(dataHandler, object, result, titleString); | result = handlerValue(dataHandler, object, result, titleString); | ||||
return getValueByType(xclass, result, entity); | |||||
return getValueByType(xclass, result, entity, (Class) ts[0]); | |||||
} | } | ||||
/** | /** | ||||
@@ -255,9 +258,10 @@ public class CellValueService { | |||||
* @param xclass | * @param xclass | ||||
* @param result | * @param result | ||||
* @param entity | * @param entity | ||||
* @param clazz | |||||
* @return | * @return | ||||
*/ | */ | ||||
private Object getValueByType(String xclass, Object result, ExcelImportEntity entity) { | |||||
private Object getValueByType(String xclass, Object result, ExcelImportEntity entity, Class clazz) { | |||||
try { | try { | ||||
//过滤空和空字符串,如果基本类型null会在上层抛出,这里就不处理了 | //过滤空和空字符串,如果基本类型null会在上层抛出,这里就不处理了 | ||||
if (result == null || StringUtils.isBlank(result.toString())) { | if (result == null || StringUtils.isBlank(result.toString())) { | ||||
@@ -305,6 +309,13 @@ public class CellValueService { | |||||
} | } | ||||
return String.valueOf(result); | return String.valueOf(result); | ||||
} | } | ||||
if (clazz.isEnum()) { | |||||
if (StringUtils.isNotEmpty(entity.getEnumImportMethod())) { | |||||
return PoiReflectorUtil.fromCache(clazz).execEnumStaticMethod(entity.getEnumImportMethod(),result); | |||||
} else { | |||||
return Enum.valueOf(clazz,result.toString()); | |||||
} | |||||
} | |||||
return result; | return result; | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
LOGGER.error(e.getMessage(), e); | LOGGER.error(e.getMessage(), e); | ||||
@@ -77,7 +77,21 @@ public class ImportBaseService { | |||||
excelEntity.setImportField(Boolean | excelEntity.setImportField(Boolean | ||||
.valueOf(PoiPublicUtil.getValueByTargetId(excel.isImportField(), targetId, "false"))); | .valueOf(PoiPublicUtil.getValueByTargetId(excel.isImportField(), targetId, "false"))); | ||||
excelEntity.setFixedIndex(excel.fixedIndex()); | excelEntity.setFixedIndex(excel.fixedIndex()); | ||||
getExcelField(targetId, field, excelEntity, excel, pojoClass, excelEntityAnn); | |||||
excelEntity.setName(PoiPublicUtil.getValueByTargetId(excel.name(), targetId, null)); | |||||
if (StringUtils.isNoneEmpty(excel.groupName())) { | |||||
excelEntity.setName(excel.groupName() + "_" + excelEntity.getName()); | |||||
} | |||||
if(excelEntityAnn != null && excelEntityAnn.show()){ | |||||
excelEntity.setName(excelEntityAnn.name() + "_" + excelEntity.getName()); | |||||
} | |||||
excelEntity.setMethod(PoiReflectorUtil.fromCache(pojoClass).getSetMethod(field.getName())); | |||||
if (StringUtils.isNotEmpty(excel.importFormat())) { | |||||
excelEntity.setFormat(excel.importFormat()); | |||||
} else { | |||||
excelEntity.setFormat(excel.format()); | |||||
} | |||||
excelEntity.setDict(excel.dict()); | |||||
excelEntity.setEnumImportMethod(excel.enumImportMethod()); | |||||
if (getMethods != null) { | if (getMethods != null) { | ||||
List<Method> newMethods = new ArrayList<Method>(); | List<Method> newMethods = new ArrayList<Method>(); | ||||
newMethods.addAll(getMethods); | newMethods.addAll(getMethods); | ||||
@@ -128,7 +142,7 @@ public class ImportBaseService { | |||||
field.getAnnotation(ExcelCollection.class).name(), targetId, null)); | field.getAnnotation(ExcelCollection.class).name(), targetId, null)); | ||||
additionalCollectionName(collection); | additionalCollectionName(collection); | ||||
excelCollection.add(collection); | excelCollection.add(collection); | ||||
} else if (PoiPublicUtil.isJavaClass(field)) { | |||||
} else if (PoiPublicUtil.isJavaClass(field) || field.getType().isEnum()) { | |||||
addEntityToMap(targetId, field, excelEntity, pojoClass, getMethods, excelParams, excelEntityAnn); | addEntityToMap(targetId, field, excelEntity, pojoClass, getMethods, excelParams, excelEntityAnn); | ||||
} else { | } else { | ||||
List<Method> newMethods = new ArrayList<Method>(); | List<Method> newMethods = new ArrayList<Method>(); | ||||
@@ -162,24 +176,7 @@ public class ImportBaseService { | |||||
} | } | ||||
} | } | ||||
public void getExcelField(String targetId, Field field, ExcelImportEntity excelEntity, | |||||
Excel excel, Class<?> pojoClass, ExcelEntity excelEntityAnn) throws Exception { | |||||
excelEntity.setName(PoiPublicUtil.getValueByTargetId(excel.name(), targetId, null)); | |||||
if (StringUtils.isNoneEmpty(excel.groupName())) { | |||||
excelEntity.setName(excel.groupName() + "_" + excelEntity.getName()); | |||||
} | |||||
if(excelEntityAnn != null && excelEntityAnn.show()){ | |||||
excelEntity.setName(excelEntityAnn.name() + "_" + excelEntity.getName()); | |||||
} | |||||
String fieldname = field.getName(); | |||||
excelEntity.setMethod(PoiReflectorUtil.fromCache(pojoClass).getSetMethod(fieldname)); | |||||
if (StringUtils.isNotEmpty(excel.importFormat())) { | |||||
excelEntity.setFormat(excel.importFormat()); | |||||
} else { | |||||
excelEntity.setFormat(excel.format()); | |||||
} | |||||
excelEntity.setDict(excel.dict()); | |||||
} | |||||
public void getExcelFieldList(String targetId, Field[] fields, Class<?> pojoClass, | public void getExcelFieldList(String targetId, Field[] fields, Class<?> pojoClass, | ||||
Map<String, ExcelImportEntity> temp, | Map<String, ExcelImportEntity> temp, | ||||
@@ -105,7 +105,7 @@ public final class PoiPublicUtil { | |||||
ExcelCollection collection = field.getAnnotation(ExcelCollection.class); | ExcelCollection collection = field.getAnnotation(ExcelCollection.class); | ||||
PoiReflectorUtil.fromCache(clazz).setValue(obj, field.getName(), | PoiReflectorUtil.fromCache(clazz).setValue(obj, field.getName(), | ||||
collection.type().newInstance()); | collection.type().newInstance()); | ||||
} else if (!isJavaClass(field)) { | |||||
} else if (!isJavaClass(field) && !field.getType().isEnum()) { | |||||
PoiReflectorUtil.fromCache(clazz).setValue(obj, field.getName(), | PoiReflectorUtil.fromCache(clazz).setValue(obj, field.getName(), | ||||
createObject(field.getType(), targetId)); | createObject(field.getType(), targetId)); | ||||
} | } | ||||
@@ -1,6 +1,7 @@ | |||||
package cn.afterturn.easypoi.util; | package cn.afterturn.easypoi.util; | ||||
import java.lang.reflect.Field; | import java.lang.reflect.Field; | ||||
import java.lang.reflect.InvocationTargetException; | |||||
import java.lang.reflect.Method; | import java.lang.reflect.Method; | ||||
import java.lang.reflect.ReflectPermission; | import java.lang.reflect.ReflectPermission; | ||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
@@ -14,20 +15,23 @@ import java.util.concurrent.ConcurrentHashMap; | |||||
/** | /** | ||||
* 反射工具类,缓存读取的class信息,省的一直获取 | * 反射工具类,缓存读取的class信息,省的一直获取 | ||||
* @author JueYue | |||||
* 参考的 mybatis的Reflector | |||||
* | |||||
* @author JueYue | |||||
* 参考的 mybatis的Reflector | |||||
*/ | */ | ||||
public final class PoiReflectorUtil { | public final class PoiReflectorUtil { | ||||
private static final Map<Class<?>, PoiReflectorUtil> CACHE_REFLECTOR = new ConcurrentHashMap<Class<?>, PoiReflectorUtil>(); | private static final Map<Class<?>, PoiReflectorUtil> CACHE_REFLECTOR = new ConcurrentHashMap<Class<?>, PoiReflectorUtil>(); | ||||
private Map<String, Method> getMethods = new HashMap<String, Method>(); | |||||
private Map<String, Method> setMethods = new HashMap<String, Method>(); | |||||
private List<Field> fieldList = new ArrayList<Field>(); | |||||
private Map<String, Method> getMethods = new HashMap<String, Method>(); | |||||
private Map<String, Method> setMethods = new HashMap<String, Method>(); | |||||
private Map<String, Method> enumMethods = new HashMap<String, Method>(); | |||||
private List<Field> fieldList = new ArrayList<Field>(); | |||||
private Class<?> type; | |||||
private Class<?> type; | |||||
private PoiReflectorUtil(Class<?> clazz) { | private PoiReflectorUtil(Class<?> clazz) { | ||||
this.type = clazz; | |||||
addGetMethods(clazz); | addGetMethods(clazz); | ||||
addFields(clazz); | addFields(clazz); | ||||
addSetMethods(clazz); | addSetMethods(clazz); | ||||
@@ -79,11 +83,11 @@ public final class PoiReflectorUtil { | |||||
Class<?> methodType = method.getReturnType(); | Class<?> methodType = method.getReturnType(); | ||||
if (methodType.equals(getterType)) { | if (methodType.equals(getterType)) { | ||||
throw new RuntimeException( | throw new RuntimeException( | ||||
"Illegal overloaded getter method with ambiguous type for property " | |||||
+ propName + " in class " | |||||
+ firstMethod.getDeclaringClass() | |||||
+ ". This breaks the JavaBeans " | |||||
+ "specification and can cause unpredicatble results."); | |||||
"Illegal overloaded getter method with ambiguous type for property " | |||||
+ propName + " in class " | |||||
+ firstMethod.getDeclaringClass() | |||||
+ ". This breaks the JavaBeans " | |||||
+ "specification and can cause unpredicatble results."); | |||||
} else if (methodType.isAssignableFrom(getterType)) { | } else if (methodType.isAssignableFrom(getterType)) { | ||||
// OK getter type is descendant | // OK getter type is descendant | ||||
} else if (getterType.isAssignableFrom(methodType)) { | } else if (getterType.isAssignableFrom(methodType)) { | ||||
@@ -91,11 +95,11 @@ public final class PoiReflectorUtil { | |||||
getterType = methodType; | getterType = methodType; | ||||
} else { | } else { | ||||
throw new RuntimeException( | throw new RuntimeException( | ||||
"Illegal overloaded getter method with ambiguous type for property " | |||||
+ propName + " in class " | |||||
+ firstMethod.getDeclaringClass() | |||||
+ ". This breaks the JavaBeans " | |||||
+ "specification and can cause unpredicatble results."); | |||||
"Illegal overloaded getter method with ambiguous type for property " | |||||
+ propName + " in class " | |||||
+ firstMethod.getDeclaringClass() | |||||
+ ". This breaks the JavaBeans " | |||||
+ "specification and can cause unpredicatble results."); | |||||
} | } | ||||
} | } | ||||
addGetMethod(propName, getter); | addGetMethod(propName, getter); | ||||
@@ -131,7 +135,7 @@ public final class PoiReflectorUtil { | |||||
name = name.substring(3); | name = name.substring(3); | ||||
} else { | } else { | ||||
throw new RuntimeException("Error parsing property name '" + name | throw new RuntimeException("Error parsing property name '" + name | ||||
+ "'. Didn't start with 'is', 'get' or 'set'."); | |||||
+ "'. Didn't start with 'is', 'get' or 'set'."); | |||||
} | } | ||||
if (name.length() == 1 || (name.length() > 1 && !Character.isUpperCase(name.charAt(1)))) { | if (name.length() == 1 || (name.length() > 1 && !Character.isUpperCase(name.charAt(1)))) { | ||||
@@ -169,11 +173,11 @@ public final class PoiReflectorUtil { | |||||
} | } | ||||
if (setter == null) { | if (setter == null) { | ||||
throw new RuntimeException( | throw new RuntimeException( | ||||
"Illegal overloaded setter method with ambiguous type for property " | |||||
+ propName + " in class " | |||||
+ firstMethod.getDeclaringClass() | |||||
+ ". This breaks the JavaBeans " | |||||
+ "specification and can cause unpredicatble results."); | |||||
"Illegal overloaded setter method with ambiguous type for property " | |||||
+ propName + " in class " | |||||
+ firstMethod.getDeclaringClass() | |||||
+ ". This breaks the JavaBeans " | |||||
+ "specification and can cause unpredicatble results."); | |||||
} | } | ||||
addSetMethod(propName, setter); | addSetMethod(propName, setter); | ||||
} | } | ||||
@@ -296,7 +300,7 @@ public final class PoiReflectorUtil { | |||||
Method method = getMethods.get(propertyName); | Method method = getMethods.get(propertyName); | ||||
if (method == null) { | if (method == null) { | ||||
throw new RuntimeException( | throw new RuntimeException( | ||||
"There is no getter for property named '" + propertyName + "' in '" + type + "'"); | |||||
"There is no getter for property named '" + propertyName + "' in '" + type + "'"); | |||||
} | } | ||||
return method; | return method; | ||||
} | } | ||||
@@ -305,13 +309,14 @@ public final class PoiReflectorUtil { | |||||
Method method = setMethods.get(propertyName); | Method method = setMethods.get(propertyName); | ||||
if (method == null) { | if (method == null) { | ||||
throw new RuntimeException( | throw new RuntimeException( | ||||
"There is no getter for property named '" + propertyName + "' in '" + type + "'"); | |||||
"There is no getter for property named '" + propertyName + "' in '" + type + "'"); | |||||
} | } | ||||
return method; | return method; | ||||
} | } | ||||
/** | /** | ||||
* 获取field 值 | * 获取field 值 | ||||
* | |||||
* @param obj | * @param obj | ||||
* @param property | * @param property | ||||
* @return | * @return | ||||
@@ -321,7 +326,7 @@ public final class PoiReflectorUtil { | |||||
Method m = getMethods.get(property); | Method m = getMethods.get(property); | ||||
if (m != null) { | if (m != null) { | ||||
try { | try { | ||||
value = m.invoke(obj, new Object[] {}); | |||||
value = m.invoke(obj, new Object[]{}); | |||||
} catch (Exception ex) { | } catch (Exception ex) { | ||||
} | } | ||||
} | } | ||||
@@ -330,9 +335,10 @@ public final class PoiReflectorUtil { | |||||
/** | /** | ||||
* 设置field值 | * 设置field值 | ||||
* @param obj 对象 | |||||
* | |||||
* @param obj 对象 | |||||
* @param property | * @param property | ||||
* @param object 属性值 | |||||
* @param object 属性值 | |||||
* @return | * @return | ||||
*/ | */ | ||||
public boolean setValue(Object obj, String property, Object object) { | public boolean setValue(Object obj, String property, Object object) { | ||||
@@ -356,4 +362,19 @@ public final class PoiReflectorUtil { | |||||
return fieldList; | return fieldList; | ||||
} | } | ||||
public Object execEnumStaticMethod(String staticMethod, Object params) { | |||||
if (!enumMethods.containsKey(setMethods)) { | |||||
try { | |||||
enumMethods.put(staticMethod,type.getMethod(staticMethod,params.getClass())); | |||||
} catch (NoSuchMethodException e) { | |||||
throw new RuntimeException( | |||||
"There is no enum for property named '" + staticMethod + "' in '" + type + "'"); | |||||
} | |||||
} | |||||
try { | |||||
return enumMethods.get(staticMethod).invoke(null,params); | |||||
} catch (Exception e) { | |||||
throw new RuntimeException(e); | |||||
} | |||||
} | |||||
} | } |