// MountainFloodDataImporter.java package org.example; import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.File; import java.io.FileInputStream; import java.sql.Connection; import java.sql.PreparedStatement; import java.util.ArrayList; import java.util.List; import java.util.UUID; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * 表3 */ public class IaGlaInfoDataImporter { // IA_GLA_INFO表的插入SQL private static final String INSERT_SQL = "INSERT INTO SHZH_JCSJ.IA_GLA_INFO (" + "ADCD, ADNM, NAME, CD, LGTD, LTTD, TYPE, WIDTH, LENGTH, STYPE, " + "R2, RVNM, RVCD, REMARK, ISENABLE, IMPORTYEAR, INPUTTYPE, AUDID, STATUS, " + "SIGNER, CADCD, GUID, AUDBATCH, WSCD" + ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; public static void main(String[] args) { // 测试用的固定路径 // args = new String[]{"F:\\1111-湖工大50条成果-已通过初检-待入库"}; // args = new String[]{"F:\\3333-2024年度咸宁市8条20251017-已通过初检-待入库"}; // args = new String[]{"F:\\4444-长江科学院-黄冈28条-已通过初检-已统一表头-待入库"}; // args = new String[]{"F:\\小流域\\5555-长江科学院20条10.23-已通过初检-已统一表头-待入库\\5555-长江科学院20条10.23-已通过初检-已统一表头-待入库"}; args = new String[]{"F:\\04 小流域成果\\2024年度\\第二批次成果\\4444-长江科学院-黄冈28条1201-已通过初检-空间格式通过-已统一表头-待入库"}; if (args.length == 0) { System.out.println("请提供湖工大9.29目录路径作为参数"); return; } String baseDir = args[0]; File baseDirectory = new File(baseDir); if (!baseDirectory.exists() || !baseDirectory.isDirectory()) { System.out.println("指定的目录不存在或不是有效目录: " + baseDir); return; } System.out.println("开始处理目录: " + baseDir); try { processAllCounties(baseDirectory); } catch (Exception e) { System.err.println("处理过程中发生错误: " + e.getMessage()); e.printStackTrace(); } } private static void processAllCounties(File baseDir) { File[] countyDirs = baseDir.listFiles(File::isDirectory); if (countyDirs == null) { System.out.println("在基础目录下未找到任何县市文件夹"); return; } int totalProcessed = 0; int totalSuccess = 0; System.out.println("找到 " + countyDirs.length + " 个县市文件夹"); for (File countyDir : countyDirs) { String countyName = extractCountyName(countyDir.getName()); System.out.println("\n=== 处理县市: " + countyName + " ==="); try { int processed = processCountyData(countyDir, countyName); totalProcessed += processed; totalSuccess++; System.out.println("✓ 成功处理 " + countyName + ",导入 " + processed + " 条记录"); } catch (Exception e) { System.err.println("✗ 处理县市 " + countyName + " 时出错: " + e.getMessage()); } } System.out.println("\n=== 处理完成 ==="); System.out.println("成功处理县市: " + totalSuccess + " 个"); System.out.println("总导入记录: " + totalProcessed + " 条"); } private static int processCountyData(File countyDir, String countyName) throws Exception { int totalProcessed = 0; // 查找小流域目录 File watershedDir = findWatershedDirectory(countyDir); if (watershedDir == null) { System.out.println("在 " + countyName + " 下未找到小流域目录"); return 0; } System.out.println("找到小流域目录: " + watershedDir.getName()); // 查找所有水系目录 File[] sxDirs = findSxDirectories(watershedDir); if (sxDirs == null || sxDirs.length == 0) { System.out.println("在 " + watershedDir.getPath() + " 下未找到水系目录"); return 0; } System.out.println("找到 " + sxDirs.length + " 个水系文件夹:"); for (File sxDir : sxDirs) { System.out.println(" - " + sxDir.getName()); } // 遍历处理每个水系文件夹 for (File sxDir : sxDirs) { System.out.println("\n处理水系: " + sxDir.getName()); int processed = processSxData(sxDir, countyName); totalProcessed += processed; System.out.println("水系 " + sxDir.getName() + " 导入 " + processed + " 条记录"); } return totalProcessed; } private static File[] findSxDirectories(File watershedDir) { File[] subDirs = watershedDir.listFiles(File::isDirectory); if (subDirs != null) { List sxDirs = new ArrayList<>(); for (File subDir : subDirs) { if (subDir.getName().contains("水系") || subDir.getName().matches("^HBW.*")) { sxDirs.add(subDir); } } return sxDirs.toArray(new File[0]); } return null; } private static int processSxData(File sxDir, String countyName) throws Exception { int processedCount = 0; // 查找成果报表目录 File reportDir = findReportDirectory(sxDir); if (reportDir == null) { System.out.println("在 " + sxDir.getPath() + " 下未找到成果报表目录"); return 0; } System.out.println("找到成果报表目录: " + reportDir.getPath()); // 查找Excel文件 File excelFile = findExcelFile(reportDir); if (excelFile == null) { System.out.println("在 " + reportDir.getPath() + " 下未找到表3沟滩占地情况调查成果表.xlsx"); return 0; } System.out.println("找到Excel文件: " + excelFile.getPath()); // 提取流域编码 String watershedCode = extractWatershedCode(sxDir.getName()); System.out.println("流域编码: " + watershedCode); // 读取Excel文件并导入数据库 processedCount = readExcelAndImport(excelFile, countyName, watershedCode); return processedCount; } private static File findWatershedDirectory(File countyDir) { File[] subDirs = countyDir.listFiles(File::isDirectory); if (subDirs != null) { for (File subDir : subDirs) { if (subDir.getName().contains("小流域")) { return subDir; } } if (subDirs.length > 0) return subDirs[0]; } return null; } private static File findReportDirectory(File sxDir) { File[] subDirs = sxDir.listFiles(File::isDirectory); if (subDirs != null) { for (File subDir : subDirs) { if (subDir.getName().contains("成果报表")) { return subDir; } } if (subDirs.length > 0) return subDirs[0]; } return null; } private static File findExcelFile(File reportDir) { File[] files = reportDir.listFiles((dir, name) -> name.equals("表3沟滩占地情况调查成果表.xlsx") || name.toLowerCase().endsWith(".xlsx")); if (files != null && files.length > 0) { for (File file : files) { if (file.getName().equals("表3沟滩占地情况调查成果表.xlsx")) { return file; } } return files[0]; } return null; } private static String extractCountyName(String dirName) { return dirName.contains("、") ? dirName.split("、")[1].trim() : dirName; } private static String extractWatershedCode(String dirName) { Pattern pattern = Pattern.compile("^[a-zA-Z0-9]+"); Matcher matcher = pattern.matcher(dirName); if(matcher.find()){ return matcher.group(); }else{ System.out.println("小流域编码文件夹有问题: " + dirName); } return dirName; } private static int readExcelAndImport(File excelFile, String countyName, String watershedCode) throws Exception { int importedCount = 0; // 先读取所有数据到内存 List dataList = readExcelData(excelFile, countyName, watershedCode); if (dataList.isEmpty()) { System.out.println("未读取到有效数据"); return 0; } System.out.println("成功读取 " + dataList.size() + " 条数据,开始导入数据库..."); // 批量导入数据库 importedCount = batchInsertData(dataList); return importedCount; } private static List readExcelData(File excelFile, String countyName, String watershedCode) throws Exception { List dataList = new ArrayList<>(); try (FileInputStream fis = new FileInputStream(excelFile); Workbook workbook = new XSSFWorkbook(fis)) { // 遍历所有工作表 for (int sheetIndex = 0; sheetIndex < workbook.getNumberOfSheets(); sheetIndex++) { Sheet sheet = workbook.getSheetAt(sheetIndex); String sheetName = sheet.getSheetName(); // 跳过填表说明等非数据工作表 if (sheetName.contains("填表说明") || sheetName.contains("说明")) { continue; } System.out.println("处理工作表: " + sheetName); // 提取县代码(从第二行) String countyCode = extractCountyCode(sheet); String adcd = extractAdcd(sheet); String adnm = extractAdnm(sheet); int startRow = findDataStartRow(sheet); if (startRow == -1) { System.out.println("在工作表 " + sheetName + " 中未找到数据开始行"); return dataList; } System.out.println("数据从第 " + (startRow + 1) + " 行开始,共 " + (sheet.getLastRowNum() - startRow + 1) + " 行"); for (int i = startRow; i <= sheet.getLastRowNum(); i++) { Row row = sheet.getRow(i); if (row == null) continue; Cell serialCell = row.getCell(0); if (serialCell == null || isCellEmpty(serialCell)) { continue; } Object[] rowData = parseRowData(row, countyName, watershedCode, countyCode,adcd,adnm); if (rowData != null) { dataList.add(rowData); System.out.println("✓ 解析第 " + (i + 1) + " 行数据成功"); } else { System.out.println("✗ 解析第 " + (i + 1) + " 行数据失败"); } } } } return dataList; } private static String extractCountyCode(Sheet sheet) { // 从第二行提取县代码 Row headerRow = sheet.getRow(1); if (headerRow != null) { Cell codeCell = headerRow.getCell(7); // H列 - 县代码 if (codeCell != null) { return getCellStringValue(codeCell); } } return ""; // 默认值 } private static String extractAdcd(Sheet sheet) { // 从第二行提取乡镇代码 Row headerRow = sheet.getRow(1); if (headerRow != null) { Cell codeCell = headerRow.getCell(12); // H列 - 乡镇代码 if (codeCell != null) { return getCellStringValue(codeCell); } } return ""; // 默认值 } private static String extractAdnm(Sheet sheet) { // 从第二行提取乡镇代码 Row headerRow = sheet.getRow(1); if (headerRow != null) { Cell codeCell = headerRow.getCell(10); // H列 - 乡镇代码 if (codeCell != null) { return getCellStringValue(codeCell); } } return ""; // 默认值 } private static int findDataStartRow(Sheet sheet) { // 查找数据开始的行(序号列开始有数据的行) for (int i = 0; i <= sheet.getLastRowNum(); i++) { Row row = sheet.getRow(i); if (row != null) { Cell cell = row.getCell(0); // A列 if (cell != null && !isCellEmpty(cell)) { // 检查是否是数字序号 if (cell.getCellType() == CellType.NUMERIC) { double value = cell.getNumericCellValue(); if (value >= 1 && value <= 1000) { return i; } } else if (cell.getCellType() == CellType.STRING) { String value = cell.getStringCellValue().trim(); if (value.matches("\\d+")) { return i; } } } } } return -1; } private static Object[] parseRowData(Row row, String countyName, String watershedCode, String countyCode,String adcd ,String adnm) { try { // 检查编码(C列)是否为空 String name = getCellStringValue(row.getCell(1)); if (name == null || name.trim().isEmpty() || "无".equals(name)) { System.out.println("第 " + (row.getRowNum() + 1) + " 行编码为空,跳过该行"); return null; } Object[] data = new Object[24]; // 对应24个参数 int index = 0; // ADCD - 行政区划代码 data[index++] = adcd; // ADNM - 行政区划名称 data[index++] = adnm; // NAME - 名称 (B列) data[index++] = name; // CD - 编号 (C列) data[index++] = getCellStringValue(row.getCell(2)); // LGTD - 经度 (D列) String lngStr = getCellStringValue(row.getCell(3)); data[index++] = parseDecimal(lngStr); // LTTD - 纬度 (E列) String latStr = getCellStringValue(row.getCell(4)); data[index++] = parseDecimal(latStr); // TYPE - 类型 (F列) data[index++] = getCellStringValue(row.getCell(5)); // WIDTH - 沟宽/m (G列) String widthStr = getCellStringValue(row.getCell(6)); data[index++] = parseDecimal(widthStr); // LENGTH - 沟深/m (H列) String depthStr = getCellStringValue(row.getCell(7)); data[index++] = parseDecimal(depthStr); // STYPE - 断面形态 (I列) data[index++] = getCellStringValue(row.getCell(8)); // R2 - 阻水面积比/% (J列) String r2Str = getCellStringValue(row.getCell(9)); data[index++] = parseDecimal(r2Str); // RVNM - 河流名称 (K列) data[index++] = getCellStringValue(row.getCell(10)); // RVCD - 河流代码 (L列) data[index++] = getCellStringValue(row.getCell(11)); // REMARK - 备注 (M列) data[index++] = getCellStringValue(row.getCell(12)); // 固定值字段 data[index++] = "1"; // ISENABLE data[index++] = "2025"; // IMPORTYEAR data[index++] = "1"; // INPUTTYPE data[index++] = null; // AUDID data[index++] = "1"; // STATUS data[index++] = null; // SIGNER data[index++] = countyCode; // CADCD // GUID - 唯一标识 data[index++] = UUID.randomUUID().toString(); // AUDBATCH data[index++] = "BATCH_" + System.currentTimeMillis(); // WSCD - 流域编码 data[index++] = watershedCode; return data; } catch (Exception e) { System.err.println("解析行数据失败: " + e.getMessage()); return null; } } private static int batchInsertData(List dataList) { int importedCount = 0; try (Connection conn = DatabaseUtil.getConnection(); PreparedStatement pstmt = conn.prepareStatement(INSERT_SQL)) { conn.setAutoCommit(false); // 开启事务 for (Object[] rowData : dataList) { try { for (int i = 0; i < rowData.length; i++) { pstmt.setObject(i + 1, rowData[i]); } pstmt.addBatch(); importedCount++; // 每10条执行一次批量插入 if (importedCount % 10 == 0) { pstmt.executeBatch(); System.out.println("已批量插入 " + importedCount + " 条记录"); } } catch (Exception e) { System.err.println("单条数据插入失败: " + e.getMessage()); // 继续处理下一条数据 } } // 执行剩余的批量插入 if (importedCount % 10 != 0) { pstmt.executeBatch(); } conn.commit(); // 提交事务 System.out.println("成功导入 " + importedCount + " 条记录到数据库"); } catch (Exception e) { System.err.println("批量插入数据失败: " + e.getMessage()); e.printStackTrace(); } return importedCount; } private static String getCellStringValue(Cell cell) { if (cell == null) { return null; } try { switch (cell.getCellType()) { case STRING: return cell.getStringCellValue().trim(); case NUMERIC: if (DateUtil.isCellDateFormatted(cell)) { return cell.getDateCellValue().toString(); } else { double num = cell.getNumericCellValue(); if (num == (long) num) { return String.valueOf((long) num); } else { return String.valueOf(num); } } case BOOLEAN: return String.valueOf(cell.getBooleanCellValue()); case FORMULA: try { return cell.getStringCellValue(); } catch (Exception e) { try { return String.valueOf(cell.getNumericCellValue()); } catch (Exception e2) { return cell.getCellFormula(); } } default: return null; } } catch (Exception e) { System.err.println("读取单元格值时出错: " + e.getMessage()); return null; } } private static Double parseDecimal(String value) { if (value == null || value.trim().isEmpty()) { return null; } try { return Double.parseDouble(value.trim()); } catch (NumberFormatException e) { return null; } } private static boolean isCellEmpty(Cell cell) { if (cell == null) return true; switch (cell.getCellType()) { case BLANK: return true; case STRING: return cell.getStringCellValue().trim().isEmpty(); default: return false; } } }