|
@@ -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);
|
|
|
- }
|
|
|
+ }
|
|
|
}
|