Quellcode durchsuchen

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

JammeyJiang vor 1 Monat
Ursprung
Commit
47ac9b7778
1 geänderte Dateien mit 125 neuen und 93 gelöschten Zeilen
  1. 125 93
      src/main/java/com/kcim/service/impl/KpiComputeImportServiceImpl.java

+ 125 - 93
src/main/java/com/kcim/service/impl/KpiComputeImportServiceImpl.java

@@ -24,7 +24,6 @@ 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.*;
 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
@@ -168,7 +167,7 @@ public class KpiComputeImportServiceImpl implements KpiComputeImportService {
             assert fileName != null;
             File file1 = new File(fileName);
             FileUtils.copyInputStreamToFile(file.getInputStream(), file1);
-            String excelSql = readExcelSql(file1, tableName, id);
+            String excelSql = readExcelSql(file1, tableName, id,computeDate);
             SqlRunner sqlRunner = new SqlRunner(getConnection());
             sqlRunner.insert(excelSql);
 
@@ -243,15 +242,15 @@ public class KpiComputeImportServiceImpl implements KpiComputeImportService {
 
     @Override
     @Transactional(rollbackFor = Throwable.class, propagation = Propagation.REQUIRED)
-    public List<SheetImportResultVO> importMultipleSheets(String computeDate,  MultipartFile file) {
+    public List<SheetImportResultVO> importMultipleSheets(String computeDate, MultipartFile file) {
+        List<CommonTitleVo> tableList = (List<CommonTitleVo>) getTableList();
         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);
@@ -297,7 +296,7 @@ public class KpiComputeImportServiceImpl implements KpiComputeImportService {
                         resultItem.setImportTime(kpiComputeImport.getCreateTime());
 
                     } catch (Exception e) {
-                        log.error("导入sheet页 '{}' 出错: {}", sheetName, e.getMessage(), e);
+                        log.error(String.format("sheet页 '{ %s}' 导入失败: %s", sheetName, e.getMessage()));
                         resultItem.setSuccess(false);
                         resultItem.setErrorMessage("导入失败: " + e.getMessage());
                     }
@@ -307,112 +306,141 @@ public class KpiComputeImportServiceImpl implements KpiComputeImportService {
             // 删除临时文件
             tempFile.delete();
         } catch (Exception e) {
-            throw new RuntimeException("导入发生异常", e);
+            throw new RuntimeException("导入发生异常" + e.getMessage());
         }
         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);
+        // 将MultipartFile转换为InputStream
+        InputStream inputStream = file.getInputStream();
 
-            // 执行SQL插入操作
-            SqlRunner sqlRunner = new SqlRunner(getConnection());
-            sqlRunner.insert(excelSql);
+        // 这里假设有一个方法可以从给定的InputStream和sheet对象中读取SQL语句
+        List<String> excelSql = readExcelSqlFromSheet(inputStream, sheet, tableName, id,computeDate);
 
-            // 更新新增人和时间
-            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);
+        // 执行SQL插入操作
+        SqlRunner sqlRunner = new SqlRunner(getConnection());
+        for (String sql : excelSql) {
+            sqlRunner.insert(sql);
         }
+
+        // 更新新增人和时间
+        String updateSql = "UPDATE `" + tableName + "` SET " +
+                "`create_user` = '" + UserContext.getCurrentUser().getId() + "', " +
+                "`create_time` = '" + DateUtils.formatDate2String(new Date()) + "' " +
+                "WHERE `import_id` = '"+id+"';";
+        sqlRunner.run(updateSql);
     }
 
-   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;
+    private static final int BATCH_SIZE = 500; // 每批次插入的记录数
+
+    private List<String> readExcelSqlFromSheet(InputStream inputStream, Sheet sheet, String tableName, Integer id, String computeDate) throws IOException {
+        List<String> sqlList = new ArrayList<>();
+        boolean firstRow = true;
+        Row headerRow = null;
+        DataFormatter dataFormatter = new DataFormatter();
+        int rowCount = 0;
+        boolean hasComputeDateField = false;
+
+        // 第一次遍历获取字段信息并判断是否有 compute_date 字段
+        for (Row row : sheet) {
+            if (rowCount == 0) {
+                headerRow = row;
+                // 检查字段中是否包含 compute_date
+                for (int i = 0; i < headerRow.getLastCellNum(); i++) {
+                    Cell headerCell = headerRow.getCell(i);
+                    if (headerCell != null && "compute_date".equals(headerCell.getStringCellValue())) {
+                        hasComputeDateField = true;
+                        break;
+                    }
+                }
+                rowCount++;
+                continue;
+            }
+            break; // 只需要读取第一行判断字段
         }
-        sqlBuilder.append("INSERT INTO `").append(tableName).append("` (");
 
-        // 构建字段名部分
-        for (int i = 0; i < headerRow.getLastCellNum(); i++) {
-            if (i > 0) {
-                sqlBuilder.append(", ");
+        // 第二次遍历处理数据行
+        StringBuilder currentBatchValues = new StringBuilder();
+        int batchCount = 0;
+        // 新增变量用于记录实际数据行数
+        int actualRowCount = 0;
+
+        for (Row row : sheet) {
+            if (actualRowCount < 2) {
+                actualRowCount++;
+                continue; // 跳过前两行(标题行 + 说明行)
             }
-            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(", ");
+            StringBuilder valueSb = new StringBuilder();
+            valueSb.append("(");
+
+            for (int i = 0; i < row.getLastCellNum(); i++) {
+                if (i > 0) {
+                    valueSb.append(", ");
+                }
+                Cell cell = row.getCell(i);
+                if (cell == null) {
+                    valueSb.append("NULL");
+                    continue;
+                }
+                cell.setCellType(CellType.STRING);
+                valueSb.append("'").append(cell.getStringCellValue().replace("'", "''")).append("'");
             }
-            Cell cell = row.getCell(i);
-            if (cell == null) {
-                sqlBuilder.append("NULL");
-                continue;
+
+            // 添加 import_id 和 hosp_id
+            valueSb.append(", ").append(id)
+                   .append(", ").append(UserContext.getCurrentLoginHospId());
+
+            // 如果字段中没有 compute_date,才手动添加
+            if (!hasComputeDateField) {
+                valueSb.append(", '").append(computeDate).append("'");
             }
 
-            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);
+            valueSb.append(")");
+
+            if (batchCount == 0) {
+                // 构建字段名部分
+                currentBatchValues.setLength(0); // 清空之前的缓存
+                currentBatchValues.append("INSERT INTO `").append(tableName).append("` (");
+
+                for (int i = 0; i < headerRow.getLastCellNum(); i++) {
+                    if (i > 0) {
+                        currentBatchValues.append(", ");
                     }
-                    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");
+                    Cell headerCell = headerRow.getCell(i);
+                    currentBatchValues.append("`").append(headerCell.getStringCellValue()).append("`");
+                }
+
+                currentBatchValues.append(", `import_id`, `hosp_id`");
+                if (!hasComputeDateField) {
+                    currentBatchValues.append(", `compute_date`");
+                }
+                currentBatchValues.append(") VALUES ");
+            } else {
+                currentBatchValues.append(", ");
             }
-        }
 
-        sqlBuilder.append(", ").append(id).append(");\n");
-        rowCount++;
-    }
+            currentBatchValues.append(valueSb.toString());
+            batchCount++;
 
-    return sqlBuilder.toString();
-}
+            // 如果达到批次大小,保存当前批次并重置
+            if (batchCount >= BATCH_SIZE) {
+                sqlList.add(currentBatchValues.toString());
+                batchCount = 0;
+            }
 
+            actualRowCount++; // 使用独立变量追踪实际行数
+        }
 
+        // 添加最后一批未满的数据
+        if (batchCount > 0) {
+            sqlList.add(currentBatchValues.toString());
+        }
+
+        return sqlList;
+    }
 
 
     /**
@@ -448,7 +476,7 @@ public class KpiComputeImportServiceImpl implements KpiComputeImportService {
         }
     }
 
-    public static String readExcelSql(File file, String tableName, Integer id) throws IOException {
+    public static String readExcelSql(File file, String tableName, Integer id, String computeDate) throws IOException {
         // 获取excel工作簿对象
         String sql = null;
         String fileName = file.getName();
@@ -490,7 +518,7 @@ public class KpiComputeImportServiceImpl implements KpiComputeImportService {
                     i++;
                 }
                 //组装记录表和hospId
-                setCommonData(id, dataList);
+                setCommonData(id, dataList,computeDate);
                 sql = insertFromMap(dataList, tableName);
 
             }
@@ -531,17 +559,21 @@ public class KpiComputeImportServiceImpl implements KpiComputeImportService {
                     }
                     i++;
                 }
-                setCommonData(id, dataList);
+                setCommonData(id, dataList,computeDate);
                 sql = insertFromMap(dataList, tableName);
             }
         }
         return sql;
     }
 
-    private static void setCommonData(Integer id, List<Map<String, Object>> dataList) {
+    private static void setCommonData(Integer id, List<Map<String, Object>> dataList, String computeDate) {
         if (!CollectionUtils.isEmpty(dataList)) {
             dataList.forEach(stringObjectMap -> {
                 stringObjectMap.put("hosp_id", UserContext.getCurrentLoginHospId());
+                //Excel字段里没有传核算年月的,用传入的核算年月
+                if(!stringObjectMap.containsKey("compute_date")) {
+                    stringObjectMap.put("compute_date", computeDate);
+                }
                 stringObjectMap.put("import_id", id);
             });
         }
@@ -643,5 +675,5 @@ public class KpiComputeImportServiceImpl implements KpiComputeImportService {
     private Connection getConnection() throws ClassNotFoundException, SQLException {
         Class.forName(driver);
         return DriverManager.getConnection(url, username, password);
-    }
+    }    
 }