Parcourir la source

添加一个Excel的多个sheet页导入功能

JammeyJiang il y a 1 mois
Parent
commit
bb04d4185d

+ 11 - 0
src/main/java/com/kcim/service/KpiComputeImportService.java

@@ -1,7 +1,10 @@
 package com.kcim.service;
 
+import com.kcim.vo.SheetImportResultVO;
 import org.springframework.web.multipart.MultipartFile;
 
+import java.util.List;
+
 /**
  * @program: CostAccount
  * @description:
@@ -41,4 +44,12 @@ public interface KpiComputeImportService {
      * @param id 记录id
      */
     void recoverImport(Integer id);
+
+    /**
+     * 批量导入数据
+     * @param computeDate 核算年月
+     * @param file 导入文件
+     * @return 导入结果列表
+     */
+    List<SheetImportResultVO> importMultipleSheets(String computeDate, MultipartFile file);
 }

+ 179 - 4
src/main/java/com/kcim/service/impl/KpiComputeImportServiceImpl.java

@@ -18,15 +18,15 @@ import com.kcim.service.CenterService;
 import com.kcim.service.KpiComputeImportService;
 import com.kcim.vo.CommonTitleVo;
 import com.kcim.vo.DictDataVo;
+import com.kcim.vo.SheetImportResultVO;
 import com.kcim.vo.UserInfoVO;
+import lombok.SneakyThrows;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.io.FileUtils;
 import org.apache.ibatis.jdbc.SqlRunner;
+import org.apache.poi.hssf.usermodel.HSSFDateUtil;
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
-import org.apache.poi.ss.usermodel.Cell;
-import org.apache.poi.ss.usermodel.CellType;
-import org.apache.poi.ss.usermodel.Row;
-import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.*;
 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
@@ -240,6 +240,181 @@ public class KpiComputeImportServiceImpl implements KpiComputeImportService {
         }
     }
 
+
+    @Override
+    @Transactional(rollbackFor = Throwable.class, propagation = Propagation.REQUIRED)
+    public List<SheetImportResultVO> importMultipleSheets(String computeDate,  MultipartFile file) {
+        String fileName = file.getOriginalFilename();
+        String uploadFileUrl = uploadFile(file, fileName);
+        List<SheetImportResultVO> sheetResults = new ArrayList<>();
+
+        try {
+            File tempFile = File.createTempFile("excel-", ".tmp");
+            file.transferTo(tempFile);
+            List<CommonTitleVo> tableList = (List<CommonTitleVo>) getTableList();
+            try (Workbook workbook = WorkbookFactory.create(tempFile)) {
+                for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
+                    Sheet sheet = workbook.getSheetAt(i);
+                    String sheetName = sheet.getSheetName();
+
+                    SheetImportResultVO resultItem = new SheetImportResultVO();
+                    resultItem.setSheetName(sheetName);
+                    resultItem.setSheetIndex(i);
+
+                    Optional<CommonTitleVo> mapping = tableList.stream()
+                            .filter(t -> t.getName().equals(sheetName))
+                            .findFirst();
+
+                    if (!mapping.isPresent()) {
+                        log.warn("未找到sheet页 '{}' 对应的数据表配置,跳过导入", sheetName);
+                        resultItem.setSuccess(false);
+                        resultItem.setErrorMessage("未找到对应的数据库表配置");
+                        sheetResults.add(resultItem);
+                        continue;
+                    }
+
+                    String tableName = mapping.get().getCode();
+                    resultItem.setTableName(tableName);
+
+                    try {
+                        KpiComputeImport kpiComputeImport = new KpiComputeImport();
+                        kpiComputeImport.setComputeDate(computeDate);
+                        kpiComputeImport.setImportStatus(NumberConstant.ZERO);
+                        kpiComputeImport.setCreateTime(new Date());
+                        kpiComputeImport.setCreateUser(String.valueOf(UserContext.getCurrentUser().getId()));
+                        kpiComputeImport.setUrl(uploadFileUrl);
+                        kpiComputeImport.setTableName(tableName);
+                        kpiComputeImport.setFileName(String.format("%s_%s", fileName, sheetName));
+                        kpiComputeImport.setHospId(UserContext.getCurrentLoginHospId());
+                        kpiComputeImport.setDelFlag(NumberConstant.ZERO);
+
+                        repository.save(kpiComputeImport);
+
+                        insertExcelDataForSheet(kpiComputeImport.getId(), tableName, file, fileName, computeDate, sheet);
+
+                        resultItem.setSuccess(true);
+                        resultItem.setImportId(kpiComputeImport.getId());
+                        resultItem.setImportTime(kpiComputeImport.getCreateTime());
+
+                    } catch (Exception e) {
+                        log.error("导入sheet页 '{}' 出错: {}", sheetName, e.getMessage(), e);
+                        resultItem.setSuccess(false);
+                        resultItem.setErrorMessage("导入失败: " + e.getMessage());
+                    }
+                    sheetResults.add(resultItem);
+                }
+            }
+            // 删除临时文件
+            tempFile.delete();
+        } catch (Exception e) {
+            throw new RuntimeException("导入发生异常", e);
+        }
+        return sheetResults;
+    }
+
+    @SneakyThrows
+    private void insertExcelDataForSheet(Integer id, String tableName, MultipartFile file, String fileName, String computeDate, Sheet sheet) {
+        try {
+            // 将MultipartFile转换为InputStream
+            InputStream inputStream = file.getInputStream();
+
+            // 这里假设有一个方法可以从给定的InputStream和sheet对象中读取SQL语句
+            String excelSql = readExcelSqlFromSheet(inputStream, sheet, tableName, id);
+
+            // 执行SQL插入操作
+            SqlRunner sqlRunner = new SqlRunner(getConnection());
+            sqlRunner.insert(excelSql);
+
+            // 更新新增人和时间
+            String updateSql = "UPDATE `" + tableName + "` SET " +
+                    "`create_user` = '" + UserContext.getCurrentUser().getId() + "', " +
+                    "`create_time` = '" + DateUtils.formatDate2String(new Date()) + "' " +
+                    "WHERE `compute_date` = '" + computeDate + "' AND `hosp_id` = " + UserContext.getCurrentLoginHospId() + ";";
+            sqlRunner.run(updateSql);
+        } catch (IOException | SQLException e) {
+            // 记录日志而不是抛出异常,以避免中断其他sheet页的处理
+            log.error("Error inserting data for sheet: {}", sheet.getSheetName(), e);
+        }
+    }
+
+   private String readExcelSqlFromSheet(InputStream inputStream, Sheet sheet, String tableName, Integer id) throws IOException {
+    StringBuilder sqlBuilder = new StringBuilder();
+    boolean firstRow = true;
+    Row headerRow = null;
+    DataFormatter dataFormatter = new DataFormatter();
+    int rowCount = 0;
+    for (Row row : sheet) {
+        // 第一行作为标题行
+        if (rowCount == 0) {
+            headerRow = row;
+            rowCount++;
+            continue;
+        }
+        if (rowCount == 1) {
+            // 第二行为说明行,跳过
+            rowCount++;
+            continue;
+        }
+        sqlBuilder.append("INSERT INTO `").append(tableName).append("` (");
+
+        // 构建字段名部分
+        for (int i = 0; i < headerRow.getLastCellNum(); i++) {
+            if (i > 0) {
+                sqlBuilder.append(", ");
+            }
+            Cell headerCell = headerRow.getCell(i);
+            sqlBuilder.append("`").append(headerCell.getStringCellValue()).append("`");
+        }
+
+        sqlBuilder.append(", `import_id`) VALUES (");
+        // 构建值部分
+        for (int i = 0; i < row.getLastCellNum(); i++) {
+            if (i > 0) {
+                sqlBuilder.append(", ");
+            }
+            Cell cell = row.getCell(i);
+            if (cell == null) {
+                sqlBuilder.append("NULL");
+                continue;
+            }
+
+            switch (cell.getCellType()) {
+                case STRING:
+                    sqlBuilder.append("'").append(cell.getStringCellValue()).append("'");
+                    break;
+                case NUMERIC:
+                    String formattedValue = dataFormatter.formatCellValue(cell);
+                    // 判断是否是日期类型
+                    if (HSSFDateUtil.isCellDateFormatted(cell)) {
+                        sqlBuilder.append("'").append(cell.getDateCellValue()).append("'");
+                    } else {
+                        sqlBuilder.append(formattedValue);
+                    }
+                    break;
+                case BOOLEAN:
+                    sqlBuilder.append(cell.getBooleanCellValue() ? 1 : 0);
+                    break;
+                case FORMULA:
+                    sqlBuilder.append("'").append(cell.getCellFormula()).append("'");
+                    break;
+                case BLANK:
+                    sqlBuilder.append("NULL");
+                    break;
+                default:
+                    sqlBuilder.append("NULL");
+            }
+        }
+
+        sqlBuilder.append(", ").append(id).append(");\n");
+        rowCount++;
+    }
+
+    return sqlBuilder.toString();
+}
+
+
+
+
     /**
      * 复原导入数据
      *

+ 19 - 0
src/main/java/com/kcim/vo/SheetImportResultVO.java

@@ -0,0 +1,19 @@
+package com.kcim.vo;
+
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * 每个sheet页导入结果VO
+ */
+@Data
+public class SheetImportResultVO {
+    private String sheetName;
+    private Integer sheetIndex;
+    private String tableName;
+    private Integer importId;
+    private Date importTime;
+    private Boolean success;
+    private String errorMessage;
+}

+ 11 - 0
src/main/java/com/kcim/web/PublicImportController.java

@@ -2,6 +2,7 @@ package com.kcim.web;
 
 import com.kcim.common.util.Result;
 import com.kcim.service.KpiComputeImportService;
+import com.kcim.vo.SheetImportResultVO;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.AllArgsConstructor;
@@ -9,6 +10,8 @@ import lombok.extern.slf4j.Slf4j;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 
+import java.util.List;
+
 /**
  * @program: CostAccount
  * @description:
@@ -61,4 +64,12 @@ public class PublicImportController {
         service.recoverImport(id);
         return Result.ok();
     }
+
+    @ApiOperation("批量导入数据")
+    @PostMapping("importMultipleSheets")
+    public Result importMultipleSheets(@RequestPart("computeDate")String computeDate,
+                             @RequestPart("file") MultipartFile file){
+        List<SheetImportResultVO> sheetImportResultVOS = service.importMultipleSheets(computeDate, file);
+        return Result.ok(sheetImportResultVOS);
+    }
 }