×

一个复杂的用户导入方案,通过反射实现自定义规则解析

我的笔记 我的笔记 发表于2020-07-30 19:25:13 浏览3284 评论0

抢沙发发表评论

背景:

    我们一个客户要求根据模板导入一些数据,本质上这是很简单的一件事,但是客户要求导入的数据需要包含子表。一开始提供得方案是让他们在第二个sheet输入子表数据。但是客户不同意。后台模板改成下图:

image.png

红色区域为主表数据,蓝色区域为子表数据。然后 第二行为 规则 行 ,第三行是数据行。数据行的解析要依照规则行处理。模板下载:

singleFamilyAll.xls

解决办法,我写成一个工具类,和一个注解

1、注解类Describe.java

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Describe {
    String value() default "";
    String bakValue() default "";
    String[] dimCode() default {};
}

2、工具类AnalysisToClass.java

import lombok.Builder;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;

@Builder
public class AnalysisToClass<T> {
    /***
     * 获取个人担保的数据
     * @param
     * @return
     */
    public List<T> analysisDebtPersonalGuarantee(String ruleFiled, String valueFiled, Class clazz) {
        try {

            if(StringUtils.isNotBlank(ruleFiled)){
                List<T> res = new ArrayList<>();
                T debtPersonalGuarantee = null;
                List<Map> methodList = getClassFiledAnnoValue(clazz, ruleFiled);
                if(StringUtils.isNotBlank(valueFiled)){
                    //这里是每一条数据
                    String[] split = valueFiled.split(";");
                    for(String s:split){
                        if(StringUtils.isNotBlank(s)){
                            s = s.replaceAll("\n","");
                            int i = s.indexOf(":")+1;
                            String substring = s.substring(i, s.length());
                            if(StringUtils.isNotBlank(substring)&&s.indexOf(":")>0){
                                debtPersonalGuarantee = (T)clazz.newInstance();
                                //substring = substring.substring(0,substring.length()-1);
                                String[] filedValue = substring.split(",");
                                //如果规则的数量和值是一样的
                                if(methodList!=null && methodList.size()>0){
                                    if(methodList.size()==filedValue.length){
                                        for(int j=0;j<methodList.size();j++){
                                            String filedName = methodList.get(j).get("name").toString();
                                            if(methodList.get(j).get("dimCode")!=null){
                                                String[] strings = (String[]) methodList.get(j).get("dimCode");
                                                if(strings!=null&&strings.length>0){
                                                    for(String dim:strings){
                                                        String[] s1 = dim.split("_");
                                                        if(s1[0].equals(filedValue[j])){
                                                            setValue(debtPersonalGuarantee,"set"+captureName(filedName),s1[1]);
                                                            continue;
                                                        }
                                                    }
                                                }else{
                                                    setValue(debtPersonalGuarantee,"set"+captureName(filedName),filedValue[j]);
                                                }
                                            }

                                        }
                                        res.add(debtPersonalGuarantee);
                                    }else{//如果不满足条件是否提示

                                    }
                                }
                            }
                        }
                    }
                }
                return res;
            }

        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }


    //首字母大写
    private String captureName(String name) {
        char[] cs=name.toCharArray();
        cs[0]-=32;
        return String.valueOf(cs);
    }
    private void  setValue(Object dto,String name,String value)  {
        Method[] m = dto.getClass().getMethods();
        for (int i = 0; i < m.length; i++) {
            if (name.toLowerCase().equals(m[i].getName().toLowerCase())) {
                try {
                    m[i].invoke(dto,value);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
    }
    private List<Map> getClassFiledAnnoValue(Class c, String contrast){
        if(StringUtils.isNotBlank(contrast)){
            Field[] at = c.getDeclaredFields();
            contrast = contrast.replaceAll("\n","");
            contrast = contrast.substring(contrast.indexOf(":")+1,contrast.length());
            contrast = contrast.substring(0,contrast.length()-1);
            String[] split = contrast.split(",");
            List<Map> res = new ArrayList();
            if(at!=null&&at.length>0){
                Arrays.asList(split).stream().forEach(s -> {
                    Arrays.asList(at).stream().forEach(field -> {
                        if(field.isAnnotationPresent(Describe.class)){
                            Describe describe = field.getAnnotation(Describe.class);
                            String value = describe.value();
                            String bakValue = describe.bakValue();
                            if(value.equals(s)||bakValue.equals(s)){
                                Map map = new HashMap<>();
                                map.put("name",field.getName());
                                map.put("dimCode",describe.dimCode());
                                res.add(map);
                            }
                        }
                    });
                });
            }
            return res;
        }
        return null;
    }
}


最后使用方法:

//解析
List<DebtPersonalGuarantee> debtPersonalGuarantees1 = AnalysisToClass.<DebtPersonalGuarantee>builder().build().analysisDebtPersonalGuarantee(rule.getNaturalPersonGuarantor(), indexLibraryModel.getNaturalPersonGuarantor(), DebtPersonalGuarantee.class);
UnitedLogger.debug("个人担保"+debtPersonalGuarantees1);

这个实体类我也贴个图片吧:红色区域就是注解用法

image.png

我的笔记博客版权我的笔记博客版权