package cn.cslg.pas.common.utils; import cn.cslg.pas.common.model.vo.ProjectImportPatentVO; import cn.cslg.pas.common.model.vo.UploadParamsVO; import cn.cslg.pas.common.model.vo.UploadSettingVO; import cn.cslg.pas.common.utils.handler.DataProcessHandler; import org.springframework.stereotype.Component; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Objects; /** * @date 2022/7/7 * @description 批量上传专利数据的数据处理工具类 */ @Component public class UploadPatentBatchUtil { /** * @param projectImportPatentVO 前台传入参数 * @param getSettingJson 配置文件解析出的Json串 * @return uploadParamsVO 返回一个由processData方法填充完数据的Pojo类 * @date 2022/7/7 * @name 解析配置文件 * @description 通过与前段传入参数中的数据源ID进行比对从而得到对应数据源的配置项目 */ public static List parsingConfigurationFiles(ProjectImportPatentVO projectImportPatentVO, String getSettingJson) { //将 Json 转换为 对象数组 List test = JsonUtils.jsonToList(getSettingJson, UploadSettingVO.class); //创建一个存放单一数据源的对象 这个对象存放的是 我们需要使用哪一个数据源的配置数据 所以只存一个 正常在Json文件里面会有多个数据源 也就是多条数据 List jsonData = new ArrayList<>(); //开始将前端传入的数据源参数与 Json 中解析出来的 sourceId(数据来源ID) 进行比对 并将比对中的那一条数据放入上方定义的 jsonData 中 用于后续使用 for (int i = 0; i < Objects.requireNonNull(test).size(); i++) { //提取一个常量 UploadSettingVO constant = Objects.requireNonNull(test).get(i); //判断 如果说 Json 解析出来的 List 中的 sourceId 和传入参数的 sourceId 匹配成功 则开始装配数据 if (constant.getSourceId().equals(projectImportPatentVO.getSourceId())) { //填充数据 jsonData = constant.getColumn(); } } //返回填充好的数据 return jsonData; } /** * @param row 任务参数 * @param jsonData 处理好后转换为Pojo类的配置文件数据 * @return uploadParamsVO 返回一个填充完数据的Pojo类 * @date 2022/7/7 * @name 处理数据 * @description 通过配置项目中的栏位名称和通过解析Excel得到的栏位名称进行比对 并对所属栏位的数据进行分割或其他处理 最后将处理完的数据填充进类中 用于向数据库存入数据 */ public static UploadParamsVO processData(Map row, List jsonData) { UploadParamsVO uploadParamsVO = new UploadParamsVO(); try { for (Object object : row.keySet()) { String key = object.toString(); Object value = row.get(key); if (StringUtils.isNotNull(value) && !value.equals("") && !value.equals("-") && !value.equals("\\")) { //将配置项与Excel栏位进行比对 List temVOColumn = getColumn(jsonData, key); for (UploadSettingVO.Column column : temVOColumn) { //创建处理对象 Object processData = DataProcessHandler.getData(column.getHandler(), column.getJarOrClassPath()); //调用处理对象中的对应处理方法对Excel中的数据进行处理 Object getProcessData = null; if (processData != null) { Method method = processData.getClass().getMethod("processData", Object.class, Object.class); getProcessData = method.invoke(processData, value.toString(), column.getSplitSymbol()); } //将格式化后的数据装配到VO类 assemblyObject(uploadParamsVO, column.getColumn(), getProcessData); if (key.contains(":")) { uploadParamsVO.setKey(key); } } } } } catch (Exception e) { e.printStackTrace(); } //数据装配完毕 准备返回Service层 进行数据库操作 return uploadParamsVO; } private static List getColumn(List jsonData, String key) { List columnList = new ArrayList<>(); for (UploadSettingVO.Column jsonDatum : jsonData) { if (jsonDatum.getSetName().equals(key)) { columnList.add(jsonDatum); } } if (key.contains(":")) { UploadSettingVO.Column field = new UploadSettingVO.Column(); field.setColumn("fieldList"); field.setSplitSymbol("\\\n"); field.setHandler("cn.cslg.pas.common.utils.handler.StringSpecialHandler"); columnList.add(field); } return columnList; } /** * @param obj 装配对象(UploadParamsVO) * @param propertyPath 以.隔开的属性路径(配置文件中的 Column) * @param value 值(row 每一行的值 在上层方法中叫 value) * @name 装配对象 * @description 通过反射将处理后的数据赋值到装配对象的给定路径的属性值 */ private static void assemblyObject(Object obj, String propertyPath, Object value) { //将属性的路径通过 "." 进行拆分 数据样式大致为 patentRightList.content 或者 patentInstructionText.manual //"."前面的是UploadParamsVO的属性名称 可能是List或者Object //"."后面的是List中的Object的属性 或者Object的属性 String[] splitProperty = propertyPath.split("\\."); //初始化一个基类 用于存储数据 Object temObj = obj; try { //进行属性路径的循环 这里一般都是两次 for (int i = 0; i < splitProperty.length; i++) { //如果需要为对应参数赋值 第一次循环不会进入这一分支 if (i == splitProperty.length - 1) { //如果是列表 if (temObj instanceof List) { //取创建空数据中的第一条 Object firstItem = ((List) temObj).get(0); //获取该条数据的类型 String listObjectType = firstItem.getClass().getTypeName(); //如果列表中的数据少于给的值的列表中的数据量 //添加数据以与给定的值对齐 if (((List) temObj).size() < ((List) Objects.requireNonNull(value)).size()) { for (int iIndex = ((List) temObj).size(); iIndex < ((List) value).size(); iIndex++) { Object cObj = Class.forName(listObjectType).newInstance();// trueType.newInstance(); ((List) temObj).add(cObj); } } //给列表中的对象相对应的属性赋值 for (int iIndex = 0; iIndex < ((List) value).size(); iIndex++) { Object inListObj = ((List) temObj).get(iIndex); Field f = inListObj.getClass().getDeclaredField(splitProperty[i]); f.setAccessible(true); if (!((List) value).isEmpty()) { f.set(inListObj, ((List) value).get(iIndex)); } } } else { Field f = temObj.getClass().getDeclaredField(splitProperty[i]); f.setAccessible(true); if (value != null) { f.set(temObj, value); } } } else { // Field f = temObj.getClass().getDeclaredField(splitProperty[i]); //允许设置私有(private)属性 f.setAccessible(true); //获取 Object propertyValue = f.get(obj); if (propertyValue == null) { if (f.getType().getName().contains("List")) { propertyValue = createList(f); } else { propertyValue = f.getType().newInstance(); } f.set(temObj, propertyValue); } temObj = propertyValue; } } } catch (Exception e) { e.printStackTrace(); } } private static List createList(Field f) { //如果是列表,创建一个List并添加一个对应类型的对象 List lst = new ArrayList<>(); //取List属性中包含的对象类型 Type trueType = f.getGenericType(); Type listArgumentObj = ((ParameterizedType) trueType).getActualTypeArguments()[0]; Object cObj = null; try { cObj = Class.forName(listArgumentObj.getTypeName()).newInstance(); } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { e.printStackTrace(); } lst.add(cObj); return lst; } }