瀏覽代碼

【CHG】优化数据导入

zhaomn 2 年之前
父節點
當前提交
65a8fb31d5

+ 7 - 7
railway-business/src/main/java/com/railway/business/bi/domain/ShowGsd.java

@@ -37,31 +37,31 @@ public class ShowGsd extends BaseEntity {
   private String lineName;
 
   @ApiModelProperty(value = "架空线路 km")
-  @Excel(name = "架空线路(km)")
+  @Excel(name = "设备名称架空线路(km)")
   private BigDecimal jkxl;
 
   @ApiModelProperty(value = "电缆线路 km")
-  @Excel(name = "电缆线路(km)")
+  @Excel(name = "设备名称电缆线路(km)")
   private BigDecimal dlxl;
 
   @ApiModelProperty(value = "隔离开关")
-  @Excel(name = "隔离开关(台)")
+  @Excel(name = "设备名称隔离开关(台)")
   private Integer glkg;
 
   @ApiModelProperty(value = "断路器")
-  @Excel(name = "断路器(台)")
+  @Excel(name = "设备名称断路器(台)")
   private Integer dlq;
 
   @ApiModelProperty(value = "电缆接头")
-  @Excel(name = "电缆接头(个)")
+  @Excel(name = "设备名称电缆接头(个)")
   private Integer dljt;
 
   @ApiModelProperty(value = "电缆井")
-  @Excel(name = "电缆井(座)")
+  @Excel(name = "设备名称电缆井(座)")
   private Integer dlj;
 
   @ApiModelProperty(value = "接续箱")
-  @Excel(name = "接续箱(座)")
+  @Excel(name = "设备名称接续箱(座)")
   private Integer jxx;
 
   @ApiModelProperty(value = "维修方式")

+ 49 - 116
railway-business/src/main/java/com/railway/business/bi/service/impl/ShowFileServiceImpl.java

@@ -13,23 +13,23 @@ import com.railway.business.bi.domain.ShowYdts;
 import com.railway.business.bi.enums.ImpFileTypeEnum;
 import com.railway.business.bi.enums.ImpSheetEnum;
 import com.railway.business.bi.enums.YcxxFoundModeEnum;
+import com.railway.business.bi.mapper.ShowBdycMapper;
+import com.railway.business.bi.mapper.ShowBpdjxjhMapper;
+import com.railway.business.bi.mapper.ShowDlycMapper;
 import com.railway.business.bi.mapper.ShowFileMapper;
-import com.railway.business.bi.service.IShowBdycService;
-import com.railway.business.bi.service.IShowBpdjxjhService;
-import com.railway.business.bi.service.IShowDlycService;
+import com.railway.business.bi.mapper.ShowGsdMapper;
+import com.railway.business.bi.mapper.ShowGsyMapper;
+import com.railway.business.bi.mapper.ShowSbxjMapper;
+import com.railway.business.bi.mapper.ShowTestPlanDtMapper;
+import com.railway.business.bi.mapper.ShowTestPlanKgMapper;
+import com.railway.business.bi.mapper.ShowYdtsMapper;
 import com.railway.business.bi.service.IShowFileService;
-import com.railway.business.bi.service.IShowGsdService;
-import com.railway.business.bi.service.IShowGsyService;
-import com.railway.business.bi.service.IShowSbxjService;
-import com.railway.business.bi.service.IShowTestPlanDtService;
-import com.railway.business.bi.service.IShowTestPlanKgService;
-import com.railway.business.bi.service.IShowYdtsService;
 import com.railway.common.core.domain.AjaxResult;
 import com.railway.common.enums.BusinessStatus;
-import com.railway.common.enums.DelFlagEnum;
 import com.railway.common.utils.SecurityUtils;
 import com.railway.common.utils.StringUtils;
 import com.railway.common.utils.poi.ExcelUtil;
+import com.railway.framework.datasource.MybatisBatchUtils;
 import java.time.LocalDateTime;
 import java.util.List;
 import org.apache.poi.ss.usermodel.Workbook;
@@ -47,34 +47,13 @@ import org.springframework.web.multipart.MultipartFile;
 public class ShowFileServiceImpl implements IShowFileService {
 
   private final ShowFileMapper showFileMapper;
-  private final IShowBdycService bdycService;
-  private final IShowDlycService dlycService;
-  private final IShowTestPlanDtService dtService;
-  private final IShowTestPlanKgService kgService;
-  private final IShowBpdjxjhService bpdjxjhService;
-  private final IShowGsdService gsdService;
-  private final IShowGsyService gsyService;
-  private final IShowYdtsService ydtsService;
-  private final IShowSbxjService sbxjService;
+  private final MybatisBatchUtils batchUtils;
 
-  public ShowFileServiceImpl(ShowFileMapper showFileMapper, IShowBdycService bdycService,
-      IShowDlycService dlycService, IShowTestPlanDtService dtService,
-      IShowTestPlanKgService kgService, IShowBpdjxjhService bpdjxjhService,
-      IShowGsdService gsdService, IShowGsyService gsyService, IShowYdtsService ydtsService,
-      IShowSbxjService sbxjService) {
+  public ShowFileServiceImpl(ShowFileMapper showFileMapper, MybatisBatchUtils batchUtils) {
     this.showFileMapper = showFileMapper;
-    this.bdycService = bdycService;
-    this.dlycService = dlycService;
-    this.dtService = dtService;
-    this.kgService = kgService;
-    this.bpdjxjhService = bpdjxjhService;
-    this.gsdService = gsdService;
-    this.gsyService = gsyService;
-    this.ydtsService = ydtsService;
-    this.sbxjService = sbxjService;
+    this.batchUtils = batchUtils;
   }
 
-
   /**
    * 检修兑现情况-2022年变配电所检修计划表(检测数字化)
    *
@@ -96,16 +75,12 @@ public class ShowFileServiceImpl implements IShowFileService {
       ExcelUtil<ShowBpdjxjh> util = new ExcelUtil<>(ShowBpdjxjh.class);
       List<ShowBpdjxjh> bdList;
       try {
-        bdList = util.importExcel(sheetName, wb, 3);
+        bdList = util.importExcel(fileId, wb, sheetName, 3);
       } catch (Exception e) {
         e.printStackTrace();
         return AjaxResult.error("文件读取失败");
       }
-      for (ShowBpdjxjh show : bdList) {
-        show.setFileId(fileId);
-        show.setDelFlag(DelFlagEnum.NOT_DELETE.getCode());
-        bpdjxjhService.create(show);
-      }
+      batchUtils.batchInsert(bdList, ShowBpdjxjhMapper.class, ShowBpdjxjhMapper::insert);
     }
     showFile.setImpResult(String.valueOf(BusinessStatus.SUCCESS.ordinal()));
     return AjaxResult.success();
@@ -131,31 +106,23 @@ public class ShowFileServiceImpl implements IShowFileService {
           ExcelUtil<ShowTestPlanKg> bdUtil = new ExcelUtil<>(ShowTestPlanKg.class);
           List<ShowTestPlanKg> bdList;
           try {
-            bdList = bdUtil.importExcel(sheetName, wb, 2, 4);
+            bdList = bdUtil.importExcel(fileId, wb, sheetName, 2, 4);
           } catch (Exception e) {
             e.printStackTrace();
             return AjaxResult.error("文件读取失败");
           }
-          for (ShowTestPlanKg bdyc : bdList) {
-            bdyc.setFileId(fileId);
-            bdyc.setDelFlag(DelFlagEnum.NOT_DELETE.getCode());
-            kgService.create(bdyc);
-          }
+          batchUtils.batchInsert(bdList, ShowTestPlanKgMapper.class, ShowTestPlanKgMapper::insert);
           break;
         case DTSY:
           ExcelUtil<ShowTestPlanDt> dlUtil = new ExcelUtil<>(ShowTestPlanDt.class);
           List<ShowTestPlanDt> dlList;
           try {
-            dlList = dlUtil.importExcel(sheetName, wb, 1);
+            dlList = dlUtil.importExcel(fileId, wb, sheetName, 1);
           } catch (Exception e) {
             e.printStackTrace();
             return AjaxResult.error("文件读取失败");
           }
-          for (ShowTestPlanDt dlyc : dlList) {
-            dlyc.setFileId(fileId);
-            dlyc.setDelFlag(DelFlagEnum.NOT_DELETE.getCode());
-            dtService.create(dlyc);
-          }
+          batchUtils.batchInsert(dlList, ShowTestPlanDtMapper.class, ShowTestPlanDtMapper::insert);
           break;
         default:
           break;
@@ -183,57 +150,42 @@ public class ShowFileServiceImpl implements IShowFileService {
       switch (sheetEnum) {
         case YDTS:
           ExcelUtil<ShowYdts> bdUtil = new ExcelUtil<>(ShowYdts.class);
-          List<ShowYdts> bdList;
+          List<ShowYdts> ydtsList;
           try {
-            bdList = bdUtil.importExcel(sheetName, wb, 1, 3);
+            ydtsList = bdUtil.importExcel(fileId, wb, sheetName, 1, 3);
           } catch (Exception e) {
             e.printStackTrace();
             return AjaxResult.error("文件读取失败");
           }
-          for (ShowYdts bdyc : bdList) {
-            if(StringUtils.isEmpty(bdyc.getSubstationName()) || "0".equals(bdyc.getSubstationName())){
-              continue;
-            }
-            bdyc.setDelFlag(DelFlagEnum.NOT_DELETE.getCode());
-            bdyc.setFileId(fileId);
-            ydtsService.create(bdyc);
-          }
+          ydtsList.removeIf(ydts -> StringUtils.isEmpty(ydts.getSubstationName()) || "0".equals(
+              ydts.getSubstationName()));
+          batchUtils.batchInsert(ydtsList, ShowYdtsMapper.class, ShowYdtsMapper::insert);
           break;
         case GSD:
           ExcelUtil<ShowGsd> dlUtil = new ExcelUtil<>(ShowGsd.class);
-          List<ShowGsd> dlList;
+          List<ShowGsd> gsdList;
           try {
-            dlList = dlUtil.importExcel(sheetName, wb, 2, 4);
+            gsdList = dlUtil.importExcel(fileId, wb, sheetName, 2, 4);
           } catch (Exception e) {
             e.printStackTrace();
             return AjaxResult.error("文件读取失败");
           }
-          for (ShowGsd dlyc : dlList) {
-            if(StringUtils.isEmpty(dlyc.getLineName()) || "0".equals(dlyc.getLineName())){
-              continue;
-            }
-            dlyc.setFileId(fileId);
-            dlyc.setDelFlag(DelFlagEnum.NOT_DELETE.getCode());
-            gsdService.create(dlyc);
-          }
+          gsdList.removeIf(gsd -> StringUtils.isEmpty(gsd.getLineName()) || "0".equals(
+              gsd.getLineName()));
+          batchUtils.batchInsert(gsdList, ShowGsdMapper.class, ShowGsdMapper::insert);
           break;
         case GSY:
           ExcelUtil<ShowGsy> syUtil = new ExcelUtil<>(ShowGsy.class);
-          List<ShowGsy> syList;
+          List<ShowGsy> gsyList;
           try {
-            syList = syUtil.importExcel(sheetName, wb, 1, 3);
+            gsyList = syUtil.importExcel(fileId, wb, sheetName, 1, 3);
           } catch (Exception e) {
             e.printStackTrace();
             return AjaxResult.error("文件读取失败");
           }
-          for (ShowGsy dlyc : syList) {
-            if(StringUtils.isEmpty(dlyc.getSubstationName()) || "0".equals(dlyc.getSubstationName())){
-              continue;
-            }
-            dlyc.setFileId(fileId);
-            dlyc.setDelFlag(DelFlagEnum.NOT_DELETE.getCode());
-            gsyService.create(dlyc);
-          }
+          gsyList.removeIf(gsy -> StringUtils.isEmpty(gsy.getSubstationName()) || "0".equals(
+              gsy.getSubstationName()));
+          batchUtils.batchInsert(gsyList, ShowGsyMapper.class, ShowGsyMapper::insert);
           break;
         default:
           break;
@@ -259,38 +211,29 @@ public class ShowFileServiceImpl implements IShowFileService {
     for (String sheetName : sheetList) {
       ImpSheetEnum sheetEnum = ImpSheetEnum.ofValue(sheetName);
       ExcelUtil<ShowSbxj> bdUtil = new ExcelUtil<>(ShowSbxj.class);
-      List<ShowSbxj> bdList;
+      List<ShowSbxj> list = null;
       switch (sheetEnum) {
         case BD:
           try {
-            bdList = bdUtil.importExcel(sheetName, wb, 1);
+            list = bdUtil.importExcel(fileId, wb, sheetName, 1);
           } catch (Exception e) {
             e.printStackTrace();
             return AjaxResult.error("文件读取失败");
           }
-          for (ShowSbxj bdyc : bdList) {
-            bdyc.setFileId(fileId);
-            bdyc.setQybds("1");
-            bdyc.setDelFlag(DelFlagEnum.NOT_DELETE.getCode());
-            sbxjService.create(bdyc);
-          }
+          list.forEach(bdyc -> bdyc.setQybds("1"));
           break;
         case DL:
           try {
-            bdList = bdUtil.importExcel(sheetName, wb, 1, 3);
+            list = bdUtil.importExcel(fileId, wb, sheetName, 1, 3);
           } catch (Exception e) {
             e.printStackTrace();
             return AjaxResult.error("文件读取失败");
           }
-          for (ShowSbxj dlyc : bdList) {
-            dlyc.setFileId(fileId);
-            dlyc.setDelFlag(DelFlagEnum.NOT_DELETE.getCode());
-            sbxjService.create(dlyc);
-          }
           break;
         default:
           break;
       }
+      batchUtils.batchInsert(list, ShowSbxjMapper.class, ShowSbxjMapper::insert);
     }
     showFile.setImpResult(String.valueOf(BusinessStatus.SUCCESS.ordinal()));
     return AjaxResult.success();
@@ -321,40 +264,30 @@ public class ShowFileServiceImpl implements IShowFileService {
           ExcelUtil<ShowBdyc> bdUtil = new ExcelUtil<>(ShowBdyc.class);
           List<ShowBdyc> bdList;
           try {
-            bdList = bdUtil.importExcel(sheetName, wb);
+            bdList = bdUtil.importExcel(fileId, wb, sheetName);
           } catch (Exception e) {
             e.printStackTrace();
             return AjaxResult.error("文件读取失败");
           }
-          for (ShowBdyc bdyc : bdList) {
-            if (null == bdyc.getFoundDate()) {
-              continue;
-            }
-            bdyc.setFileId(fileId);
-            bdyc.setFoundMode(foundMode);
-            bdyc.setDelFlag(DelFlagEnum.NOT_DELETE.getCode());
-            bdycService.create(bdyc);
-          }
+          String foundMode1 = foundMode;
+          bdList.removeIf(bdyc -> null == bdyc.getFoundDate());
+          bdList.forEach(bdyc -> bdyc.setFoundMode(foundMode1));
+          batchUtils.batchInsert(bdList, ShowBdycMapper.class, ShowBdycMapper::insert);
           break;
         case YCT3:
         case YCT4:
           ExcelUtil<ShowDlyc> dlUtil = new ExcelUtil<>(ShowDlyc.class);
           List<ShowDlyc> dlList;
           try {
-            dlList = dlUtil.importExcel(sheetName, wb);
+            dlList = dlUtil.importExcel(fileId, wb, sheetName);
           } catch (Exception e) {
             e.printStackTrace();
             return AjaxResult.error("文件读取失败");
           }
-          for (ShowDlyc dlyc : dlList) {
-            if (null == dlyc.getFoundDate()) {
-              continue;
-            }
-            dlyc.setFileId(fileId);
-            dlyc.setFoundMode(foundMode);
-            dlyc.setDelFlag(DelFlagEnum.NOT_DELETE.getCode());
-            dlycService.create(dlyc);
-          }
+          String foundMode2 = foundMode;
+          dlList.removeIf(dlyc -> null == dlyc.getFoundDate());
+          dlList.forEach(dlyc -> dlyc.setFoundMode(foundMode2));
+          batchUtils.batchInsert(dlList, ShowDlycMapper.class, ShowDlycMapper::insert);
           break;
         default:
           break;

+ 145 - 120
railway-common/src/main/java/com/railway/common/utils/poi/ExcelUtil.java

@@ -6,9 +6,11 @@ import com.railway.common.annotation.Excel.Type;
 import com.railway.common.annotation.Excels;
 import com.railway.common.constant.Constants;
 import com.railway.common.core.text.Convert;
+import com.railway.common.enums.DelFlagEnum;
 import com.railway.common.exception.UtilException;
 import com.railway.common.utils.DictUtils;
 import com.railway.common.utils.LocalDateUtil;
+import com.railway.common.utils.SecurityUtils;
 import com.railway.common.utils.StringUtils;
 import com.railway.common.utils.file.FileTypeUtils;
 import com.railway.common.utils.file.FileUploadUtils;
@@ -321,7 +323,7 @@ public class ExcelUtil<T> {
   public List<T> importExcel(String sheetName, InputStream is, int titleNum, int dataStartNum)
       throws Exception {
     this.wb = WorkbookFactory.create(is);
-    return importExcel(sheetName, wb, titleNum, dataStartNum);
+    return importExcel(null, wb, sheetName, titleNum, dataStartNum);
   }
 
   /**
@@ -331,8 +333,8 @@ public class ExcelUtil<T> {
    * @param sheetName 表格索引名
    * @return 转换后集合
    */
-  public List<T> importExcel(String sheetName, Workbook wb, int titleNum) throws Exception {
-    return importExcel(sheetName, wb, titleNum, titleNum + 1);
+  public List<T> importExcel(Long fileId, Workbook wb, String sheetName, int titleNum) throws Exception {
+    return importExcel(fileId, wb, sheetName, titleNum, titleNum + 1);
   }
 
   /**
@@ -342,8 +344,8 @@ public class ExcelUtil<T> {
    * @param sheetName 表格索引名
    * @return 转换后集合
    */
-  public List<T> importExcel(String sheetName, Workbook wb) throws Exception {
-    return importExcel(sheetName, wb, 0, 1);
+  public List<T> importExcel(Long fileId, Workbook wb, String sheetName) throws Exception {
+    return importExcel(fileId, wb, sheetName, 0, 1);
   }
 
   /**
@@ -354,7 +356,7 @@ public class ExcelUtil<T> {
    * @param wb Workbook
    * @return 转换后集合
    */
-  public List<T> importExcel(String sheetName, Workbook wb, int titleNum, int dataStartNum)
+  public List<T> importExcel(Long fileId, Workbook wb, String sheetName, int titleNum, int dataStartNum)
       throws Exception {
     this.type = Type.IMPORT;
     List<T> list = new ArrayList<>();
@@ -375,133 +377,156 @@ public class ExcelUtil<T> {
     }
     // 获取最后一个非空行的行下标,比如总行数为n,则返回的为n-1
     int rows = sheet.getLastRowNum();
+    if (rows == 0) {
+      return list;
+    }
 
-    if (rows > 0) {
-      // 定义一个map用于存放excel列的序号和field.
-      Map<String, Integer> cellMap = new HashMap<>();
-      Map<Integer, String> cellMapTmp = new HashMap<>();
-      // 获取表头
-      for (int hRow = titleNum; hRow < dataStartNum; hRow++) {
-        Row heard = sheet.getRow(hRow);
-        for (int i = 0; i < heard.getPhysicalNumberOfCells(); i++) {
-          Cell cell = heard.getCell(i);
-          if (StringUtils.isNotNull(cell)) {
-            String value = this.getCellValue(heard, i).toString().replaceAll("\n", "");
-            if (cellMapTmp.containsKey(i)) {
-              if(StringUtils.isEmpty(value)) {
-                value = cellMapTmp.get(i);
-              } else {
-                value = cellMapTmp.get(i).replaceAll("`", "") + value;
-              }
-            }
-            if (StringUtils.isEmpty(value) && i > 0) {
-              value = cellMapTmp.get(i - 1) + "`";
-            }
-            cellMapTmp.put(i, value);
-          }
-        }
+    Map<Integer, Object[]> fieldsMap = getFieldsMap(sheet, titleNum, dataStartNum);
+    for (int i = dataStartNum; i <= rows; i++) {
+      // 从第2行开始取数据,默认第一行是表头.
+      Row row = sheet.getRow(i);
+      // 判断当前行是否是空行
+      if (isRowEmpty(row)) {
+        continue;
       }
-      for (Map.Entry<Integer, String> entry : cellMapTmp.entrySet()) {
-        if(cellMap.containsKey(entry.getValue())){
-          continue;
+      T entity = null;
+      for (Map.Entry<Integer, Object[]> entry : fieldsMap.entrySet()) {
+        // 如果不存在实例则新建.
+        entity = (entity == null ? clazz.newInstance() : entity);
+        // 从map中得到对应列的field.
+        Field field = (Field) entry.getValue()[0];
+        Excel attr = (Excel) entry.getValue()[1];
+        Object val = convert(entry, field, row);
+        String propertyName = field.getName();
+        if (StringUtils.isNotEmpty(attr.targetAttr())) {
+          propertyName = field.getName() + "." + attr.targetAttr();
+        } else if (StringUtils.isNotEmpty(attr.readConverterExp())) {
+          val = reverseByExp(Convert.toStr(val), attr.readConverterExp(), attr.separator());
+        } else if (StringUtils.isNotEmpty(attr.dictType())) {
+          val = reverseDictByExp(Convert.toStr(val), attr.dictType(), attr.separator());
+        } else if (!attr.handler().equals(ExcelHandlerAdapter.class)) {
+          val = dataFormatHandlerAdapter(val, attr);
+        } else if (ColumnType.IMAGE == attr.cellType() && StringUtils.isNotEmpty(pictures)) {
+          PictureData image = pictures.get(row.getRowNum() + "_" + entry.getKey());
+          if (image == null) {
+            val = "";
+          } else {
+            byte[] data = image.getData();
+            val = FileUtils.writeImportBytes(data);
+          }
         }
-        cellMap.put(entry.getValue(), entry.getKey());
+        ReflectUtils.invokeSetter(entity, propertyName, val);
       }
-      // 有数据时才处理 得到类的所有field.
-      List<Object[]> fields = this.getFields();
-      Map<Integer, Object[]> fieldsMap = new HashMap<>();
-      for (Object[] objects : fields) {
-        Excel attr = (Excel) objects[1];
-        Integer column = cellMap.get(attr.name());
-        if (column != null) {
-          fieldsMap.put(column, objects);
+      if (null != entity) {
+        if(StringUtils.isNotEmpty(fileId)) {
+          setBaseValue(entity, fileId);
         }
+        list.add(entity);
       }
-      for (int i = dataStartNum; i <= rows; i++) {
-        // 从第2行开始取数据,默认第一行是表头.
-        Row row = sheet.getRow(i);
-        // 判断当前行是否是空行
-        if (isRowEmpty(row)) {
-          continue;
-        }
-        T entity = null;
-        for (Map.Entry<Integer, Object[]> entry : fieldsMap.entrySet()) {
-          Object val = this.getCellValue(row, entry.getKey());
-
-          // 如果不存在实例则新建.
-          entity = (entity == null ? clazz.newInstance() : entity);
-          // 从map中得到对应列的field.
-          Field field = (Field) entry.getValue()[0];
-          Excel attr = (Excel) entry.getValue()[1];
-          // 取得类型,并根据对象类型设置值.
-          Class<?> fieldType = field.getType();
-          if (String.class == fieldType) {
-            String s = Convert.toStr(val);
-            if (StringUtils.endsWith(s, ".0")) {
-              val = StringUtils.substringBefore(s, ".0");
+    }
+    return list;
+  }
+
+  private void setBaseValue(T entity, Long fileId){
+    ReflectUtils.invokeSetter(entity, "delFlag", DelFlagEnum.NOT_DELETE.getCode());
+    ReflectUtils.invokeSetter(entity, "fileId", fileId);
+    ReflectUtils.invokeSetter(entity, "createTime", LocalDateTime.now());
+    ReflectUtils.invokeSetter(entity, "createBy", SecurityUtils.getUsername());
+  }
+
+  private Map<Integer, Object[]> getFieldsMap(Sheet sheet, int titleNum, int dataStartNum) {
+    // 定义一个map用于存放excel列的序号和field.
+    Map<Integer, String> cellMapTmp = new HashMap<>();
+    // 获取表头
+    for (int hRow = titleNum; hRow < dataStartNum; hRow++) {
+      Row heard = sheet.getRow(hRow);
+      for (int i = 0; i < heard.getPhysicalNumberOfCells(); i++) {
+        Cell cell = heard.getCell(i);
+        if (StringUtils.isNotNull(cell)) {
+          String value = this.getCellValue(heard, i).toString().replaceAll("\n", "");
+          if (cellMapTmp.containsKey(i)) {
+            if (StringUtils.isEmpty(value)) {
+              value = cellMapTmp.get(i);
             } else {
-              String dateFormat = field.getAnnotation(Excel.class).dateFormat();
-              if (StringUtils.isNotEmpty(dateFormat)) {
-                val = parseDateToStr(dateFormat, val);
-              } else {
-                val = Convert.toStr(val);
-              }
-            }
-          } else if ((Integer.TYPE == fieldType || Integer.class == fieldType)
-              && StringUtils.isNumeric(Convert.toStr(val))) {
-            val = Convert.toInt(val);
-          } else if ((Long.TYPE == fieldType || Long.class == fieldType) && StringUtils.isNumeric(
-              Convert.toStr(val))) {
-            val = Convert.toLong(val);
-          } else if (Double.TYPE == fieldType || Double.class == fieldType) {
-            val = Convert.toDouble(val);
-          } else if (Float.TYPE == fieldType || Float.class == fieldType) {
-            val = Convert.toFloat(val);
-          } else if (BigDecimal.class == fieldType) {
-            val = Convert.toBigDecimal(val);
-          } else if (Date.class == fieldType || LocalDate.class == fieldType) {
-            if (val instanceof String) {
-              String dateFormat = field.getAnnotation(Excel.class).dateFormat();
-              if (StringUtils.isNotEmpty(dateFormat) && dateFormat.equals("MMdd")) {
-                val = String.valueOf(LocalDate.now().getYear()) + val;
-              }
-              val = LocalDateUtil.parseDate(val);
-            } else if (val instanceof Double) {
-              val = DateUtil.getJavaDate((Double) val);
+              value = cellMapTmp.get(i).replaceAll("`", "") + value;
             }
-            if (null == val) {
-              val = getCellDateValue(row, entry.getKey());
-            }
-            if (LocalDate.class == fieldType) {
-              val = LocalDateUtil.parseLocalDate(val);
-            }
-          } else if (Boolean.TYPE == fieldType || Boolean.class == fieldType) {
-            val = Convert.toBool(val, false);
           }
-          String propertyName = field.getName();
-          if (StringUtils.isNotEmpty(attr.targetAttr())) {
-            propertyName = field.getName() + "." + attr.targetAttr();
-          } else if (StringUtils.isNotEmpty(attr.readConverterExp())) {
-            val = reverseByExp(Convert.toStr(val), attr.readConverterExp(), attr.separator());
-          } else if (StringUtils.isNotEmpty(attr.dictType())) {
-            val = reverseDictByExp(Convert.toStr(val), attr.dictType(), attr.separator());
-          } else if (!attr.handler().equals(ExcelHandlerAdapter.class)) {
-            val = dataFormatHandlerAdapter(val, attr);
-          } else if (ColumnType.IMAGE == attr.cellType() && StringUtils.isNotEmpty(pictures)) {
-            PictureData image = pictures.get(row.getRowNum() + "_" + entry.getKey());
-            if (image == null) {
-              val = "";
-            } else {
-              byte[] data = image.getData();
-              val = FileUtils.writeImportBytes(data);
-            }
+          if (StringUtils.isEmpty(value) && i > 0) {
+            value = cellMapTmp.get(i - 1) + "`";
           }
-          ReflectUtils.invokeSetter(entity, propertyName, val);
+          cellMapTmp.put(i, value);
         }
-        list.add(entity);
       }
     }
-    return list;
+    Map<String, Integer> cellMap = new HashMap<>();
+    for (Map.Entry<Integer, String> entry : cellMapTmp.entrySet()) {
+      if (cellMap.containsKey(entry.getValue())) {
+        continue;
+      }
+      cellMap.put(entry.getValue(), entry.getKey());
+    }
+    // 有数据时才处理 得到类的所有field.
+    List<Object[]> fields = this.getFields();
+    Map<Integer, Object[]> fieldsMap = new HashMap<>();
+    for (Object[] objects : fields) {
+      Excel attr = (Excel) objects[1];
+      Integer column = cellMap.get(attr.name());
+      if (column != null) {
+        fieldsMap.put(column, objects);
+      }
+    }
+    return fieldsMap;
+  }
+
+  private Object convert(Map.Entry<Integer, Object[]> entry, Field field, Row row) {
+    Object val = this.getCellValue(row, entry.getKey());
+    // 取得类型,并根据对象类型设置值.
+    Class<?> fieldType = field.getType();
+    if (String.class == fieldType) {
+      String s = Convert.toStr(val);
+      if (StringUtils.endsWith(s, ".0")) {
+        val = StringUtils.substringBefore(s, ".0");
+      } else {
+        String dateFormat = field.getAnnotation(Excel.class).dateFormat();
+        if (StringUtils.isNotEmpty(dateFormat)) {
+          val = parseDateToStr(dateFormat, val);
+        } else {
+          val = Convert.toStr(val);
+        }
+      }
+    } else if ((Integer.TYPE == fieldType || Integer.class == fieldType)
+        && StringUtils.isNumeric(Convert.toStr(val))) {
+      val = Convert.toInt(val);
+    } else if ((Long.TYPE == fieldType || Long.class == fieldType) && StringUtils.isNumeric(
+        Convert.toStr(val))) {
+      val = Convert.toLong(val);
+    } else if (Double.TYPE == fieldType || Double.class == fieldType) {
+      val = Convert.toDouble(val);
+    } else if (Float.TYPE == fieldType || Float.class == fieldType) {
+      val = Convert.toFloat(val);
+    } else if (BigDecimal.class == fieldType) {
+      val = Convert.toBigDecimal(val);
+    } else if (Date.class == fieldType || LocalDate.class == fieldType) {
+      if (val instanceof String) {
+        String dateFormat = field.getAnnotation(Excel.class).dateFormat();
+        if (StringUtils.isNotEmpty(dateFormat) && dateFormat.equals("MMdd")) {
+          val = String.valueOf(LocalDate.now().getYear()) + val;
+        }
+        val = LocalDateUtil.parseDate(val);
+      } else if (val instanceof Double) {
+        val = DateUtil.getJavaDate((Double) val);
+      }
+      if (null == val) {
+        val = getCellDateValue(row, entry.getKey());
+      }
+      if (LocalDate.class == fieldType) {
+        val = LocalDateUtil.parseLocalDate(val);
+      }
+    } else if (Boolean.TYPE == fieldType || Boolean.class == fieldType) {
+      val = Convert.toBool(val, false);
+    }
+
+    return val;
   }
 
   /**

+ 107 - 0
railway-framework/src/main/java/com/railway/framework/datasource/MybatisBatchUtils.java

@@ -0,0 +1,107 @@
+package com.railway.framework.datasource;
+
+import java.util.List;
+import java.util.function.BiConsumer;
+import java.util.function.BiFunction;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.ibatis.session.ExecutorType;
+import org.apache.ibatis.session.SqlSession;
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.transaction.support.TransactionSynchronizationManager;
+
+/**
+ * Mybatis批量操作
+ *
+ * @author zhaomn
+ */
+@Slf4j
+@Configuration
+public class MybatisBatchUtils {
+
+  private static final int BATCH_SIZE = 1000;
+
+  private final SqlSessionFactory sessionFactory;
+
+  public MybatisBatchUtils(SqlSessionFactory sessionFactory) {
+    this.sessionFactory = sessionFactory;
+  }
+
+  /**
+   * 批量新增方法
+   *
+   * @param data 要新增的集合
+   * @param mapperClass Mapper类
+   * @param function 对应的单条新增方法
+   * @param <M> mapper类型
+   * @param <T> 结合元素类型
+   * @param <R> 返回数据类型
+   * @return 数据插入结果
+   */
+  public <T, M, R> boolean batchUpdateOrInsert(List<T> data, Class<M> mapperClass,
+      BiFunction<T, M, R> function) {
+    if (data == null || data.size() == 0) {
+      log.info("batchInsert data data is null!");
+      return true;
+    }
+    int i = 1;
+    SqlSession sqlSession = sessionFactory.openSession(ExecutorType.BATCH);
+    try {
+      M mapper = sqlSession.getMapper(mapperClass);
+      int size = data.size();
+      for (T element : data) {
+        function.apply(element, mapper);
+        if ((i % BATCH_SIZE == 0) || i == size) {
+          sqlSession.flushStatements();
+        }
+        i++;
+      }
+      // 非事务环境下强制commit,事务情况下该commit相当于无效
+      sqlSession.commit(!TransactionSynchronizationManager.isSynchronizationActive());
+      return true;
+    } catch (Exception e) {
+      log.error("batchInsert is exception!mapperClass={}", mapperClass.getName(), e);
+      sqlSession.rollback();
+      throw new RuntimeException(e);
+    } finally {
+      sqlSession.close();
+    }
+  }
+
+  /**
+   * 批量新增方法
+   *
+   * @param data 要新增的集合
+   * @param mapperClass Mapper类
+   * @param consumer 对应的单条新增方法
+   * @param <M> mapper类型
+   * @param <T> 结合元素类型
+   */
+  public <M, T> void batchInsert(List<T> data, Class<M> mapperClass, BiConsumer<M, T> consumer) {
+    if (data == null || data.size() == 0) {
+      log.info("batchInsert data data is null!");
+      return;
+    }
+    SqlSession sqlSession = sessionFactory.openSession(ExecutorType.BATCH);
+    int i = 1;
+    int size = data.size();
+    try {
+      M mapper = sqlSession.getMapper(mapperClass);
+      for (T element : data) {
+        consumer.accept(mapper, element);
+        if ((i % BATCH_SIZE == 0) || i == size) {
+          sqlSession.commit();
+          sqlSession.clearCache();
+        }
+        i++;
+      }
+    } catch (Exception e) {
+      e.printStackTrace();
+      log.error("batchInsert is exception!mapperClass={}", mapperClass.getName(), e);
+      sqlSession.rollback();
+    } finally {
+      sqlSession.close();
+    }
+  }
+
+}