forked from sfms3.0/sfms3.0
4 changed files with 215 additions and 2 deletions
@ -0,0 +1,15 @@ |
|||
package com.win.framework.excel.core.annotations; |
|||
|
|||
import java.lang.annotation.*; |
|||
|
|||
/** |
|||
* 字典格式化 |
|||
* |
|||
* 实现将字典数据的值,格式化成字典数据的标签 |
|||
*/ |
|||
@Target({ElementType.FIELD}) |
|||
@Retention(RetentionPolicy.RUNTIME) |
|||
@Inherited |
|||
public @interface OnlyOne { |
|||
|
|||
} |
@ -0,0 +1,15 @@ |
|||
package com.win.framework.excel.core.annotations; |
|||
|
|||
import java.lang.annotation.*; |
|||
|
|||
/** |
|||
* 字典格式化 |
|||
* |
|||
* 实现将字典数据的值,格式化成字典数据的标签 |
|||
*/ |
|||
@Target({ElementType.FIELD}) |
|||
@Retention(RetentionPolicy.RUNTIME) |
|||
@Inherited |
|||
public @interface SubObject { |
|||
|
|||
} |
@ -0,0 +1,177 @@ |
|||
package com.win.framework.excel.core.listener; |
|||
|
|||
import cn.hutool.core.annotation.AnnotationUtil; |
|||
import cn.hutool.core.bean.BeanUtil; |
|||
import cn.hutool.core.util.ReflectUtil; |
|||
import com.alibaba.excel.context.AnalysisContext; |
|||
import com.alibaba.excel.event.AnalysisEventListener; |
|||
import com.google.common.base.Objects; |
|||
import com.win.framework.common.exception.ServiceException; |
|||
import com.win.framework.excel.core.annotations.OnlyOne; |
|||
import com.win.framework.excel.core.annotations.SubObject; |
|||
import lombok.Data; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
|
|||
import java.lang.reflect.Field; |
|||
import java.lang.reflect.InvocationTargetException; |
|||
import java.lang.reflect.Method; |
|||
import java.lang.reflect.ParameterizedType; |
|||
import java.util.ArrayList; |
|||
import java.util.Collection; |
|||
import java.util.List; |
|||
|
|||
@Data |
|||
@Slf4j |
|||
public class ExcelListener<T> extends AnalysisEventListener<T> { |
|||
|
|||
/** |
|||
* excel数据 |
|||
*/ |
|||
private List<Object> dataList; |
|||
|
|||
/** |
|||
* 判断重复的属性方法 |
|||
*/ |
|||
private String methodName; |
|||
|
|||
/** |
|||
* 子类 |
|||
*/ |
|||
private String subObjectMethodName; |
|||
|
|||
/** |
|||
* 主表class |
|||
*/ |
|||
private Class<?> mainClass; |
|||
|
|||
/** |
|||
* 子表class |
|||
*/ |
|||
private Class<?> subClass; |
|||
|
|||
/** |
|||
* 构造函数 |
|||
*/ |
|||
public ExcelListener(Class<?> mainClass) { |
|||
dataList = new ArrayList<>(); |
|||
this.mainClass = mainClass; |
|||
} |
|||
|
|||
@Override |
|||
public void invoke(T object, AnalysisContext analysisContext) { |
|||
if(this.methodName == null) { |
|||
String methodName = this.getOnlyOneAnnotation(); |
|||
if(methodName == null) { |
|||
throw new ServiceException().setMessage("未发现OnlyOne注解属性"); |
|||
} |
|||
this.methodName = methodName; |
|||
} |
|||
if(this.subObjectMethodName == null) { |
|||
String subObjectMethodName = this.getSubObjectAnnotation(); |
|||
if(subObjectMethodName == null) { |
|||
throw new ServiceException().setMessage("未发现SubObject注解属性"); |
|||
} |
|||
this.subObjectMethodName = subObjectMethodName; |
|||
} |
|||
this.buildEntity(object); |
|||
} |
|||
|
|||
@Override |
|||
public void doAfterAllAnalysed(AnalysisContext analysisContext) { |
|||
|
|||
} |
|||
|
|||
/** |
|||
* 判断数据是否存在 |
|||
*/ |
|||
private Object checkDataIsExist(T object) { |
|||
for(Object obj : dataList) { |
|||
Object methodValue1 = ReflectUtil.invoke(obj, "get" + this.methodName); |
|||
Object methodValue2 = ReflectUtil.invoke(object, "get" + this.methodName); |
|||
if(methodValue1.equals(methodValue2)) { |
|||
return obj; |
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
/** |
|||
* 添加数据 |
|||
* @param vo |
|||
*/ |
|||
private void buildEntity(T vo) { |
|||
Object mainObject = this.checkDataIsExist(vo); |
|||
Object subObject; |
|||
try {//创建子数据对象
|
|||
subObject = this.subClass.getDeclaredConstructors()[0].newInstance((Object) null); |
|||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { |
|||
throw new RuntimeException(e); |
|||
} |
|||
BeanUtil.copyProperties(vo, subObject); |
|||
if(mainObject == null) {//list中不存在主数据
|
|||
try {//创建主数据对象
|
|||
mainObject = this.mainClass.getDeclaredConstructors()[0].newInstance((Object) null); |
|||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { |
|||
throw new RuntimeException(e); |
|||
} |
|||
BeanUtil.copyProperties(vo, mainObject); |
|||
Method setMethod = ReflectUtil.getMethod(this.mainClass, "set" + this.subObjectMethodName); |
|||
List<Object> subClassList = new ArrayList<>(); |
|||
subClassList.add(subObject); |
|||
ReflectUtil.invoke(mainObject, setMethod, subClassList); |
|||
dataList.add(mainObject); |
|||
} else {//list中存在主数据,只添加子数据
|
|||
Method getMethod = ReflectUtil.getMethod(this.mainClass, "get" + this.subObjectMethodName); |
|||
List<Object> subClassList = ReflectUtil.invoke(mainObject, getMethod); |
|||
subClassList.add(subObject); |
|||
Method setMethod = ReflectUtil.getMethod(this.mainClass, "set" + this.subObjectMethodName); |
|||
ReflectUtil.invoke(mainObject, setMethod, subClassList); |
|||
} |
|||
} |
|||
|
|||
private String getOnlyOneAnnotation() { |
|||
Field[] fields = mainClass.getDeclaredFields(); |
|||
for (Field field : fields) { |
|||
// 只判断该字段拥有非空注解
|
|||
if (AnnotationUtil.hasAnnotation(field, OnlyOne.class)){ |
|||
//获取属性的名字
|
|||
String attributeName = field.getName(); |
|||
//将属性名字的首字母大写
|
|||
return Character.toUpperCase(attributeName.charAt(0)) + attributeName.substring(1); |
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
private String getSubObjectAnnotation() { |
|||
Object object; |
|||
try { |
|||
object = mainClass.getDeclaredConstructors()[0].newInstance((Object) null); |
|||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { |
|||
throw new RuntimeException(e); |
|||
} |
|||
Field[] fields = object.getClass().getDeclaredFields(); |
|||
for (Field field : fields) { |
|||
// 只判断该字段拥有非空注解
|
|||
if (AnnotationUtil.hasAnnotation(field, SubObject.class)) { |
|||
Class<?> fieldType = field.getType(); |
|||
if (Collection.class.isAssignableFrom(fieldType)) { |
|||
java.lang.reflect.Type[] actualType = ((ParameterizedType) field.getGenericType()).getActualTypeArguments(); |
|||
if (actualType.length != 1 || actualType[0] == null || actualType[0].toString().length() < 5 || !Objects.equal(actualType[0].toString().substring(0, 5).toLowerCase(), "class")){ |
|||
// 非class类型的不处理
|
|||
throw new ServiceException().setMessage("SubObject非泛型"); |
|||
} |
|||
this.subClass = actualType[0].getClass(); |
|||
} else { |
|||
throw new ServiceException().setMessage("SubObject注解属性必须是Collection实现类"); |
|||
} |
|||
//获取属性的名字
|
|||
String attributeName = field.getName(); |
|||
//将属性名字的首字母大写
|
|||
return Character.toUpperCase(attributeName.charAt(0)) + attributeName.substring(1); |
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
} |
Loading…
Reference in new issue