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