master
wany 2025-10-29 15:31:28 +08:00
commit 8698ce1568
18 changed files with 8521 additions and 0 deletions

View File

@ -0,0 +1,19 @@
package org.example;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class CommonUtils {
public 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;
}
}

View File

@ -0,0 +1,40 @@
package org.example;// DatabaseConfig.java
import java.io.InputStream;
import java.util.Properties;
public class DatabaseConfig {
private static final Properties props = new Properties();
static {
try (InputStream input = DatabaseConfig.class.getClassLoader()
.getResourceAsStream("database.properties")) {
if (input == null) {
// 使用默认配置
props.setProperty("db.url", "jdbc:dm://10.0.41.113:5236/SHZH_JCSJ");
props.setProperty("db.username", "SYSDBA");
props.setProperty("db.password", "SYSDBA001");
props.setProperty("db.driver", "dm.jdbc.driver.DmDriver");
} else {
props.load(input);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static String getUrl() {
return props.getProperty("db.url");
}
public static String getUsername() {
return props.getProperty("db.username");
}
public static String getPassword() {
return props.getProperty("db.password");
}
public static String getDriver() {
return props.getProperty("db.driver");
}
}

View File

@ -0,0 +1,48 @@
// DatabaseTest.java
package org.example;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class DatabaseTest {
public static void main(String[] args) {
testConnection();
}
public static void testConnection() {
String[] urls = {
// "jdbc:dm://localhost:5236/SHZH_JCSJ",
// "jdbc:dm://127.0.0.1:5236/SHZH_JCSJ",
"jdbc:dm://10.0.41.113:5236/SHZH_JCSJ"
};
String username = "SYSDBA";
String password = "SYSDBA001";
for (String url : urls) {
System.out.println("测试连接: " + url);
try {
Class.forName("dm.jdbc.driver.DmDriver");
Connection conn = DriverManager.getConnection(url, username, password);
// 测试简单查询
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT 1 FROM DUAL");
if (rs.next()) {
System.out.println("✓ 连接成功: " + url);
}
rs.close();
stmt.close();
conn.close();
return; // 成功则退出
} catch (Exception e) {
System.err.println("✗ 连接失败: " + url + " - " + e.getMessage());
}
}
}
}

View File

@ -0,0 +1,51 @@
// DatabaseUtil.java
package org.example;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class DatabaseUtil {
// 达梦数据库配置
// private static final String DB_URL = "jdbc:dm://10.0.41.113:5236/SHZH_JCSJ";
// private static final String DB_USERNAME = "SYSDBA";
// private static final String DB_PASSWORD = "SYSDBA001";
private static final String DB_URL = "jdbc:dm://10.42.6.248:5236/SHZH_JCSJ";
private static final String DB_USERNAME = "SHZH";
private static final String DB_PASSWORD = "Shzh_890";
private static final String DB_DRIVER = "dm.jdbc.driver.DmDriver";
static {
try {
Class.forName(DB_DRIVER);
System.out.println("达梦数据库驱动加载成功");
} catch (ClassNotFoundException e) {
throw new RuntimeException("加载数据库驱动失败", e);
}
}
public static Connection getConnection() throws SQLException {
try {
Connection conn = DriverManager.getConnection(DB_URL, DB_USERNAME, DB_PASSWORD);
System.out.println("数据库连接成功");
return conn;
} catch (SQLException e) {
System.err.println("数据库连接失败: " + e.getMessage());
throw e;
}
}
public static void close(Connection conn, PreparedStatement pstmt, ResultSet rs) {
try {
if (rs != null) rs.close();
if (pstmt != null) pstmt.close();
if (conn != null) conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,194 @@
// MountainFloodDataImporter.java
package org.example;
import java.io.File;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;
public class GetWscdDataImporter {
public static void main(String[] args) {
// 先测试数据库连接
if (!testDatabaseConnection()) {
System.err.println("数据库连接测试失败,程序退出");
return;
}
// 测试用的固定路径
args = new String[]{"I:\\6666-华科26个流域1023-已统一表头-待入库"};
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 boolean testDatabaseConnection() {
try {
Connection conn = DatabaseUtil.getConnection();
if (conn != null && !conn.isClosed()) {
System.out.println("✓ 数据库连接测试成功");
conn.close();
return true;
}
} catch (Exception e) {
System.err.println("✗ 数据库连接测试失败: " + e.getMessage());
}
return false;
}
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;
int totalDuplicates = 0;
System.out.println("找到 " + countyDirs.length + " 个县市文件夹");
List<String> res = new ArrayList<>();
for (File countyDir : countyDirs) {
String countyName = extractCountyName(countyDir.getName());
System.out.println("\n=== 处理县市: " + countyName + " ===");
try {
// 获取该县市下所有小流域编码
List<String> watershedCodes = getWatershedCodesForCounty(countyDir);
System.out.println("在 " + countyName + " 下找到 " + watershedCodes.size() + " 个小流域编码:");
for (String code : watershedCodes) {
System.out.println(" - " + code);
}
res.addAll(watershedCodes);
totalSuccess++;
} catch (Exception e) {
System.err.println("✗ 处理县市 " + countyName + " 时出错: " + e.getMessage());
e.printStackTrace();
}
}
System.out.println("\n=== 处理完成 ===");
System.out.println("成功处理县市: " + totalSuccess + " 个");
System.out.println("总找到小流域编码: " + totalProcessed + " 个");
String s = "";
for (String code : res) {
s += "'"+code+"',\n";
}
System.out.println(s);
}
/**
*
*/
private static List<String> getWatershedCodesForCounty(File countyDir) {
List<String> watershedCodes = new ArrayList<>();
// 查找小流域目录
File watershedDir = findWatershedDirectory(countyDir);
if (watershedDir == null) {
System.out.println("在 " + countyDir.getName() + " 下未找到小流域目录");
return watershedCodes;
}
System.out.println("找到小流域目录: " + watershedDir.getName());
// 查找所有水系目录
File[] sxDirs = findSxDirectories(watershedDir);
if (sxDirs == null || sxDirs.length == 0) {
System.out.println("在 " + watershedDir.getPath() + " 下未找到水系目录");
return watershedCodes;
}
System.out.println("找到 " + sxDirs.length + " 个水系文件夹:");
// 遍历处理每个水系文件夹,提取小流域编码
for (File sxDir : sxDirs) {
String watershedCode = CommonUtils.extractWatershedCode(sxDir.getName());
if (watershedCode != null && !watershedCode.isEmpty()) {
watershedCodes.add(watershedCode);
System.out.println(" - " + sxDir.getName() + " -> 编码: " + watershedCode);
}
}
return watershedCodes;
}
/**
*
*/
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[] findSxDirectories(File watershedDir) {
File[] subDirs = watershedDir.listFiles(File::isDirectory);
if (subDirs != null) {
List<File> sxDirs = new ArrayList<>();
for (File subDir : subDirs) {
String dirName = subDir.getName();
// 包含"水系"或者以HBWFF开头的文件夹都认为是水系文件夹
if (dirName.contains("水系") || dirName.startsWith("HBWF")) {
sxDirs.add(subDir);
}
}
return sxDirs.toArray(new File[0]);
}
return null;
}
/**
*
*/
private static String extractCountyName(String dirName) {
if (dirName.contains("、")) {
String[] parts = dirName.split("、");
return parts.length > 1 ? parts[1].trim() : parts[0].trim();
}
return dirName;
}
// 处理结果类
private static class ProcessResult {
int processed;
int duplicates;
ProcessResult(int processed, int duplicates) {
this.processed = processed;
this.duplicates = duplicates;
}
}
}

View File

@ -0,0 +1,646 @@
// MountainFloodEftsImporter.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.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 4
*/
public class IaEftsTownImporter {
// 外洪顶托集镇及村落调查分析成果表插入SQL
private static final String INSERT_EFTS_TOWN_SQL =
"INSERT INTO SHZH_JCSJ.IA_EFTS_TOWN (" +
"PCD, PNM, TM50, CRP50, NCRP50, TM100, CRP100, NCRP100, REMARK, ISENABLE, " +
"IMPORTYEAR, ADCD, INPUTTYPE, AUDID, STATUS, SIGNER, CADCD, GUID, AUDBATCH, WSCD" +
") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
// 检查重复的SQL
private static final String CHECK_EFTS_DUPLICATE_SQL =
"SELECT COUNT(*) FROM SHZH_JCSJ.IA_EFTS_TOWN " +
"WHERE PCD = ? AND TM50 = ? AND TM100 = ?";
public static void main(String[] args) {
// 先测试数据库连接
if (!testDatabaseConnection()) {
System.err.println("数据库连接测试失败,程序退出");
return;
}
// 测试用的固定路径
// args = new String[]{"F:\\1111-湖工大50条成果-已通过初检-待入库"};
// args = new String[]{"F:\\3333-2024年度咸宁市8条20251017-已通过初检-待入库"};
// args = new String[]{"F:\\2222-华科-黄石局-14条小流域10.20-已通过初检-已统一表头-待入库"};
args = new String[]{"F:\\小流域\\5555-长江科学院20条10.23-已通过初检-已统一表头-待入库\\5555-长江科学院20条10.23-已通过初检-已统一表头-待入库"};
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 {
processAllEftsTables(baseDirectory);
} catch (Exception e) {
System.err.println("处理过程中发生错误: " + e.getMessage());
e.printStackTrace();
}
}
private static boolean testDatabaseConnection() {
try {
Connection conn = DatabaseUtil.getConnection();
if (conn != null && !conn.isClosed()) {
System.out.println("✓ 数据库连接测试成功");
conn.close();
return true;
}
} catch (Exception e) {
System.err.println("✗ 数据库连接测试失败: " + e.getMessage());
}
return false;
}
private static void processAllEftsTables(File baseDir) {
File[] countyDirs = baseDir.listFiles(File::isDirectory);
if (countyDirs == null) {
System.out.println("在基础目录下未找到任何县市文件夹");
return;
}
int totalProcessed = 0;
int totalSuccess = 0;
int totalDuplicates = 0;
int totalSkipped = 0;
System.out.println("开始处理外洪顶托集镇及村落调查分析成果表...");
System.out.println("找到 " + countyDirs.length + " 个县市文件夹");
for (File countyDir : countyDirs) {
String countyName = extractCountyName(countyDir.getName());
System.out.println("\n=== 处理县市: " + countyName + " ===");
try {
ProcessResult result = processCountyEftsData(countyDir, countyName);
totalProcessed += result.processed;
totalDuplicates += result.duplicates;
totalSkipped += result.skipped;
totalSuccess++;
System.out.println("✓ 成功处理 " + countyName +
",导入 " + result.processed + " 条记录,跳过 " + result.duplicates +
" 条重复记录," + result.skipped + " 条因E列为空跳过");
} catch (Exception e) {
System.err.println("✗ 处理县市 " + countyName + " 时出错: " + e.getMessage());
e.printStackTrace();
}
}
System.out.println("\n=== 外洪顶托集镇及村落调查分析成果表处理完成 ===");
System.out.println("成功处理县市: " + totalSuccess + " 个");
System.out.println("总导入记录: " + totalProcessed + " 条");
System.out.println("总跳过重复记录: " + totalDuplicates + " 条");
System.out.println("总因E列为空跳过记录: " + totalSkipped + " 条");
}
private static ProcessResult processCountyEftsData(File countyDir, String countyName) throws Exception {
int totalProcessed = 0;
int totalDuplicates = 0;
int totalSkipped = 0;
// 查找小流域目录
File watershedDir = findWatershedDirectory(countyDir);
if (watershedDir == null) {
System.out.println("在 " + countyName + " 下未找到小流域目录");
return new ProcessResult(0, 0, 0);
}
System.out.println("找到小流域目录: " + watershedDir.getName());
// 查找所有水系目录
File[] sxDirs = findSxDirectories(watershedDir);
if (sxDirs == null || sxDirs.length == 0) {
System.out.println("在 " + watershedDir.getPath() + " 下未找到水系目录");
return new ProcessResult(0, 0, 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());
ProcessResult result = processSxEftsData(sxDir, countyName);
totalProcessed += result.processed;
totalDuplicates += result.duplicates;
totalSkipped += result.skipped;
System.out.println("水系 " + sxDir.getName() + " 导入 " + result.processed + " 条记录,跳过 " +
result.duplicates + " 条重复记录," + result.skipped + " 条因E列为空跳过");
}
return new ProcessResult(totalProcessed, totalDuplicates, totalSkipped);
}
private static ProcessResult processSxEftsData(File sxDir, String countyName) throws Exception {
int processedCount = 0;
int duplicateCount = 0;
int skippedCount = 0;
// 查找成果报表目录
File reportDir = findReportDirectory(sxDir);
if (reportDir == null) {
System.out.println("在 " + sxDir.getPath() + " 下未找到成果报表目录");
return new ProcessResult(0, 0, 0);
}
System.out.println("找到成果报表目录: " + reportDir.getPath());
// 查找Excel文件
File excelFile = findEftsExcelFile(reportDir);
if (excelFile == null) {
System.out.println("在 " + reportDir.getPath() + " 下未找到表4外洪顶托集镇及村落调查分析成果表.xlsx");
return new ProcessResult(0, 0, 0);
}
System.out.println("找到外洪顶托集镇及村落调查分析成果表: " + excelFile.getPath());
// 提取流域编码
String watershedCode = CommonUtils.extractWatershedCode(sxDir.getName());
System.out.println("流域编码: " + watershedCode);
// 读取Excel文件并导入数据库
ProcessResult result = readEftsExcelAndImport(excelFile, countyName, watershedCode);
return result;
}
private static ProcessResult readEftsExcelAndImport(File excelFile, String countyName, String watershedCode) throws Exception {
int importedCount = 0;
int duplicateCount = 0;
int skippedCount = 0;
// 读取所有数据到内存
List<Object[]> eftsDataList = readEftsExcelData(excelFile, countyName, watershedCode);
if (eftsDataList.isEmpty()) {
System.out.println("未读取到有效数据");
return new ProcessResult(0, 0, 0);
}
System.out.println("成功读取 " + eftsDataList.size() + " 条数据,开始导入数据库...");
// 批量导入数据库
ProcessResult result = batchInsertEftsData(eftsDataList);
return result;
}
private static List<Object[]> readEftsExcelData(File excelFile, String countyName, String watershedCode) throws Exception {
List<Object[]> 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();
System.out.println("处理工作表: " + sheetName);
// 提取县代码和乡镇代码
String countyCode = extractCountyCode(sheet);
String townCode = extractTownCode(sheet);
String townName = extractTownName(sheet);
System.out.println("县代码: " + countyCode + ", 乡镇代码: " + townCode + ", 乡镇名称: " + townName);
int startRow = findEftsDataStartRow(sheet);
if (startRow == -1) {
System.out.println("在工作表 " + sheetName + " 中未找到数据开始行");
continue;
}
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;
}
// 检查E列是否为空如果为空则跳过
Cell eColumnCell = row.getCell(4); // E列是索引4
if (eColumnCell == null || isCellEmpty(eColumnCell)) {
System.out.println("跳过第 " + (i + 1) + " 行E列为空");
continue;
}
Object[] eftsData = parseEftsRowData(row, countyName, watershedCode, countyCode, townCode, townName);
if (eftsData != null) {
dataList.add(eftsData);
System.out.println("✓ 解析第 " + (i + 1) + " 行数据成功");
} else {
System.out.println("✗ 解析第 " + (i + 1) + " 行数据失败");
}
}
}
} catch (Exception e) {
System.err.println("读取Excel文件失败: " + e.getMessage());
throw e;
}
return dataList;
}
private static String extractCountyCode(Sheet sheet) {
// 从第二行提取县代码 (F列)
Row headerRow = sheet.getRow(1);
if (headerRow != null) {
Cell codeCell = headerRow.getCell(5); // F列是索引5
if (codeCell != null) {
return getCellStringValue(codeCell);
}
}
return "";
}
private static String extractTownCode(Sheet sheet) {
// 从第二行提取乡镇代码 (I列)
Row headerRow = sheet.getRow(1);
if (headerRow != null) {
Cell codeCell = headerRow.getCell(9); // I列是索引9
if (codeCell != null) {
return getCellStringValue(codeCell);
}
}
return "";
}
private static String extractTownName(Sheet sheet) {
// 从第二行提取乡镇名称 (G列)
Row headerRow = sheet.getRow(1);
if (headerRow != null) {
Cell nameCell = headerRow.getCell(7); // G列是索引7
if (nameCell != null) {
return getCellStringValue(nameCell);
}
}
return "";
}
private static int findEftsDataStartRow(Sheet sheet) {
for (int i = 0; i <= sheet.getLastRowNum(); i++) {
Row row = sheet.getRow(i);
if (row != null) {
Cell cell = row.getCell(0);
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[] parseEftsRowData(Row row, String countyName, String watershedCode,
String countyCode, String townCode, String townName) {
try {
Object[] data = new Object[20]; // 对应20个参数
int index = 0;
// PCD - 防治对象代码 (C列)
String pcd = getCellStringValue(row.getCell(2));
if (pcd == null || pcd.trim().isEmpty()) {
return null; // 防治对象编码为空,跳过
}
data[index++] = pcd;
// PNM - 防治对象名称 (B列)
data[index++] = getCellStringValue(row.getCell(1));
// TM50 - 50年一遇时段 (D列)
data[index++] = getCellStringValue(row.getCell(3));
// CRP50 - 50年一遇原临界雨量 (E列)
String crp50Str = getCellStringValue(row.getCell(4));
if (crp50Str != null && !crp50Str.trim().isEmpty()) {
try {
data[index++] = Double.parseDouble(crp50Str.trim());
} catch (NumberFormatException e) {
System.err.println("50年一遇原临界雨量格式错误: " + crp50Str);
data[index++] = null;
}
} else {
data[index++] = null;
}
// NCRP50 - 50年一遇修正后临界雨量 (F列)
String ncrp50Str = getCellStringValue(row.getCell(5));
if (ncrp50Str != null && !ncrp50Str.trim().isEmpty()) {
try {
data[index++] = Double.parseDouble(ncrp50Str.trim());
} catch (NumberFormatException e) {
System.err.println("50年一遇修正后临界雨量格式错误: " + ncrp50Str);
data[index++] = null;
}
} else {
data[index++] = null;
}
// TM100 - 100年一遇时段 (G列)
data[index++] = getCellStringValue(row.getCell(6));
// CRP100 - 100年一遇原临界雨量 (H列)
String crp100Str = getCellStringValue(row.getCell(7));
if (crp100Str != null && !crp100Str.trim().isEmpty()) {
try {
data[index++] = Double.parseDouble(crp100Str.trim());
} catch (NumberFormatException e) {
System.err.println("100年一遇原临界雨量格式错误: " + crp100Str);
data[index++] = null;
}
} else {
data[index++] = null;
}
// NCRP100 - 100年一遇修正后临界雨量 (I列)
String ncrp100Str = getCellStringValue(row.getCell(8));
if (ncrp100Str != null && !ncrp100Str.trim().isEmpty()) {
try {
data[index++] = Double.parseDouble(ncrp100Str.trim());
} catch (NumberFormatException e) {
System.err.println("100年一遇修正后临界雨量格式错误: " + ncrp100Str);
data[index++] = null;
}
} else {
data[index++] = null;
}
// REMARK - 备注 (J列)
data[index++] = getCellStringValue(row.getCell(9));
// 固定值字段
data[index++] = "1"; // ISENABLE
data[index++] = "2025"; // IMPORTYEAR
data[index++] = townCode; // ADCD - 乡镇代码
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_EFTS_" + System.currentTimeMillis();
// WSCD - 流域编码
data[index++] = watershedCode;
return data;
} catch (Exception e) {
System.err.println("解析外洪顶托数据失败: " + e.getMessage());
e.printStackTrace();
return null;
}
}
private static ProcessResult batchInsertEftsData(List<Object[]> eftsDataList) {
int importedCount = 0;
int duplicateCount = 0;
int skippedCount = 0;
try (Connection conn = DatabaseUtil.getConnection();
PreparedStatement eftsPstmt = conn.prepareStatement(INSERT_EFTS_TOWN_SQL);
PreparedStatement checkEftsDupPstmt = conn.prepareStatement(CHECK_EFTS_DUPLICATE_SQL)) {
conn.setAutoCommit(false); // 开启事务
// 使用Set来跟踪已处理的数据避免内存中重复
Set<String> processedEftsKeys = new HashSet<>();
for (Object[] rowData : eftsDataList) {
try {
// 检查是否重复
String pcd = (String) rowData[0]; // PCD在索引0
String tm50 = (String) rowData[2]; // TM50在索引2
String tm100 = (String) rowData[5]; // TM100在索引5
// 检查必要字段是否为空
if (pcd == null || tm50 == null || tm100 == null) {
System.out.println("跳过数据不完整的记录: PCD=" + pcd);
skippedCount++;
continue;
}
// 生成唯一键,先检查内存中是否已处理
String eftsKey = pcd + "|" + tm50 + "|" + tm100;
if (processedEftsKeys.contains(eftsKey)) {
duplicateCount++;
System.out.println("跳过内存中重复记录: " + pcd + " - " + tm50 + "/" + tm100);
continue;
}
// 检查数据库中是否已存在
checkEftsDupPstmt.setString(1, pcd);
checkEftsDupPstmt.setString(2, tm50);
checkEftsDupPstmt.setString(3, tm100);
try (ResultSet rs = checkEftsDupPstmt.executeQuery()) {
if (rs.next() && rs.getInt(1) > 0) {
duplicateCount++;
System.out.println("跳过数据库中重复记录: " + pcd + " - " + tm50 + "/" + tm100);
continue;
}
}
// 插入数据
for (int i = 0; i < rowData.length; i++) {
eftsPstmt.setObject(i + 1, rowData[i]);
}
eftsPstmt.addBatch();
importedCount++;
processedEftsKeys.add(eftsKey);
// 每10条执行一次批量插入
if (importedCount % 10 == 0) {
eftsPstmt.executeBatch();
System.out.println("已批量插入 " + importedCount + " 条记录到外洪顶托表");
}
} catch (Exception e) {
System.err.println("单条数据插入失败: " + e.getMessage());
e.printStackTrace();
}
}
// 执行剩余的批量插入
if (importedCount > 0) {
eftsPstmt.executeBatch();
System.out.println("最终批量插入完成,共 " + importedCount + " 条记录到外洪顶托表");
}
conn.commit(); // 提交事务
System.out.println("外洪顶托表事务提交成功");
} catch (Exception e) {
System.err.println("批量插入外洪顶托表数据失败: " + e.getMessage());
e.printStackTrace();
}
return new ProcessResult(importedCount, duplicateCount, skippedCount);
}
// 辅助方法
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[] findSxDirectories(File watershedDir) {
File[] subDirs = watershedDir.listFiles(File::isDirectory);
if (subDirs != null) {
List<File> sxDirs = new ArrayList<>();
for (File subDir : subDirs) {
if (subDir.getName().contains("水系") || subDir.getName().matches("^HBWFF.*")) {
sxDirs.add(subDir);
}
}
return sxDirs.toArray(new File[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 findEftsExcelFile(File reportDir) {
File[] files = reportDir.listFiles((dir, name) ->
name.equals("表4外洪顶托集镇及村落调查分析成果表.xlsx") ||
name.contains("外洪顶托") ||
name.toLowerCase().endsWith(".xlsx"));
if (files != null && files.length > 0) {
for (File file : files) {
if (file.getName().equals("表4外洪顶托集镇及村落调查分析成果表.xlsx")) {
return file;
}
}
for (File file : files) {
if (file.getName().contains("外洪顶托")) {
return file;
}
}
return files[0];
}
return null;
}
private static String extractCountyName(String dirName) {
return dirName.contains("、") ? dirName.split("、")[1].trim() : dirName;
}
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();
return (num == (long) num) ? String.valueOf((long) num) : 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 null;
}
}
default:
return null;
}
} catch (Exception 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;
}
}
// 处理结果类
private static class ProcessResult {
int processed;
int duplicates;
int skipped;
ProcessResult(int processed, int duplicates, int skipped) {
this.processed = processed;
this.duplicates = duplicates;
this.skipped = skipped;
}
}
}

View File

@ -0,0 +1,548 @@
// 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[]{"I:\\7777-华科-咸宁市8条1027-已通过初检-已统一表头-已入库"};
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<File> sxDirs = new ArrayList<>();
for (File subDir : subDirs) {
if (subDir.getName().contains("水系") || subDir.getName().matches("^HBWF.*")) {
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<Object[]> 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<Object[]> readExcelData(File excelFile, String countyName, String watershedCode) throws Exception {
List<Object[]> 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(2));
if (name == null || name.trim().isEmpty()) {
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<Object[]> 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;
}
}
}

View File

@ -0,0 +1,613 @@
// 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;
/**
* 5,6,7
*/
public class IaHdpPointDataImporter {
public final static String five = "表5 重点防治对象危险地建房详查成果表.xlsx";
public final static String three = "3";
public final static String six = "表6 重点防治对象房屋结构问题详查成果表.xlsx";
public final static String two = "2";
public final static String seven = "表7 重点防治对象弱势人群详查成果表.xlsx";
// IA_SHZH_HDP_POINT表的插入SQL
private static final String INSERT_SQL =
"INSERT INTO SHZH_JCSJ.IA_SHZH_HDP_POINT (" +
"ADCD, PCD, LGTD, LTTD, GC, PCOUNT, NAME, PHONE, BBZRRNM, BBZRRPHONE, " +
"PPOINT, REMARK, ISENABLE, IMPORTYEAR, INPUTTYPE, AUDID, STATUS, SIGNER, " +
"CADCD, GUID, AUDBATCH, WSCD, TYPE, PNM" +
") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
public static void main(String[] args) {
// 测试用的固定路径
// args = new String[]{"F:\\1111-湖工大50条成果-已通过初检-已入库"};
// args = new String[]{"F:\\2222-华科-黄石局-14条小流域10.20-已通过初检-已统一表头-已入库"};
// args = new String[]{"F:\\3333-华科-地大9条-20251021-已通过初检-已统一表头-已入库"};
// args = new String[]{"F:\\4444-长江科学院-黄冈28条-已通过初检-已统一表头-待入库"};
args = new String[]{"I:\\8888-长科院-孝昌县8条1028-已通过初检-已统一表头-待入库"};
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<File> sxDirs = new ArrayList<>();
for (File subDir : subDirs) {
if (subDir.getName().contains("水系") || subDir.getName().matches("^HBWF.*")) {
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() + " 下未找到" + six);
return 0;
}
System.out.println("找到Excel文件: " + excelFile.getPath());
// 提取流域编码
String watershedCode = CommonUtils.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(six) || name.toLowerCase().endsWith(".xlsx"));
if (files != null && files.length > 0) {
for (File file : files) {
if (file.getName().equals(six)) {
return file;
}
}
return files[0];
}
return null;
}
private static String extractCountyName(String dirName) {
return dirName.contains("、") ? dirName.split("、")[1].trim() : dirName;
}
private static int readExcelAndImport(File excelFile, String countyName, String watershedCode) throws Exception {
int importedCount = 0;
// 先读取所有数据到内存
List<Object[]> 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<Object[]> readExcelData(File excelFile, String countyName, String watershedCode) throws Exception {
List<Object[]> 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 ("填表说明".equals(sheetName)) {
System.out.println("跳过填表说明工作表");
continue;
}
System.out.println("处理工作表: " + sheetName);
int startRow = findDataStartRow(sheet);
if (startRow == -1) {
System.out.println("在工作表 " + sheetName + " 中未找到数据开始行");
continue;
}
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(8);
if (serialCell == null || isCellEmpty(serialCell)) {
continue;
}
Object[] rowData = parseRowData(row,countyName, watershedCode);
if (rowData != null) {
dataList.add(rowData);
System.out.println("✓ 解析第 " + (i + 1) + " 行数据成功");
} else {
System.out.println("✗ 解析第 " + (i + 1) + " 行数据失败");
}
}
}
}
return dataList;
}
private static int findDataStartRow(Sheet sheet) {
// 查找数据开始的行
for (int i = 2; i <= sheet.getLastRowNum(); i++) {
Row row = sheet.getRow(i);
if (row != null) {
Cell cell = row.getCell(8);
if (cell != null && !isCellEmpty(cell)) {
return i;
// // 检查是否是数字序号
// 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[] parseRowData1(Row row, String countyName, String watershedCode) {
try {
// 检查姓名(B列)是否为空
String name = getCellStringValue(row.getCell(1));
if (name == null || name.trim().isEmpty()) {
System.out.println("第 " + (row.getRowNum() + 1) + " 行姓名为空,跳过该行");
return null;
}
Object[] data = new Object[24]; // 对应24个参数
int index = 0;
// ADCD - 行政区划代码 (使用防治对象代码的前6位作为县级代码)
String preventionCode = getCellStringValue(row.getCell(5)); // I列 - 防治对象代码
String countyCode = (preventionCode != null && preventionCode.length() >= 6) ?
preventionCode.substring(0, 9) + "000000" : "";
data[index++] = countyCode;
// PCD - 防治对象代码 (I列)
data[index++] = preventionCode;
// LGTD - 住房经度(°) (E列)
String lngStr = getCellStringValue(row.getCell(6));
data[index++] = parseDecimal(lngStr);
// LTTD - 住房纬度(°) (F列)
String latStr = getCellStringValue(row.getCell(7));
data[index++] = parseDecimal(latStr);
// GC - 宅基地高程(m) (G列)
String elevationStr = getCellStringValue(row.getCell(8));
data[index++] = parseDecimal(elevationStr);
// PCOUNT - 常住人口 (D列)
String populationStr = getCellStringValue(row.getCell(3));
if (populationStr != null && !populationStr.trim().isEmpty()) {
try {
data[index++] = Integer.parseInt(populationStr.trim());
} catch (NumberFormatException e) {
data[index++] = null;
}
} else {
data[index++] = null;
}
// NAME - 姓名 (B列)
data[index++] = name;
// PHONE - 联系方式 (C列)
data[index++] = getCellStringValue(row.getCell(2));
// BBZRRNM - 包保责任人姓名 (暂无数据设为null)
data[index++] = getCellStringValue(row.getCell(9));
// BBZRRPHONE - 包保责任人电话 (暂无数据设为null)
data[index++] = getCellStringValue(row.getCell(10));
// PPOINT - 安置点 (暂无数据设为null)
data[index++] = null;
// REMARK - 备注 (J列)
data[index++] = getCellStringValue(row.getCell(11));
// 固定值字段
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 - 县级编码(前6位)
data[index++] = null;
// GUID - 唯一标识
data[index++] = UUID.randomUUID().toString();
// AUDBATCH
data[index++] = "BATCH_" + System.currentTimeMillis();
// WSCD - 流域编码
data[index++] = watershedCode;
// TYPE - 重点关注对象类型 (3:危险地建房)
data[index++] = "1";
// PNM - 防治对象名称 (H列)
data[index++] = getCellStringValue(row.getCell(4));
return data;
} catch (Exception e) {
System.err.println("解析行数据失败: " + e.getMessage());
return null;
}
}
private static Object[] parseRowData(Row row,String countyName, String watershedCode) {
try {
// 检查姓名(B列)是否为空
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 - 行政区划代码 (使用防治对象代码的前6位作为县级代码)
String preventionCode = getCellStringValue(row.getCell(8)); // I列 - 防治对象代码
String countyCode = (preventionCode != null && preventionCode.length() >= 6) ?
preventionCode.substring(0, 9) + "000000" : "";
data[index++] = countyCode;
// PCD - 防治对象代码 (I列)
data[index++] = preventionCode;
// LGTD - 住房经度(°) (E列)
String lngStr = getCellStringValue(row.getCell(4));
data[index++] = parseDecimal(lngStr);
// LTTD - 住房纬度(°) (F列)
String latStr = getCellStringValue(row.getCell(5));
data[index++] = parseDecimal(latStr);
// GC - 宅基地高程(m) (G列)
String elevationStr = getCellStringValue(row.getCell(6));
data[index++] = parseDecimal(elevationStr);
// PCOUNT - 常住人口 (D列)
String populationStr = getCellStringValue(row.getCell(3));
if (populationStr != null && !populationStr.trim().isEmpty()) {
try {
data[index++] = Integer.parseInt(populationStr.trim());
} catch (NumberFormatException e) {
data[index++] = null;
}
} else {
data[index++] = null;
}
// NAME - 姓名 (B列)
data[index++] = name;
// PHONE - 联系方式 (C列)
data[index++] = getCellStringValue(row.getCell(2));
// BBZRRNM - 包保责任人姓名 (暂无数据设为null)
data[index++] = null;
// BBZRRPHONE - 包保责任人电话 (暂无数据设为null)
data[index++] = null;
// PPOINT - 安置点 (暂无数据设为null)
data[index++] = null;
// REMARK - 备注 (J列)
data[index++] = getCellStringValue(row.getCell(9));
// 固定值字段
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++] = null;
// GUID - 唯一标识
data[index++] = UUID.randomUUID().toString();
// AUDBATCH
data[index++] = "BATCH_" + System.currentTimeMillis();
// WSCD - 流域编码
data[index++] = watershedCode;
// TYPE - 重点关注对象类型 (3:危险地建房)
data[index++] = two;
// PNM - 防治对象名称 (H列)
data[index++] = getCellStringValue(row.getCell(7));
return data;
} catch (Exception e) {
System.err.println("解析行数据失败: " + e.getMessage());
return null;
}
}
private static int batchInsertData(List<Object[]> 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;
}
}
}

View File

@ -0,0 +1,546 @@
// 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;
/**
* 2
*/
public class IaRbadInfoDataImporter {
// IA_RBAD_INFO表的插入SQL
private static final String INSERT_SQL =
"INSERT INTO SHZH_JCSJ.IA_RBAD_INFO (" +
"ADCD, NAME, LGTD, LTTD, TYPE, WIDTH, LENGTH, STYPE, R1, V, " +
"RVCD, YSNM, YSCD, KJNM, KJCD, REMARK, ISENABLE, IMPORTYEAR, CD, 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:\\3333-华科-地大9条-20251021-已通过初检-已统一表头-待入库"};
// args = new String[]{"F:\\小流域\\5555-长江科学院20条10.23-已通过初检-已统一表头-待入库\\5555-长江科学院20条10.23-已通过初检-已统一表头-待入库"};
args = new String[]{"I:\\8888-长科院-孝昌县8条1028-已通过初检-已统一表头-待入库"};
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<File> sxDirs = new ArrayList<>();
for (File subDir : subDirs) {
if (subDir.getName().contains("水系") || subDir.getName().matches("^HBWF.*")) {
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() + " 下未找到表2跨沟道路、桥涵、塘坝调查成果表.xlsx");
return 0;
}
System.out.println("找到Excel文件: " + excelFile.getPath());
// 提取流域编码
String watershedCode = CommonUtils.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("表2跨沟道路、桥涵、塘坝调查成果表.xlsx") || name.toLowerCase().endsWith(".xlsx"));
if (files != null && files.length > 0) {
for (File file : files) {
if (file.getName().equals("表2跨沟道路、桥涵、塘坝调查成果表.xlsx")) {
return file;
}
}
return files[0];
}
return null;
}
private static String extractCountyName(String dirName) {
return dirName.contains("、") ? dirName.split("、")[1].trim() : dirName;
}
private static int readExcelAndImport(File excelFile, String countyName, String watershedCode) throws Exception {
int importedCount = 0;
// 先读取所有数据到内存
List<Object[]> 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<Object[]> readExcelData(File excelFile, String countyName, String watershedCode) throws Exception {
List<Object[]> 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 + " 中未找到数据开始行");
continue;
}
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(15); // 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 {
// 检查名称(B列)是否为空
String name = getCellStringValue(row.getCell(1));
if (name == null || name.trim().isEmpty()) {
System.out.println("第 " + (row.getRowNum() + 1) + " 行名称为空,跳过该行");
return null;
}
Object[] data = new Object[27]; // 对应27个参数
int index = 0;
// ADCD - 行政区划代码
data[index++] = adcd;
// NAME - 名称 (B列)
data[index++] = name;
// 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));
// R1 - 阻水面积比R1/% (J列)
data[index++] = getCellStringValue(row.getCell(9));
// V - 阻水库容V/万m3 (K列)
data[index++] = getCellStringValue(row.getCell(10));
// RVCD - 河流代码 (L列)
data[index++] = getCellStringValue(row.getCell(11));
// YSNM - 壅水影响对象名称 (M列)
data[index++] = getCellStringValue(row.getCell(12));
// YSCD - 壅水影响对象编码 (N列)
data[index++] = getCellStringValue(row.getCell(13));
// KJNM - 溃决影响对象名称 (O列)
data[index++] = getCellStringValue(row.getCell(14));
// KJCD - 溃决影响对象编码 (P列)
data[index++] = getCellStringValue(row.getCell(15));
// REMARK - 备注 (Q列)
data[index++] = getCellStringValue(row.getCell(16));
// 固定值字段
data[index++] = "1"; // ISENABLE
data[index++] = "2025"; // IMPORTYEAR
data[index++] = getCellStringValue(row.getCell(2)); // CD - 编码 (C列)
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<Object[]> 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;
}
}
}

View File

@ -0,0 +1,726 @@
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.sql.ResultSet;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 1
*/
public class IaShzhHdpDataImporter {
// 防灾对象表插入SQL
private static final String INSERT_HDP_SQL =
"INSERT INTO SHZH_JCSJ.IA_SHZH_HDP(ADCD, ADNM, TYPE, PCOUNT, RVNM, RVCD, BRNAME, BRCD, " +
"DAMNAME, DAMCD, DZRVNM, DZRVCD, ISSZ, ISJW, ISDW, ISGT, ISYS, ISDT, ISGD, ISML, " +
"REMARK, ISENABLE, IMPORTYEAR, ISKJ, PRENAME, PRECODE, ISLHHP, ISNSL, SIGNER, CADCD, " +
"GUID, AUDBATCH, INPUTTYPE, AUDID, STATUS, WSCD) \n" +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, " +
"?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?)";
// 防灾对象河流信息表插入SQL
private static final String INSERT_RV_INFO_SQL =
"INSERT INTO SHZH_JCSJ.IA_RV_INFO (" +
"PRECODE, PRENAME, RVCD, RVNM, WSCD" +
") VALUES (?, ?, ?, ?, ?)";
// 检查防灾对象重复的SQL基于县编码、名称、编码、类型、人口
private static final String CHECK_HDP_DUPLICATE_SQL =
"SELECT COUNT(*) FROM SHZH_JCSJ.IA_SHZH_HDP " +
"WHERE ADCD = ? AND PRENAME = ? AND PRECODE = ? AND TYPE = ? AND " +
"(PCOUNT = ? OR (PCOUNT IS NULL AND ? IS NULL))";
// 检查河流信息重复的SQL基于precode, prename, rvcd, rvnm, wscd
private static final String CHECK_RV_INFO_DUPLICATE_SQL =
"SELECT COUNT(*) FROM SHZH_JCSJ.IA_RV_INFO " +
"WHERE PRECODE = ? AND PRENAME = ? AND RVCD = ? AND RVNM = ? AND WSCD = ?";
public static void main(String[] args) {
// 先测试数据库连接
if (!testDatabaseConnection()) {
System.err.println("数据库连接测试失败,程序退出");
return;
}
// 测试用的固定路径
// args = new String[]{"F:\\1111-湖工大50条成果-已通过初检-待入库"};
// args = new String[]{"F:\\3333-2024年度咸宁市8条20251017-已通过初检-待入库"};
// args = new String[]{"F:\\4444-长江科学院-黄冈28条-已通过初检-已统一表头-待入库"};
// args = new String[]{"F:\\3333-华科-地大9条-20251021-已通过初检-已统一表头-待入库"};
// args = new String[]{"F:\\小流域\\5555-长江科学院20条10.23-已通过初检-已统一表头-待入库\\5555-长江科学院20条10.23-已通过初检-已统一表头-待入库"};
args = new String[]{"I:\\8888-长科院-孝昌县8条1028-已通过初检-已统一表头-待入库"};
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 boolean testDatabaseConnection() {
try {
Connection conn = DatabaseUtil.getConnection();
if (conn != null && !conn.isClosed()) {
System.out.println("✓ 数据库连接测试成功");
conn.close();
return true;
}
} catch (Exception e) {
System.err.println("✗ 数据库连接测试失败: " + e.getMessage());
}
return false;
}
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;
int totalDuplicates = 0;
int totalRvDuplicates = 0;
System.out.println("找到 " + countyDirs.length + " 个县市文件夹");
for (File countyDir : countyDirs) {
String countyName = extractCountyName(countyDir.getName());
System.out.println("\n=== 处理县市: " + countyName + " ===");
try {
ProcessResult result = processCountyData(countyDir, countyName);
totalProcessed += result.processed;
totalDuplicates += result.duplicates;
totalRvDuplicates += result.rvDuplicates;
totalSuccess++;
System.out.println("✓ 成功处理 " + countyName +
",导入 " + result.processed + " 条记录,跳过 " + result.duplicates +
" 条重复记录,河流信息表跳过 " + result.rvDuplicates + " 条重复记录");
} catch (Exception e) {
System.err.println("✗ 处理县市 " + countyName + " 时出错: " + e.getMessage());
}
}
System.out.println("\n=== 处理完成 ===");
System.out.println("成功处理县市: " + totalSuccess + " 个");
System.out.println("总导入记录: " + totalProcessed + " 条");
System.out.println("防灾对象表跳过重复记录: " + totalDuplicates + " 条");
System.out.println("河流信息表跳过重复记录: " + totalRvDuplicates + " 条");
}
private static ProcessResult processCountyData(File countyDir, String countyName) throws Exception {
int totalProcessed = 0;
int totalDuplicates = 0;
int totalRvDuplicates = 0;
// 查找小流域目录
File watershedDir = findWatershedDirectory(countyDir);
if (watershedDir == null) {
System.out.println("在 " + countyName + " 下未找到小流域目录");
return new ProcessResult(0, 0, 0);
}
System.out.println("找到小流域目录: " + watershedDir.getName());
// 查找所有水系目录
File[] sxDirs = findSxDirectories(watershedDir);
if (sxDirs == null || sxDirs.length == 0) {
System.out.println("在 " + watershedDir.getPath() + " 下未找到水系目录");
return new ProcessResult(0, 0, 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());
ProcessResult result = processSxData(sxDir, countyName);
totalProcessed += result.processed;
totalDuplicates += result.duplicates;
totalRvDuplicates += result.rvDuplicates;
System.out.println("水系 " + sxDir.getName() + " 导入 " + result.processed + " 条记录,跳过 " +
result.duplicates + " 条重复记录,河流信息表跳过 " + result.rvDuplicates + " 条重复记录");
}
return new ProcessResult(totalProcessed, totalDuplicates, totalRvDuplicates);
}
private static ProcessResult processSxData(File sxDir, String countyName) throws Exception {
int processedCount = 0;
int duplicateCount = 0;
int rvDuplicateCount = 0;
// 查找成果报表目录
File reportDir = findReportDirectory(sxDir);
if (reportDir == null) {
System.out.println("在 " + sxDir.getPath() + " 下未找到成果报表目录");
return new ProcessResult(0, 0, 0);
}
System.out.println("找到成果报表目录: " + reportDir.getPath());
// 查找Excel文件
File excelFile = findExcelFile(reportDir);
if (excelFile == null) {
System.out.println("在 " + reportDir.getPath() + " 下未找到表1山洪灾害防治对象名录.xlsx");
return new ProcessResult(0, 0, 0);
}
System.out.println("找到Excel文件: " + excelFile.getPath());
// 提取流域编码
String watershedCode = CommonUtils.extractWatershedCode(sxDir.getName());
System.out.println("流域编码: " + watershedCode);
// 读取Excel文件并导入数据库
ProcessResult result = readExcelAndImport(excelFile, countyName, watershedCode);
return result;
}
private static ProcessResult readExcelAndImport(File excelFile, String countyName, String watershedCode) throws Exception {
int importedCount = 0;
int duplicateCount = 0;
int rvDuplicateCount = 0;
// 先读取所有数据到内存
List<Object[]> hdpDataList = new ArrayList<>();
List<Object[]> rvInfoDataList = new ArrayList<>();
readExcelData(excelFile, countyName, watershedCode, hdpDataList, rvInfoDataList);
if (hdpDataList.isEmpty()) {
System.out.println("未读取到有效数据");
return new ProcessResult(0, 0, 0);
}
System.out.println("成功读取 " + hdpDataList.size() + " 条数据,开始导入数据库...");
// 批量导入数据库
ProcessResult result = batchInsertData(hdpDataList, rvInfoDataList);
return result;
}
private static String extractCountyCode(Sheet sheet) {
// 从第二行提取县代码
Row headerRow = sheet.getRow(1);
if (headerRow != null) {
Cell codeCell = headerRow.getCell(9); // 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(22); // 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(14); // H列 - 乡镇名称
if (codeCell != null) {
return getCellStringValue(codeCell);
}
}
return ""; // 默认值
}
private static void readExcelData(File excelFile, String countyName, String watershedCode,
List<Object[]> hdpDataList, List<Object[]> rvInfoDataList) throws Exception {
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().replaceAll("[\\u4e00-\\u9fa5]+$", "");
// 跳过填表说明等非数据工作表
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("未找到数据开始行");
return;
}
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[] hdpData = parseRowData(row, countyName, watershedCode, countyCode, adcd, adnm);
if (hdpData != null) {
hdpDataList.add(hdpData);
// 同时生成河流信息表数据
Object[] rvInfoData = parseRvInfoData(hdpData);
if (rvInfoData != null) {
rvInfoDataList.add(rvInfoData);
}
System.out.println("✓ 解析第 " + (i + 1) + " 行数据成功");
} else {
System.out.println("✗ 解析第 " + (i + 1) + " 行数据失败");
}
}
}
}
}
private static ProcessResult batchInsertData(List<Object[]> hdpDataList, List<Object[]> rvInfoDataList) {
int importedCount = 0;
int duplicateCount = 0;
int rvDuplicateCount = 0;
try (Connection conn = DatabaseUtil.getConnection();
PreparedStatement hdpPstmt = conn.prepareStatement(INSERT_HDP_SQL);
PreparedStatement rvInfoPstmt = conn.prepareStatement(INSERT_RV_INFO_SQL);
PreparedStatement checkHdpDupPstmt = conn.prepareStatement(CHECK_HDP_DUPLICATE_SQL);
PreparedStatement checkRvInfoDupPstmt = conn.prepareStatement(CHECK_RV_INFO_DUPLICATE_SQL)) {
conn.setAutoCommit(false); // 开启事务
// 使用Set来跟踪已处理的数据避免内存中重复
Set<String> processedHdpKeys = new HashSet<>();
Set<String> processedRvInfoKeys = new HashSet<>();
// 处理防灾对象表数据
for (Object[] rowData : hdpDataList) {
try {
// 检查是否重复
String adcd = (String) rowData[0];
String prename = (String) rowData[24]; // PRENAME在索引24
String precode = (String) rowData[25]; // PRECODE在索引25
String type = (String) rowData[2]; // TYPE在索引2
Integer pcount = (Integer) rowData[3]; // PCOUNT在索引3
// 检查必要字段是否为空
if (adcd == null || prename == null || precode == null || type == null) {
System.out.println("跳过数据不完整的记录: " + prename + " (" + precode + ")");
continue;
}
// 生成唯一键,先检查内存中是否已处理
String hdpKey = adcd + "|" + prename + "|" + precode + "|" + type + "|" + pcount;
if (processedHdpKeys.contains(hdpKey)) {
duplicateCount++;
System.out.println("跳过内存中重复记录: " + prename + " (" + precode + ")");
continue;
}
// 检查数据库中是否已存在
checkHdpDupPstmt.setString(1, adcd);
checkHdpDupPstmt.setString(2, prename);
checkHdpDupPstmt.setString(3, precode);
checkHdpDupPstmt.setString(4, type);
if (pcount != null) {
checkHdpDupPstmt.setInt(5, pcount);
checkHdpDupPstmt.setInt(6, pcount);
} else {
checkHdpDupPstmt.setNull(5, java.sql.Types.INTEGER);
checkHdpDupPstmt.setNull(6, java.sql.Types.INTEGER);
}
try (ResultSet rs = checkHdpDupPstmt.executeQuery()) {
if (rs.next() && rs.getInt(1) > 0) {
duplicateCount++;
System.out.println("跳过数据库中重复记录: " + prename + " (" + precode + ")");
continue;
}
}
// 插入数据
for (int i = 0; i < rowData.length; i++) {
hdpPstmt.setObject(i + 1, rowData[i]);
}
hdpPstmt.addBatch();
importedCount++;
processedHdpKeys.add(hdpKey); // 记录已处理的键
// 每10条执行一次批量插入
if (importedCount % 10 == 0) {
hdpPstmt.executeBatch();
System.out.println("已批量插入 " + importedCount + " 条记录到防灾对象表");
}
} catch (Exception e) {
System.err.println("单条数据插入失败: " + e.getMessage());
e.printStackTrace();
// 继续处理下一条数据
}
}
// 执行剩余的批量插入
if (importedCount > 0 && importedCount % 10 != 0) {
hdpPstmt.executeBatch();
System.out.println("最终批量插入完成,共 " + importedCount + " 条记录到防灾对象表");
}
// 处理河流信息表数据
int rvImportedCount = 0;
for (Object[] rvData : rvInfoDataList) {
try {
// 检查河流信息是否重复
String precode = (String) rvData[0];
String prename = (String) rvData[1];
String rvcd = (String) rvData[2];
String rvnm = (String) rvData[3];
String wscd = (String) rvData[4];
// 检查必要字段是否为空
if (precode == null || prename == null || rvcd == null || rvnm == null || wscd == null) {
System.out.println("跳过河流信息数据不完整的记录: " + prename + " (" + precode + ")");
continue;
}
// 生成唯一键,先检查内存中是否已处理
String rvInfoKey = precode + "|" + prename + "|" + rvcd + "|" + rvnm + "|" + wscd;
if (processedRvInfoKeys.contains(rvInfoKey)) {
rvDuplicateCount++;
System.out.println("跳过内存中河流信息重复记录: " + prename + " (" + precode + ") - " + rvnm);
continue;
}
// 检查数据库中是否已存在
checkRvInfoDupPstmt.setString(1, precode);
checkRvInfoDupPstmt.setString(2, prename);
checkRvInfoDupPstmt.setString(3, rvcd);
checkRvInfoDupPstmt.setString(4, rvnm);
checkRvInfoDupPstmt.setString(5, wscd);
try (ResultSet rs = checkRvInfoDupPstmt.executeQuery()) {
if (rs.next() && rs.getInt(1) > 0) {
rvDuplicateCount++;
System.out.println("跳过数据库中河流信息重复记录: " + prename + " (" + precode + ") - " + rvnm);
continue;
}
}
for (int i = 0; i < rvData.length; i++) {
rvInfoPstmt.setObject(i + 1, rvData[i]);
}
rvInfoPstmt.addBatch();
rvImportedCount++;
processedRvInfoKeys.add(rvInfoKey); // 记录已处理的键
if (rvImportedCount % 10 == 0) {
rvInfoPstmt.executeBatch();
System.out.println("已批量插入 " + rvImportedCount + " 条记录到河流信息表");
}
} catch (Exception e) {
System.err.println("河流信息表数据插入失败: " + e.getMessage());
e.printStackTrace();
}
}
// 执行剩余的河流信息批量插入
if (rvImportedCount > 0 && rvImportedCount % 10 != 0) {
rvInfoPstmt.executeBatch();
System.out.println("最终批量插入完成,共 " + rvImportedCount + " 条记录到河流信息表");
}
conn.commit(); // 提交事务
System.out.println("事务提交成功");
} catch (Exception e) {
System.err.println("批量插入数据失败: " + e.getMessage());
e.printStackTrace();
}
return new ProcessResult(importedCount, duplicateCount, rvDuplicateCount);
}
// 修改ProcessResult类添加河流信息重复统计
private static class ProcessResult {
int processed;
int duplicates;
int rvDuplicates;
ProcessResult(int processed, int duplicates, int rvDuplicates) {
this.processed = processed;
this.duplicates = duplicates;
this.rvDuplicates = rvDuplicates;
}
}
// 解析河流信息表数据
private static Object[] parseRvInfoData(Object[] hdpData) {
try {
Object[] rvData = new Object[5];
// PRECODE
rvData[0] = hdpData[25]; // PRECODE在索引25
// PRENAME
rvData[1] = hdpData[24]; // PRENAME在索引24
// RVCD - 河流代码
rvData[2] = hdpData[5]; // RVCD在索引5
// RVNM - 河流名称
rvData[3] = hdpData[4]; // RVNM在索引4
// WSCD - 流域编码
rvData[4] = hdpData[35]; // WSCD在索引35
return rvData;
} catch (Exception e) {
System.err.println("解析河流信息数据失败: " + e.getMessage());
return null;
}
}
// 其他辅助方法保持不变...
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[] findSxDirectories(File watershedDir) {
File[] subDirs = watershedDir.listFiles(File::isDirectory);
if (subDirs != null) {
List<File> sxDirs = new ArrayList<>();
for (File subDir : subDirs) {
// 包含"水系"或者是类似HBWF开头的文件夹都认为是水系文件夹
if (subDir.getName().contains("水系") || subDir.getName().matches("^HBWF.*")) {
sxDirs.add(subDir);
}
}
return sxDirs.toArray(new File[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("表1山洪灾害防治对象名录.xlsx") || name.toLowerCase().endsWith(".xlsx"));
if (files != null && files.length > 0) {
for (File file : files) {
if (file.getName().equals("表1山洪灾害防治对象名录.xlsx")) {
return file;
}
}
return files[0];
}
return null;
}
private static String extractCountyName(String dirName) {
return dirName.contains("、") ? dirName.split("、")[1].trim() : dirName;
}
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);
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 String getCellStringValue(Cell cell) {
if (cell == null) return null;
try {
switch (cell.getCellType()) {
case STRING: return cell.getStringCellValue().trim();
case NUMERIC:
double num = cell.getNumericCellValue();
return (num == (long) num) ? String.valueOf((long) num) : String.valueOf(num);
case BOOLEAN: return String.valueOf(cell.getBooleanCellValue());
default: return null;
}
} catch (Exception 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;
}
}
// parseRowData方法保持不变...
private static Object[] parseRowData(Row row, String countyName, String watershedCode, String countyCode,String adcd ,String adnm) {
try {
Object[] data = new Object[36]; // 对应36个参数
int index = 0;
// ADCD - 行政区划代码 (C列)
String objectCode = getCellStringValue(row.getCell(2));
data[index++] = adcd;
// ADNM - 行政区划名称 (B列 + 县市名称)
String objectName = getCellStringValue(row.getCell(1));
data[index++] = adnm;
// TYPE - 类型 (D列)
data[index++] = getCellStringValue(row.getCell(3));
// PCOUNT - 人口 (E列)
String populationStr = getCellStringValue(row.getCell(4));
if (populationStr != null && !populationStr.trim().isEmpty()) {
try {
data[index++] = Integer.parseInt(populationStr.trim());
} catch (NumberFormatException e) {
data[index++] = null;
}
} else {
data[index++] = null;
}
// RVNM - 河流名称 (F列)
data[index++] = getCellStringValue(row.getCell(5));
// RVCD - 河流代码 (G列)
data[index++] = getCellStringValue(row.getCell(6));
// BRNAME - 桥梁名称 (H列)
data[index++] = getCellStringValue(row.getCell(7));
// BRCD - 桥梁编码 (I列)
data[index++] = getCellStringValue(row.getCell(8));
// DAMNAME - 塘坝名称 (J列)
data[index++] = getCellStringValue(row.getCell(9));
// DAMCD - 塘坝编码 (K列)
data[index++] = getCellStringValue(row.getCell(10));
// DZRVNM - 多支河流名称 (L列)
data[index++] = getCellStringValue(row.getCell(11));
// DZRVCD - 多支河流代码 (M列)
data[index++] = getCellStringValue(row.getCell(12));
// 风险隐患要素 (N~S列)
data[index++] = getCellStringValue(row.getCell(13)); // ISSZ束窄
data[index++] = getCellStringValue(row.getCell(14)); // ISJW急弯
data[index++] = getCellStringValue(row.getCell(15)); // ISDW低洼地
data[index++] = getCellStringValue(row.getCell(18)); // ISGT沟滩占地
data[index++] = getCellStringValue(row.getCell(20)); // ISYS壅水
data[index++] = getCellStringValue(row.getCell(21)); // ISDT顶托
// 风险隐患影响类型 (T~Y列)
data[index++] = getCellStringValue(row.getCell(22)); // ISGD改道
data[index++] = getCellStringValue(row.getCell(23)); // ISML漫流
// REMARK - 备注 (Z列)
data[index++] = getCellStringValue(row.getCell(24));
// 固定值字段
data[index++] = "1"; // ISENABLE
data[index++] = "2025"; // IMPORTYEAR
data[index++] = getCellStringValue(row.getCell(19)); // ISKJ溃决
data[index++] = objectName; // PRENAME
data[index++] = objectCode; // PRECODE
data[index++] = getCellStringValue(row.getCell(16)); // ISLHHP临河滑坡
data[index++] = getCellStringValue(row.getCell(17)); // ISNSL泥石流
data[index++] = null; // SIGNER
data[index++] = countyCode; // CADCD
// GUID - 唯一标识
data[index++] = UUID.randomUUID().toString();
// 其他固定字段
data[index++] = "BATCH_" + System.currentTimeMillis(); // AUDBATCH
data[index++] = "1"; // INPUTTYPE
data[index++] = null; // AUDID
data[index++] = "1"; // STATUS
// WSCD - 流域编码
data[index++] = watershedCode;
return data;
} catch (Exception e) {
System.err.println("解析行数据失败: " + e.getMessage());
return null;
}
}
}

View File

@ -0,0 +1,915 @@
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.sql.ResultSet;
import java.sql.Timestamp;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
*
*/
public class IaShzhHsurfaceDataImporter {
public static final String dirName1 = "防治对象断面成果";
public static final String type1 = "1";
public static final String dirName2 = "跨沟道路河桥涵";
public static final String type2 = "2";
// 横断面主表插入SQL - 所有字段都通过参数设置
private static final String INSERT_HSURFACE_SQL =
"INSERT INTO SHZH_JCSJ.IA_M_HSURFACE(" +
"HECD, ADCD, CHANNEL, ADDRESS, ISCTOWN, DMIDENTIT, " +
"DMFORM, TEXTURE, COORDINATE, ELETYPE, BASEELE, BASELGTD, " +
"BASELTTD, AZIMUTH, HMZ, CZZ, METHOD, VECD, SIGNER, " +
"AUDID, STATUS, REMARK, MODITIME, ISENABLE, IMPORTYEAR, " +
"AUDBATCH, CADCD, GUID, INPUTTYPE, WSCD, SURFACE_CLASSIFY, " +
"OBJECT_NAME, SURFACE_TYPE) " +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, " +
"?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, " +
"?, ?, ?, ?, ?,?)";
// 横断面点表插入SQL - 所有字段都通过参数设置
private static final String INSERT_HSPOINT_SQL =
"INSERT INTO SHZH_JCSJ.IA_M_HSPOINT(" +
"HSURFACEID, TRANSECTNAME, FID, HELGTD, HELTTD, CDISTANCE, " +
"HEELE, POINTSIGN, TRANSECTTYPE, RVCOEFF, RIGHTCOEFF, " +
"LEFTCOEFF, GRADIENT, MODITIME, GUID, REMARK) " +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
// 检查横断面主表重复的SQL
private static final String CHECK_HSURFACE_DUPLICATE_SQL =
"SELECT COUNT(*) FROM SHZH_JCSJ.IA_M_HSURFACE WHERE HECD = ? and SURFACE_CLASSIFY = ?";
// 检查横断面点表重复的SQL
private static final String CHECK_HSPOINT_DUPLICATE_SQL =
"SELECT COUNT(*) FROM SHZH_JCSJ.IA_M_HSPOINT WHERE HSURFACEID = ? AND FID = ?";
public static void main(String[] args) {
// 测试用的固定路径
// args = new String[]{"C:\\Users\\gsiot\\Desktop\\项目资料\\山洪\\小流域\\222"};
// args = new String[]{"F:\\1111-湖工大50条成果-已通过初检-待入库"};--湖工大
// args = new String[]{"F:\\4444-长江科学院-黄冈28条-已通过初检-已统一表头-待入库"};
args = new String[]{"I:\\7777-华科-咸宁市8条1027-已通过初检-已统一表头-已入库"};
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;
int totalDuplicates = 0;
int totalPointDuplicates = 0;
System.out.println("找到 " + countyDirs.length + " 个县市文件夹");
for (File countyDir : countyDirs) {
String countyName = extractCountyName(countyDir.getName());
System.out.println("\n=== 处理县市: " + countyName + " ===");
try {
ProcessResult result = processCountyData(countyDir, countyName);
totalProcessed += result.processed;
totalDuplicates += result.duplicates;
totalPointDuplicates += result.pointDuplicates;
totalSuccess++;
System.out.println("✓ 成功处理 " + countyName +
",导入 " + result.processed + " 条记录,跳过 " + result.duplicates +
" 条重复记录,断面点跳过 " + result.pointDuplicates + " 条重复记录");
} catch (Exception e) {
System.err.println("✗ 处理县市 " + countyName + " 时出错: " + e.getMessage());
}
}
System.out.println("\n=== 处理完成 ===");
System.out.println("成功处理县市: " + totalSuccess + " 个");
System.out.println("总导入记录: " + totalProcessed + " 条");
System.out.println("横断面主表跳过重复记录: " + totalDuplicates + " 条");
System.out.println("横断面点表跳过重复记录: " + totalPointDuplicates + " 条");
}
private static ProcessResult processCountyData(File countyDir, String countyName) throws Exception {
int totalProcessed = 0;
int totalDuplicates = 0;
int totalPointDuplicates = 0;
// 查找小流域目录
File watershedDir = findWatershedDirectory(countyDir);
if (watershedDir == null) {
System.out.println("在 " + countyName + " 下未找到小流域目录");
return new ProcessResult(0, 0, 0);
}
System.out.println("找到小流域目录: " + watershedDir.getName());
// 查找所有水系目录
File[] sxDirs = findSxDirectories(watershedDir);
if (sxDirs == null || sxDirs.length == 0) {
System.out.println("在 " + watershedDir.getPath() + " 下未找到水系目录");
return new ProcessResult(0, 0, 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());
ProcessResult result = processSxData(sxDir, countyName);
totalProcessed += result.processed;
totalDuplicates += result.duplicates;
totalPointDuplicates += result.pointDuplicates;
System.out.println("水系 " + sxDir.getName() + " 导入 " + result.processed + " 条记录,跳过 " +
result.duplicates + " 条重复记录,断面点跳过 " + result.pointDuplicates + " 条重复记录");
}
return new ProcessResult(totalProcessed, totalDuplicates, totalPointDuplicates);
}
private static ProcessResult processSxData(File sxDir, String countyName) throws Exception {
int processedCount = 0;
int duplicateCount = 0;
int pointDuplicateCount = 0;
// 按照新的目录结构查找文件
File crossSectionDir = findCrossSectionDirectory(sxDir);
if (crossSectionDir == null) {
System.out.println("在 " + sxDir.getPath() + " 下未找到横断面成果表目录");
return new ProcessResult(0, 0, 0);
}
System.out.println("找到横断面成果表目录: " + crossSectionDir.getPath());
// 查找所有Excel文件
File[] excelFiles = findExcelFiles(crossSectionDir);
if (excelFiles == null || excelFiles.length == 0) {
System.out.println("在 " + crossSectionDir.getPath() + " 下未找到横断面Excel文件");
return new ProcessResult(0, 0, 0);
}
System.out.println("找到 " + excelFiles.length + " 个横断面Excel文件:");
for (File excelFile : excelFiles) {
System.out.println(" - " + excelFile.getName());
}
// 提取流域编码
String watershedCode = CommonUtils.extractWatershedCode(sxDir.getName());
System.out.println("流域编码: " + watershedCode);
// 处理每个Excel文件
for (File excelFile : excelFiles) {
System.out.println("\n处理文件: " + excelFile.getName());
try {
// 验证文件是否为有效Excel文件
if (!isValidExcelFile(excelFile)) {
System.err.println("跳过无效的Excel文件: " + excelFile.getName());
continue;
}
ProcessResult result = readExcelAndImport(excelFile, countyName, watershedCode);
processedCount += result.processed;
duplicateCount += result.duplicates;
pointDuplicateCount += result.pointDuplicates;
System.out.println("文件 " + excelFile.getName() + " 导入 " + result.processed +
" 条记录,跳过 " + result.duplicates + " 条重复记录");
} catch (Exception e) {
System.err.println("处理文件 " + excelFile.getName() + " 时出错: " + e.getMessage());
if (e.getMessage().contains("valid OOXML")) {
System.err.println(" 文件可能损坏或格式不正确,跳过此文件");
}
// 继续处理下一个文件
}
}
return new ProcessResult(processedCount, duplicateCount, pointDuplicateCount);
}
/**
* Excel
*/
private static boolean isValidExcelFile(File file) {
if (!file.exists() || !file.isFile()) {
return false;
}
// 检查文件扩展名
String fileName = file.getName().toLowerCase();
if (!fileName.endsWith(".xlsx")) {
System.err.println("文件扩展名不是.xlsx: " + file.getName());
return false;
}
// 检查文件大小
if (file.length() == 0) {
System.err.println("文件大小为0: " + file.getName());
return false;
}
// 尝试打开文件验证格式
try (FileInputStream fis = new FileInputStream(file)) {
// 只读取文件头进行验证,不加载整个文件
byte[] header = new byte[4];
if (fis.read(header) != 4) {
return false;
}
// Excel文件的文件头特征
if (header[0] != 0x50 || header[1] != 0x4B || header[2] != 0x03 || header[3] != 0x04) {
System.err.println("文件头不符合Excel格式: " + file.getName());
return false;
}
return true;
} catch (Exception e) {
System.err.println("验证Excel文件失败: " + file.getName() + " - " + e.getMessage());
return false;
}
}
private static ProcessResult readExcelAndImport(File excelFile, String countyName,String wscd) throws Exception {
int importedCount = 0;
int duplicateCount = 0;
int pointDuplicateCount = 0;
// 先读取所有数据到内存
List<Object[]> hsurfaceDataList = new ArrayList<>();
List<Object[]> hspointDataList = new ArrayList<>();
readExcelData(wscd,excelFile, hsurfaceDataList, hspointDataList);
if (hsurfaceDataList.isEmpty()) {
System.out.println("未读取到有效数据");
return new ProcessResult(0, 0, 0);
}
System.out.println("成功读取 " + hsurfaceDataList.size() + " 条横断面数据,包含 " +
hspointDataList.size() + " 个断面点,开始导入数据库...");
// 批量导入数据库
ProcessResult result = batchInsertData(hsurfaceDataList, hspointDataList);
return result;
}
private static void readExcelData(String wscd,File excelFile,
List<Object[]> hsurfaceDataList,
List<Object[]> hspointDataList) throws Exception {
try (FileInputStream fis = new FileInputStream(excelFile);
Workbook workbook = new XSSFWorkbook(fis)) {
String name = excelFile.getName();
Pattern pattern = Pattern.compile("^[a-zA-Z0-9]+");
Matcher matcher = pattern.matcher(name);
if(matcher.find()){
name=matcher.group();
}else{
System.out.println("工作表表名有问题: " + name);
}
// 遍历所有工作表
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);
// 解析横断面主表数据
Object[] hsurfaceData = parseHsurfaceData(sheet, sheetName,wscd,name);
if (hsurfaceData != null) {
hsurfaceDataList.add(hsurfaceData);
System.out.println("✓ 解析横断面主表数据成功: " + sheetName);
// 解析断面点数据
List<Object[]> points = parseHspointData(sheet, (String) hsurfaceData[27]); // guid作为HSURFACEID
hspointDataList.addAll(points);
System.out.println("✓ 解析 " + points.size() + " 个断面点数据");
} else {
System.out.println("✗ 解析横断面主表数据失败: " + sheetName);
}
}
}
}
private static Object[] parseHsurfaceData(Sheet sheet, String sheetName,String wscd,String excelName) {
try {
Object[] data = new Object[33]; // 对应33个参数
int index = 0;
// 按照新的读取规则获取基本信息
// 第1行C列-所在位置F列-行政区划代码
String location = getCellValue(sheet, 0, 2); // C1单元格
String adminCode = getCellValue(sheet, 0, 5); // F1单元格
// 第3行C列-所在沟道F列-断面标识
String channel = getCellValue(sheet, 1, 2); // C3单元格
String dmIdentit = getCellValue(sheet, 1, 5); // F3单元格
// 第5行C列-断面形态F列-是否跨县
String dmForm = getCellValue(sheet, 2, 2); // C5单元格
String isCrossCounty = getCellValue(sheet, 2, 5); // F5单元格
// 第7行C列-河床底质F列-测量方法
String texture = getCellValue(sheet, 3, 2); // C7单元格
String method = getCellValue(sheet, 3, 5); // F7单元格
// 第1行H列-坐标系备注
String coordinate = ""; // H1单元格
// 提取基点信息(如果存在)
// 第9行C列-基点经度F列-基点纬度
String baseLongitude = getCellValue(sheet, 4, 2); // C9单元格 - 基点经度
String baseLatitude = getCellValue(sheet, 4, 5); // F9单元格 - 基点纬度
// 第11行C列-基点高程F列-断面方位角
String baseElevation = getCellValue(sheet, 5, 2); // C11单元格 - 基点高程
String azimuth = getCellValue(sheet, 5, 5); // F11单元格 - 断面方位角
// 第13行C列-历史最高水位F列-成灾水位
String historyWaterLevel = getCellValue(sheet, 6, 2); // C13单元格 - 历史最高水位
String disasterWaterLevel = getCellValue(sheet, 6, 5); // F13单元格 - 成灾水位
// HECD - 横断面编码 (工作表名)
data[index++] = sheetName;
// ADCD - 行政区划代码
data[index++] = getSafeString(adminCode);
// CHANNEL - 所在沟道
data[index++] = getSafeString(channel);
// ADDRESS - 所在位置
data[index++] = getSafeString(location);
// ISCTOWN - 是否跨县
data[index++] = getSafeString(isCrossCounty);
// DMIDENTIT - 断面标识
data[index++] = getSafeString(dmIdentit);
// DMFORM - 断面形态
data[index++] = getSafeString(dmForm);
// TEXTURE - 河床底质
data[index++] = getSafeString(texture);
// COORDINATE - 坐标系
data[index++] = getSafeString(coordinate);
// ELETYPE - 高程系(默认为空)
data[index++] = null;
// BASEELE - 基点高程
data[index++] = getSafeString(baseElevation);
// BASELGTD - 基点经度
data[index++] = getSafeString(baseLongitude);
// BASELTTD - 基点纬度
data[index++] = getSafeString(baseLatitude);
// AZIMUTH - 断面方位角
data[index++] = getSafeString(azimuth);
// HMZ - 历史最高水位
data[index++] = getSafeString(historyWaterLevel);
// CZZ - 成灾水位
data[index++] = getSafeString(disasterWaterLevel);
// METHOD - 测量方法
data[index++] = getSafeString(method);
// VECD - 纵断面编码(默认为空)
data[index++] = null;
// SIGNER - 填写人姓名(默认为空)
data[index++] = null;
// AUDID - 审核批次号(默认为空)
data[index++] = null;
// STATUS - 状态默认1-待审核)
data[index++] = "1";
// REMARK - 备注
data[index++] = getSafeString(coordinate);
// MODITIME - 时间戳
data[index++] = new Timestamp(System.currentTimeMillis());
// ISENABLE - 启用状态
data[index++] = "1";
// IMPORTYEAR - 导入年份
data[index++] = "2025";
// AUDBATCH - 审核批次
data[index++] = "BATCH_" + System.currentTimeMillis();
// CADCD - 县级编码(从行政区划代码提取)
data[index++] = adminCode != null && adminCode.length() >= 6 ?
adminCode.substring(0, 6) +"000000000" : "";
// GUID - 唯一标识
data[index++] = UUID.randomUUID().toString();
// INPUTTYPE - 录入方式
data[index++] = "1";
// WSCD - 流域编码
data[index++] = wscd;
// SURFACE_CLASSIFY - 断面分类
data[index++] = excelName;
// OBJECT_NAME - 对象名称
data[index++] = null;
// SURFACE_TYPE - 断面类型
data[index++] = type1;
return data;
} catch (Exception e) {
System.err.println("解析横断面主表数据失败: " + e.getMessage());
e.printStackTrace();
return null;
}
}
private static List<Object[]> parseHspointData(Sheet sheet, String hsurfaceId) {
List<Object[]> points = new ArrayList<>();
try {
// 找到数据开始行(序号列开始)
int startRow = findDataStartRow(sheet);
if (startRow == -1) {
System.out.println("未找到断面点数据开始行");
return points;
}
System.out.println("断面点数据从第 " + (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[] pointData = parsePointRowData(row, hsurfaceId, i - startRow + 1);
if (pointData != null) {
points.add(pointData);
}
}
} catch (Exception e) {
System.err.println("解析断面点数据失败: " + e.getMessage());
e.printStackTrace();
}
return points;
}
private static Object[] parsePointRowData(Row row, String hsurfaceId, int fid) {
try {
Object[] data = new Object[16]; // 对应16个参数
int index = 0;
// HSURFACEID - 横断面主表ID
data[index++] = hsurfaceId;
// TRANSECTNAME - 断面特征点描述
data[index++] = getSafeString(getCellStringValue(row.getCell(1)));
// FID - 断面序号
data[index++] = fid;
// HELGTD - 经度
data[index++] = parseDoubleWithDefault(getCellStringValue(row.getCell(4)));
// HELTTD - 纬度
data[index++] = parseDoubleWithDefault(getCellStringValue(row.getCell(5)));
// CDISTANCE - 起点距
data[index++] = parseDoubleWithDefault(getCellStringValue(row.getCell(2)));
// HEELE - 高程
data[index++] = parseDoubleWithDefault(getCellStringValue(row.getCell(3)));
// POINTSIGN - 点类型标记
data[index++] = "0";
// TRANSECTTYPE - 断面类型
data[index++] = "普通断面";
// RVCOEFF - 糙率
data[index++] = parseDoubleWithDefault(getCellStringValue(row.getCell(6)));
// RIGHTCOEFF - 右岸糙率
data[index++] = null;
// LEFTCOEFF - 左岸糙率
data[index++] = null;
// GRADIENT - 坡降
data[index++] = null;
// MODITIME - 时间戳
data[index++] = new Timestamp(System.currentTimeMillis());
// GUID - 唯一标识
data[index++] = UUID.randomUUID().toString();
// REMARK - 备注
data[index++] = null;
return data;
} catch (Exception e) {
System.err.println("解析断面点行数据失败: " + e.getMessage());
return null;
}
}
private static ProcessResult batchInsertData(List<Object[]> hsurfaceDataList, List<Object[]> hspointDataList) {
int importedCount = 0;
int duplicateCount = 0;
int pointDuplicateCount = 0;
Connection conn = null;
PreparedStatement hsurfacePstmt = null;
PreparedStatement hspointPstmt = null;
PreparedStatement checkHsurfaceDupPstmt = null;
PreparedStatement checkHspointDupPstmt = null;
try {
conn = DatabaseUtil.getConnection();
if (conn == null) {
System.err.println("无法获取数据库连接");
return new ProcessResult(0, 0, 0);
}
hsurfacePstmt = conn.prepareStatement(INSERT_HSURFACE_SQL);
hspointPstmt = conn.prepareStatement(INSERT_HSPOINT_SQL);
checkHsurfaceDupPstmt = conn.prepareStatement(CHECK_HSURFACE_DUPLICATE_SQL);
checkHspointDupPstmt = conn.prepareStatement(CHECK_HSPOINT_DUPLICATE_SQL);
conn.setAutoCommit(false); // 开启事务
// 处理横断面主表数据
for (Object[] rowData : hsurfaceDataList) {
try {
String hecd = (String) rowData[0];
String surface_classify = (String) rowData[30];
// 检查横断面是否重复
checkHsurfaceDupPstmt.setString(1, hecd);
checkHsurfaceDupPstmt.setString(2, surface_classify);
try (ResultSet rs = checkHsurfaceDupPstmt.executeQuery()) {
if (rs.next() && rs.getInt(1) > 0) {
duplicateCount++;
System.out.println("跳过重复横断面: " + hecd);
continue;
}
}
// 插入数据 - 设置所有参数
setHsurfaceParameters(hsurfacePstmt, rowData);
hsurfacePstmt.executeUpdate();
importedCount++;
System.out.println("✓ 插入横断面记录: " + hecd);
} catch (Exception e) {
System.err.println("横断面数据插入失败: " + e.getMessage());
e.printStackTrace();
}
}
// 处理横断面点表数据
int pointImportedCount = 0;
for (Object[] pointData : hspointDataList) {
try {
String hsurfaceId = (String) pointData[0];
Integer fid = (Integer) pointData[2];
// 检查断面点是否重复
checkHspointDupPstmt.setString(1, hsurfaceId);
checkHspointDupPstmt.setInt(2, fid);
try (ResultSet rs = checkHspointDupPstmt.executeQuery()) {
if (rs.next() && rs.getInt(1) > 0) {
pointDuplicateCount++;
continue;
}
}
// 插入数据 - 设置所有参数
setHspointParameters(hspointPstmt, pointData);
hspointPstmt.addBatch();
pointImportedCount++;
// 每10条执行一次批量插入
if (pointImportedCount % 10 == 0) {
hspointPstmt.executeBatch();
hspointPstmt.clearBatch(); // 清空批量
System.out.println("已批量插入 " + pointImportedCount + " 条断面点记录");
}
} catch (Exception e) {
System.err.println("断面点数据插入失败: " + e.getMessage());
e.printStackTrace();
}
}
// 执行剩余的断面点批量插入
if (pointImportedCount > 0) {
hspointPstmt.executeBatch();
System.out.println("最终批量插入完成,共 " + pointImportedCount + " 条断面点记录");
}
conn.commit(); // 提交事务
System.out.println("事务提交成功");
} catch (Exception e) {
System.err.println("批量插入数据失败: " + e.getMessage());
e.printStackTrace();
if (conn != null) {
try {
conn.rollback();
System.out.println("事务回滚成功");
} catch (Exception rollbackEx) {
System.err.println("事务回滚失败: " + rollbackEx.getMessage());
}
}
} finally {
// 关闭资源
closeResource(checkHspointDupPstmt);
closeResource(checkHsurfaceDupPstmt);
closeResource(hspointPstmt);
closeResource(hsurfacePstmt);
closeResource(conn);
}
return new ProcessResult(importedCount, duplicateCount, pointDuplicateCount);
}
// 设置横断面主表参数
private static void setHsurfaceParameters(PreparedStatement pstmt, Object[] rowData) throws Exception {
int index = 1;
for (int i = 0; i < rowData.length; i++) {
Object value = rowData[i];
if (value == null) {
pstmt.setNull(index++, java.sql.Types.NULL);
} else if (value instanceof String) {
pstmt.setString(index++, (String) value);
} else if (value instanceof Double) {
pstmt.setDouble(index++, (Double) value);
} else if (value instanceof Integer) {
pstmt.setInt(index++, (Integer) value);
} else if (value instanceof Timestamp) {
pstmt.setTimestamp(index++, (Timestamp) value);
} else {
pstmt.setObject(index++, value);
}
}
}
// 设置横断面点表参数
private static void setHspointParameters(PreparedStatement pstmt, Object[] pointData) throws Exception {
int index = 1;
for (int i = 0; i < pointData.length; i++) {
Object value = pointData[i];
if (value == null) {
pstmt.setNull(index++, java.sql.Types.NULL);
} else if (value instanceof String) {
pstmt.setString(index++, (String) value);
} else if (value instanceof Double) {
pstmt.setDouble(index++, (Double) value);
} else if (value instanceof Integer) {
pstmt.setInt(index++, (Integer) value);
} else if (value instanceof Timestamp) {
pstmt.setTimestamp(index++, (Timestamp) value);
} else {
pstmt.setObject(index++, value);
}
}
}
// 安全关闭资源的方法
private static void closeResource(AutoCloseable resource) {
if (resource != null) {
try {
resource.close();
} catch (Exception e) {
System.err.println("关闭资源时出错: " + e.getMessage());
}
}
}
// 辅助方法安全获取字符串避免null
private static String getSafeString(String value) {
return value != null ? value : "";
}
// 辅助方法解析Double提供默认值
private static Double parseDoubleWithDefault(String value) {
if (value != null && !value.trim().isEmpty()) {
try {
return Double.parseDouble(value.trim());
} catch (NumberFormatException e) {
return 0.0;
}
}
return 0.0;
}
// 辅助方法
private static class ProcessResult {
int processed;
int duplicates;
int pointDuplicates;
ProcessResult(int processed, int duplicates, int pointDuplicates) {
this.processed = processed;
this.duplicates = duplicates;
this.pointDuplicates = pointDuplicates;
}
}
// 目录查找方法(保持不变)
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[] findSxDirectories(File watershedDir) {
File[] subDirs = watershedDir.listFiles(File::isDirectory);
if (subDirs != null) {
List<File> sxDirs = new ArrayList<>();
for (File subDir : subDirs) {
if (subDir.getName().contains("水系") || subDir.getName().matches("^HBWF.*")) {
sxDirs.add(subDir);
}
}
return sxDirs.toArray(new File[0]);
}
return null;
}
private static File findCrossSectionDirectory(File sxDir) {
// 按照新目录结构:水系目录 > 电子数据 > 测量数据 > 防治对象断面成果 > 横断面成果表
File electronicDataDir = findSubDirectory(sxDir, "电子数据");
if (electronicDataDir == null) {
System.out.println("在 " + sxDir.getPath() + " 下未找到电子数据目录");
return null;
}
File measureDataDir = findSubDirectory(electronicDataDir, "测量数据");
if (measureDataDir == null) {
System.out.println("在 " + electronicDataDir.getPath() + " 下未找到测量数据目录");
return null;
}
File sectionResultDir = findSubDirectory(measureDataDir, dirName1);
if (sectionResultDir == null) {
System.out.println("在 " + measureDataDir.getPath() + " 下未找到"+dirName1+"目录");
return null;
}
File crossSectionDir = findSubDirectory(sectionResultDir, "横断面成果表");
if (crossSectionDir == null) {
System.out.println("在 " + sectionResultDir.getPath() + " 下未找到横断面成果表目录");
return null;
}
return crossSectionDir;
}
private static File findSubDirectory(File parentDir, String dirName) {
File[] subDirs = parentDir.listFiles(File::isDirectory);
if (subDirs != null) {
for (File subDir : subDirs) {
if (subDir.getName().equals(dirName)) {
return subDir;
}
}
// 如果没有精确匹配,尝试包含匹配
for (File subDir : subDirs) {
if (subDir.getName().contains(dirName)) {
return subDir;
}
}
}
return null;
}
private static File[] findExcelFiles(File crossSectionDir) {
File[] files = crossSectionDir.listFiles((dir, name) ->
name.toLowerCase().endsWith(".xlsx"));
return files != null ? files : new File[0];
}
private static String extractCountyName(String dirName) {
return dirName.contains("、") ? dirName.split("、")[1].trim() : dirName;
}
private static String getCellValue(Sheet sheet, int rowNum, int colNum) {
Row row = sheet.getRow(rowNum);
if (row != null) {
Cell cell = row.getCell(colNum);
return getCellStringValue(cell);
}
return null;
}
private static String getCellStringValue(Cell cell) {
if (cell == null) return null;
try {
switch (cell.getCellType()) {
case STRING: return cell.getStringCellValue().trim();
case NUMERIC:
double num = cell.getNumericCellValue();
return (num == (long) num) ? String.valueOf((long) num) : String.valueOf(num);
case BOOLEAN: return String.valueOf(cell.getBooleanCellValue());
default: return null;
}
} catch (Exception 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;
}
}
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); // 序号列
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;
}
}

View File

@ -0,0 +1,934 @@
package org.example;
import org.apache.poi.openxml4j.util.ZipSecureFile;
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.sql.ResultSet;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
*
*/
public class IaShzhHsurfaceDataImporter2 {
public static final String dirName1 = "防治对象断面成果";
public static final String type1 = "1";
public static final String dirName2 = "跨沟道路河桥涵";
public static final String type2 = "2";
// 横断面主表插入SQL - 所有字段都通过参数设置
private static final String INSERT_HSURFACE_SQL =
"INSERT INTO SHZH_JCSJ.IA_M_HSURFACE(" +
"HECD, ADCD, CHANNEL, ADDRESS, ISCTOWN, DMIDENTIT, " +
"DMFORM, TEXTURE, COORDINATE, ELETYPE, BASEELE, BASELGTD, " +
"BASELTTD, AZIMUTH, HMZ, CZZ, METHOD, VECD, SIGNER, " +
"AUDID, STATUS, REMARK, MODITIME, ISENABLE, IMPORTYEAR, " +
"AUDBATCH, CADCD, GUID, INPUTTYPE, WSCD, SURFACE_CLASSIFY, " +
"OBJECT_NAME, SURFACE_TYPE) " +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, " +
"?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, " +
"?, ?, ?, ?, ?,?)";
// 横断面点表插入SQL - 所有字段都通过参数设置
private static final String INSERT_HSPOINT_SQL =
"INSERT INTO SHZH_JCSJ.IA_M_HSPOINT(" +
"HSURFACEID, TRANSECTNAME, FID, HELGTD, HELTTD, CDISTANCE, " +
"HEELE, POINTSIGN, TRANSECTTYPE, RVCOEFF, RIGHTCOEFF, " +
"LEFTCOEFF, GRADIENT, MODITIME, GUID, REMARK) " +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
// 检查横断面主表重复的SQL
private static final String CHECK_HSURFACE_DUPLICATE_SQL =
"SELECT COUNT(*) FROM SHZH_JCSJ.IA_M_HSURFACE WHERE HECD = ? and SURFACE_CLASSIFY = ?";
// 检查横断面点表重复的SQL
private static final String CHECK_HSPOINT_DUPLICATE_SQL =
"SELECT COUNT(*) FROM SHZH_JCSJ.IA_M_HSPOINT WHERE HSURFACEID = ? AND FID = ?";
public static void main(String[] args) {
// 测试用的固定路径
// args = new String[]{"C:\\Users\\gsiot\\Desktop\\项目资料\\山洪\\小流域\\222"};
// args = new String[]{"F:\\1111-湖工大50条成果-已通过初检-待入库"};--湖工大
// args = new String[]{"F:\\4444-长江科学院-黄冈28条-已通过初检-已统一表头-待入库"};
args = new String[]{"I:\\7777-华科-咸宁市8条1027-已通过初检-已统一表头-已入库"};
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;
int totalDuplicates = 0;
int totalPointDuplicates = 0;
System.out.println("找到 " + countyDirs.length + " 个县市文件夹");
for (File countyDir : countyDirs) {
String countyName = extractCountyName(countyDir.getName());
System.out.println("\n=== 处理县市: " + countyName + " ===");
try {
ProcessResult result = processCountyData(countyDir, countyName);
totalProcessed += result.processed;
totalDuplicates += result.duplicates;
totalPointDuplicates += result.pointDuplicates;
totalSuccess++;
System.out.println("✓ 成功处理 " + countyName +
",导入 " + result.processed + " 条记录,跳过 " + result.duplicates +
" 条重复记录,断面点跳过 " + result.pointDuplicates + " 条重复记录");
} catch (Exception e) {
System.err.println("✗ 处理县市 " + countyName + " 时出错: " + e.getMessage());
}
}
System.out.println("\n=== 处理完成 ===");
System.out.println("成功处理县市: " + totalSuccess + " 个");
System.out.println("总导入记录: " + totalProcessed + " 条");
System.out.println("横断面主表跳过重复记录: " + totalDuplicates + " 条");
System.out.println("横断面点表跳过重复记录: " + totalPointDuplicates + " 条");
}
private static ProcessResult processCountyData(File countyDir, String countyName) throws Exception {
int totalProcessed = 0;
int totalDuplicates = 0;
int totalPointDuplicates = 0;
// 查找小流域目录
File watershedDir = findWatershedDirectory(countyDir);
if (watershedDir == null) {
System.out.println("在 " + countyName + " 下未找到小流域目录");
return new ProcessResult(0, 0, 0);
}
System.out.println("找到小流域目录: " + watershedDir.getName());
// 查找所有水系目录
File[] sxDirs = findSxDirectories(watershedDir);
if (sxDirs == null || sxDirs.length == 0) {
System.out.println("在 " + watershedDir.getPath() + " 下未找到水系目录");
return new ProcessResult(0, 0, 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());
ProcessResult result = processSxData(sxDir, countyName);
totalProcessed += result.processed;
totalDuplicates += result.duplicates;
totalPointDuplicates += result.pointDuplicates;
System.out.println("水系 " + sxDir.getName() + " 导入 " + result.processed + " 条记录,跳过 " +
result.duplicates + " 条重复记录,断面点跳过 " + result.pointDuplicates + " 条重复记录");
}
return new ProcessResult(totalProcessed, totalDuplicates, totalPointDuplicates);
}
private static ProcessResult processSxData(File sxDir, String countyName) throws Exception {
int processedCount = 0;
int duplicateCount = 0;
int pointDuplicateCount = 0;
// 按照新的目录结构查找文件
File crossSectionDir = findCrossSectionDirectory(sxDir);
if (crossSectionDir == null) {
System.out.println("在 " + sxDir.getPath() + " 下未找到横断面成果表目录");
return new ProcessResult(0, 0, 0);
}
System.out.println("找到横断面成果表目录: " + crossSectionDir.getPath());
// 查找所有Excel文件
File[] excelFiles = findExcelFiles(crossSectionDir);
if (excelFiles == null || excelFiles.length == 0) {
System.out.println("在 " + crossSectionDir.getPath() + " 下未找到横断面Excel文件");
return new ProcessResult(0, 0, 0);
}
System.out.println("找到 " + excelFiles.length + " 个横断面Excel文件:");
for (File excelFile : excelFiles) {
System.out.println(" - " + excelFile.getName());
}
// 提取流域编码
String watershedCode = CommonUtils.extractWatershedCode(sxDir.getName());
System.out.println("流域编码: " + watershedCode);
// 处理每个Excel文件
for (File excelFile : excelFiles) {
System.out.println("\n处理文件: " + excelFile.getName());
try {
// 验证文件是否为有效Excel文件
if (!isValidExcelFile(excelFile)) {
System.err.println("跳过无效的Excel文件: " + excelFile.getName());
continue;
}
ProcessResult result = readExcelAndImport(excelFile, countyName, watershedCode);
processedCount += result.processed;
duplicateCount += result.duplicates;
pointDuplicateCount += result.pointDuplicates;
System.out.println("文件 " + excelFile.getName() + " 导入 " + result.processed +
" 条记录,跳过 " + result.duplicates + " 条重复记录");
} catch (Exception e) {
System.err.println("处理文件 " + excelFile.getName() + " 时出错: " + e.getMessage());
if (e.getMessage().contains("valid OOXML")) {
System.err.println(" 文件可能损坏或格式不正确,跳过此文件");
}
// 继续处理下一个文件
}
}
return new ProcessResult(processedCount, duplicateCount, pointDuplicateCount);
}
/**
* Excel
*/
private static boolean isValidExcelFile(File file) {
if (!file.exists() || !file.isFile()) {
return false;
}
// 检查文件扩展名
String fileName = file.getName().toLowerCase();
if (!fileName.endsWith(".xlsx")) {
System.err.println("文件扩展名不是.xlsx: " + file.getName());
return false;
}
// 检查文件大小
if (file.length() == 0) {
System.err.println("文件大小为0: " + file.getName());
return false;
}
// 尝试打开文件验证格式
try (FileInputStream fis = new FileInputStream(file)) {
// 只读取文件头进行验证,不加载整个文件
byte[] header = new byte[4];
if (fis.read(header) != 4) {
return false;
}
// Excel文件的文件头特征
if (header[0] != 0x50 || header[1] != 0x4B || header[2] != 0x03 || header[3] != 0x04) {
System.err.println("文件头不符合Excel格式: " + file.getName());
return false;
}
return true;
} catch (Exception e) {
System.err.println("验证Excel文件失败: " + file.getName() + " - " + e.getMessage());
return false;
}
}
private static ProcessResult readExcelAndImport(File excelFile, String countyName, String wscd) throws Exception {
int importedCount = 0;
int duplicateCount = 0;
int pointDuplicateCount = 0;
// 先读取所有数据到内存
List<Object[]> hsurfaceDataList = new ArrayList<>();
List<Object[]> hspointDataList = new ArrayList<>();
readExcelData(wscd, excelFile, hsurfaceDataList, hspointDataList);
if (hsurfaceDataList.isEmpty()) {
System.out.println("未读取到有效数据");
return new ProcessResult(0, 0, 0);
}
System.out.println("成功读取 " + hsurfaceDataList.size() + " 条横断面数据,包含 " +
hspointDataList.size() + " 个断面点,开始导入数据库...");
// 批量导入数据库
ProcessResult result = batchInsertData(hsurfaceDataList, hspointDataList);
return result;
}
private static void readExcelData(String wscd, File excelFile,
List<Object[]> hsurfaceDataList,
List<Object[]> hspointDataList) throws Exception {
// 保存原始设置
double originalRatio = ZipSecureFile.getMinInflateRatio();
try {
// 临时调整安全阈值
ZipSecureFile.setMinInflateRatio(0.001);
try (FileInputStream fis = new FileInputStream(excelFile);
Workbook workbook = new XSSFWorkbook(fis)) {
String name = excelFile.getName();
Pattern pattern = Pattern.compile("^[a-zA-Z0-9]+");
Matcher matcher = pattern.matcher(name);
if (matcher.find()) {
name = matcher.group();
} else {
System.out.println("工作表表名有问题: " + name);
}
// 遍历所有工作表
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);
// 解析横断面主表数据
Object[] hsurfaceData = parseHsurfaceData(sheet, sheetName, wscd, name);
if (hsurfaceData != null) {
hsurfaceDataList.add(hsurfaceData);
System.out.println("✓ 解析横断面主表数据成功: " + sheetName);
// 解析断面点数据
List<Object[]> points = parseHspointData(sheet, (String) hsurfaceData[27]); // guid作为HSURFACEID
hspointDataList.addAll(points);
System.out.println("✓ 解析 " + points.size() + " 个断面点数据");
} else {
System.out.println("✗ 解析横断面主表数据失败: " + sheetName);
}
}
}
} finally {
// 恢复原始设置
ZipSecureFile.setMinInflateRatio(originalRatio);
}
}
private static Object[] parseHsurfaceData(Sheet sheet, String sheetName, String wscd, String excelName) {
try {
Object[] data = new Object[33]; // 对应33个参数
int index = 0;
// 按照新的读取规则获取基本信息
// 第1行C列-所在位置F列-行政区划代码
String location = getCellValue(sheet, 0, 2); // C1单元格
String adminCode = getCellValue(sheet, 0, 5); // F1单元格
// 第3行C列-所在沟道F列-断面标识
String channel = getCellValue(sheet, 1, 2); // C3单元格
String dmIdentit = getCellValue(sheet, 1, 5); // F3单元格
// 第5行C列-断面形态F列-是否跨县
String dmForm = getCellValue(sheet, 2, 2); // C5单元格
String isCrossCounty = getCellValue(sheet, 2, 5); // F5单元格
// 第7行C列-河床底质F列-测量方法
String texture = getCellValue(sheet, 3, 2); // C7单元格
String method = getCellValue(sheet, 3, 5); // F7单元格
// 第1行H列-坐标系备注
String coordinate = ""; // H1单元格
// 提取基点信息(如果存在)
// 第9行C列-基点经度F列-基点纬度
String baseLongitude = getCellValue(sheet, 4, 2); // C9单元格 - 基点经度
String baseLatitude = getCellValue(sheet, 4, 5); // F9单元格 - 基点纬度
// 第11行C列-基点高程F列-断面方位角
String baseElevation = getCellValue(sheet, 5, 2); // C11单元格 - 基点高程
String azimuth = getCellValue(sheet, 5, 5); // F11单元格 - 断面方位角
// 第13行C列-历史最高水位F列-成灾水位
String historyWaterLevel = getCellValue(sheet, 6, 2); // C13单元格 - 历史最高水位
String disasterWaterLevel = getCellValue(sheet, 6, 5); // F13单元格 - 成灾水位
// HECD - 横断面编码 (工作表名)
data[index++] = sheetName;
// ADCD - 行政区划代码
data[index++] = getSafeString(adminCode);
// CHANNEL - 所在沟道
data[index++] = getSafeString(channel);
// ADDRESS - 所在位置
data[index++] = getSafeString(location);
// ISCTOWN - 是否跨县
data[index++] = getSafeString(isCrossCounty);
// DMIDENTIT - 断面标识
data[index++] = getSafeString(dmIdentit);
// DMFORM - 断面形态
data[index++] = getSafeString(dmForm);
// TEXTURE - 河床底质
data[index++] = getSafeString(texture);
// COORDINATE - 坐标系
data[index++] = getSafeString(coordinate);
// ELETYPE - 高程系(默认为空)
data[index++] = null;
// BASEELE - 基点高程
data[index++] = getSafeString(baseElevation);
// BASELGTD - 基点经度
data[index++] = getSafeString(baseLongitude);
// BASELTTD - 基点纬度
data[index++] = getSafeString(baseLatitude);
// AZIMUTH - 断面方位角
data[index++] = getSafeString(azimuth);
// HMZ - 历史最高水位
data[index++] = getSafeString(historyWaterLevel);
// CZZ - 成灾水位
data[index++] = getSafeString(disasterWaterLevel);
// METHOD - 测量方法
data[index++] = getSafeString(method);
// VECD - 纵断面编码(默认为空)
data[index++] = null;
// SIGNER - 填写人姓名(默认为空)
data[index++] = null;
// AUDID - 审核批次号(默认为空)
data[index++] = null;
// STATUS - 状态默认1-待审核)
data[index++] = "1";
// REMARK - 备注
data[index++] = getSafeString(coordinate);
// MODITIME - 时间戳
data[index++] = new Timestamp(System.currentTimeMillis());
// ISENABLE - 启用状态
data[index++] = "1";
// IMPORTYEAR - 导入年份
data[index++] = "2025";
// AUDBATCH - 审核批次
data[index++] = "BATCH_" + System.currentTimeMillis();
// CADCD - 县级编码(从行政区划代码提取)
data[index++] = adminCode != null && adminCode.length() >= 6 ?
adminCode.substring(0, 6) + "000000000" : "";
// GUID - 唯一标识
data[index++] = UUID.randomUUID().toString();
// INPUTTYPE - 录入方式
data[index++] = "1";
// WSCD - 流域编码
data[index++] = wscd;
// SURFACE_CLASSIFY - 断面分类
data[index++] = excelName;
// OBJECT_NAME - 对象名称
data[index++] = null;
// SURFACE_TYPE - 断面类型
data[index++] = type1;
return data;
} catch (Exception e) {
System.err.println("解析横断面主表数据失败: " + e.getMessage());
e.printStackTrace();
return null;
}
}
private static List<Object[]> parseHspointData(Sheet sheet, String hsurfaceId) {
List<Object[]> points = new ArrayList<>();
try {
// 找到数据开始行(序号列开始)
int startRow = findDataStartRow(sheet);
if (startRow == -1) {
System.out.println("未找到断面点数据开始行");
return points;
}
System.out.println("断面点数据从第 " + (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[] pointData = parsePointRowData(row, hsurfaceId, i - startRow + 1);
if (pointData != null) {
points.add(pointData);
}
}
} catch (Exception e) {
System.err.println("解析断面点数据失败: " + e.getMessage());
e.printStackTrace();
}
return points;
}
private static Object[] parsePointRowData(Row row, String hsurfaceId, int fid) {
try {
Object[] data = new Object[16]; // 对应16个参数
int index = 0;
// HSURFACEID - 横断面主表ID
data[index++] = hsurfaceId;
// TRANSECTNAME - 断面特征点描述
data[index++] = getSafeString(getCellStringValue(row.getCell(1)));
// FID - 断面序号
data[index++] = fid;
// HELGTD - 经度
data[index++] = parseDoubleWithDefault(getCellStringValue(row.getCell(4)));
// HELTTD - 纬度
data[index++] = parseDoubleWithDefault(getCellStringValue(row.getCell(5)));
// CDISTANCE - 起点距
data[index++] = parseDoubleWithDefault(getCellStringValue(row.getCell(2)));
// HEELE - 高程
data[index++] = parseDoubleWithDefault(getCellStringValue(row.getCell(3)));
// POINTSIGN - 点类型标记
data[index++] = "0";
// TRANSECTTYPE - 断面类型
data[index++] = "普通断面";
// RVCOEFF - 糙率
data[index++] = parseDoubleWithDefault(getCellStringValue(row.getCell(6)));
// RIGHTCOEFF - 右岸糙率
data[index++] = null;
// LEFTCOEFF - 左岸糙率
data[index++] = null;
// GRADIENT - 坡降
data[index++] = null;
// MODITIME - 时间戳
data[index++] = new Timestamp(System.currentTimeMillis());
// GUID - 唯一标识
data[index++] = UUID.randomUUID().toString();
// REMARK - 备注
data[index++] = null;
return data;
} catch (Exception e) {
System.err.println("解析断面点行数据失败: " + e.getMessage());
return null;
}
}
private static ProcessResult batchInsertData(List<Object[]> hsurfaceDataList, List<Object[]> hspointDataList) {
int importedCount = 0;
int duplicateCount = 0;
int pointDuplicateCount = 0;
Connection conn = null;
PreparedStatement hsurfacePstmt = null;
PreparedStatement hspointPstmt = null;
PreparedStatement checkHsurfaceDupPstmt = null;
PreparedStatement checkHspointDupPstmt = null;
try {
conn = DatabaseUtil.getConnection();
if (conn == null) {
System.err.println("无法获取数据库连接");
return new ProcessResult(0, 0, 0);
}
hsurfacePstmt = conn.prepareStatement(INSERT_HSURFACE_SQL);
hspointPstmt = conn.prepareStatement(INSERT_HSPOINT_SQL);
checkHsurfaceDupPstmt = conn.prepareStatement(CHECK_HSURFACE_DUPLICATE_SQL);
checkHspointDupPstmt = conn.prepareStatement(CHECK_HSPOINT_DUPLICATE_SQL);
conn.setAutoCommit(false); // 开启事务
// 处理横断面主表数据
for (Object[] rowData : hsurfaceDataList) {
try {
String hecd = (String) rowData[0];
String surface_classify = (String) rowData[30];
// 检查横断面是否重复
checkHsurfaceDupPstmt.setString(1, hecd);
checkHsurfaceDupPstmt.setString(2, surface_classify);
try (ResultSet rs = checkHsurfaceDupPstmt.executeQuery()) {
if (rs.next() && rs.getInt(1) > 0) {
duplicateCount++;
System.out.println("跳过重复横断面: " + hecd);
continue;
}
}
// 插入数据 - 设置所有参数
setHsurfaceParameters(hsurfacePstmt, rowData);
hsurfacePstmt.executeUpdate();
importedCount++;
System.out.println("✓ 插入横断面记录: " + hecd);
} catch (Exception e) {
System.err.println("横断面数据插入失败: " + e.getMessage());
e.printStackTrace();
}
}
// 处理横断面点表数据
int pointImportedCount = 0;
for (Object[] pointData : hspointDataList) {
try {
String hsurfaceId = (String) pointData[0];
Integer fid = (Integer) pointData[2];
// 检查断面点是否重复
checkHspointDupPstmt.setString(1, hsurfaceId);
checkHspointDupPstmt.setInt(2, fid);
try (ResultSet rs = checkHspointDupPstmt.executeQuery()) {
if (rs.next() && rs.getInt(1) > 0) {
pointDuplicateCount++;
continue;
}
}
// 插入数据 - 设置所有参数
setHspointParameters(hspointPstmt, pointData);
hspointPstmt.addBatch();
pointImportedCount++;
// 每10条执行一次批量插入
if (pointImportedCount % 10 == 0) {
hspointPstmt.executeBatch();
hspointPstmt.clearBatch(); // 清空批量
System.out.println("已批量插入 " + pointImportedCount + " 条断面点记录");
}
} catch (Exception e) {
System.err.println("断面点数据插入失败: " + e.getMessage());
e.printStackTrace();
}
}
// 执行剩余的断面点批量插入
if (pointImportedCount > 0) {
hspointPstmt.executeBatch();
System.out.println("最终批量插入完成,共 " + pointImportedCount + " 条断面点记录");
}
conn.commit(); // 提交事务
System.out.println("事务提交成功");
} catch (Exception e) {
System.err.println("批量插入数据失败: " + e.getMessage());
e.printStackTrace();
if (conn != null) {
try {
conn.rollback();
System.out.println("事务回滚成功");
} catch (Exception rollbackEx) {
System.err.println("事务回滚失败: " + rollbackEx.getMessage());
}
}
} finally {
// 关闭资源
closeResource(checkHspointDupPstmt);
closeResource(checkHsurfaceDupPstmt);
closeResource(hspointPstmt);
closeResource(hsurfacePstmt);
closeResource(conn);
}
return new ProcessResult(importedCount, duplicateCount, pointDuplicateCount);
}
// 设置横断面主表参数
private static void setHsurfaceParameters(PreparedStatement pstmt, Object[] rowData) throws Exception {
int index = 1;
for (int i = 0; i < rowData.length; i++) {
Object value = rowData[i];
if (value == null) {
pstmt.setNull(index++, java.sql.Types.NULL);
} else if (value instanceof String) {
pstmt.setString(index++, (String) value);
} else if (value instanceof Double) {
pstmt.setDouble(index++, (Double) value);
} else if (value instanceof Integer) {
pstmt.setInt(index++, (Integer) value);
} else if (value instanceof Timestamp) {
pstmt.setTimestamp(index++, (Timestamp) value);
} else {
pstmt.setObject(index++, value);
}
}
}
// 设置横断面点表参数
private static void setHspointParameters(PreparedStatement pstmt, Object[] pointData) throws Exception {
int index = 1;
for (int i = 0; i < pointData.length; i++) {
Object value = pointData[i];
if (value == null) {
pstmt.setNull(index++, java.sql.Types.NULL);
} else if (value instanceof String) {
pstmt.setString(index++, (String) value);
} else if (value instanceof Double) {
pstmt.setDouble(index++, (Double) value);
} else if (value instanceof Integer) {
pstmt.setInt(index++, (Integer) value);
} else if (value instanceof Timestamp) {
pstmt.setTimestamp(index++, (Timestamp) value);
} else {
pstmt.setObject(index++, value);
}
}
}
// 安全关闭资源的方法
private static void closeResource(AutoCloseable resource) {
if (resource != null) {
try {
resource.close();
} catch (Exception e) {
System.err.println("关闭资源时出错: " + e.getMessage());
}
}
}
// 辅助方法安全获取字符串避免null
private static String getSafeString(String value) {
return value != null ? value : "";
}
// 辅助方法解析Double提供默认值
private static Double parseDoubleWithDefault(String value) {
if (value != null && !value.trim().isEmpty()) {
try {
return Double.parseDouble(value.trim());
} catch (NumberFormatException e) {
return 0.0;
}
}
return 0.0;
}
// 辅助方法
private static class ProcessResult {
int processed;
int duplicates;
int pointDuplicates;
ProcessResult(int processed, int duplicates, int pointDuplicates) {
this.processed = processed;
this.duplicates = duplicates;
this.pointDuplicates = pointDuplicates;
}
}
// 目录查找方法(保持不变)
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[] findSxDirectories(File watershedDir) {
File[] subDirs = watershedDir.listFiles(File::isDirectory);
if (subDirs != null) {
List<File> sxDirs = new ArrayList<>();
for (File subDir : subDirs) {
if (subDir.getName().contains("水系") || subDir.getName().matches("^HBWFF.*")) {
sxDirs.add(subDir);
}
}
return sxDirs.toArray(new File[0]);
}
return null;
}
private static File findCrossSectionDirectory(File sxDir) {
// 按照新目录结构:水系目录 > 电子数据 > 测量数据 > 防治对象断面成果 > 横断面成果表
File electronicDataDir = findSubDirectory(sxDir, "电子数据");
if (electronicDataDir == null) {
System.out.println("在 " + sxDir.getPath() + " 下未找到电子数据目录");
return null;
}
File measureDataDir = findSubDirectory(electronicDataDir, "测量数据");
if (measureDataDir == null) {
System.out.println("在 " + electronicDataDir.getPath() + " 下未找到测量数据目录");
return null;
}
File sectionResultDir = findSubDirectory(measureDataDir, dirName1);
if (sectionResultDir == null) {
System.out.println("在 " + measureDataDir.getPath() + " 下未找到" + dirName1 + "目录");
return null;
}
File crossSectionDir = findSubDirectory(sectionResultDir, "横断面成果表");
if (crossSectionDir == null) {
System.out.println("在 " + sectionResultDir.getPath() + " 下未找到横断面成果表目录");
return null;
}
return crossSectionDir;
}
private static File findSubDirectory(File parentDir, String dirName) {
File[] subDirs = parentDir.listFiles(File::isDirectory);
if (subDirs != null) {
for (File subDir : subDirs) {
if (subDir.getName().equals(dirName)) {
return subDir;
}
}
// 如果没有精确匹配,尝试包含匹配
for (File subDir : subDirs) {
if (subDir.getName().contains(dirName)) {
return subDir;
}
}
}
return null;
}
private static File[] findExcelFiles(File crossSectionDir) {
File[] files = crossSectionDir.listFiles((dir, name) ->
name.toLowerCase().endsWith(".xlsx"));
return files != null ? files : new File[0];
}
private static String extractCountyName(String dirName) {
return dirName.contains("、") ? dirName.split("、")[1].trim() : dirName;
}
private static String getCellValue(Sheet sheet, int rowNum, int colNum) {
Row row = sheet.getRow(rowNum);
if (row != null) {
Cell cell = row.getCell(colNum);
return getCellStringValue(cell);
}
return null;
}
private static String getCellStringValue(Cell cell) {
if (cell == null) return null;
try {
switch (cell.getCellType()) {
case STRING:
return cell.getStringCellValue().trim();
case NUMERIC:
double num = cell.getNumericCellValue();
return (num == (long) num) ? String.valueOf((long) num) : String.valueOf(num);
case BOOLEAN:
return String.valueOf(cell.getBooleanCellValue());
default:
return null;
}
} catch (Exception 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;
}
}
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); // 序号列
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;
}
}

View File

@ -0,0 +1,846 @@
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.sql.ResultSet;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Excel
*/
public class IaShzhVsurfaceDataImporter {
// 纵断面主表插入SQL
private static final String INSERT_VSURFACE_SQL =
"INSERT INTO SHZH_JCSJ.IA_M_VSURFACE " +
"(ZECD, ADCD, CHANNEL, ADDRESS, ISCTOWN, BASEELE, BASELGTD, BASELTTD, ELETYPE, " +
"METHOD, SIGNER, AUDID, STATUS, REMARK, MODITIME, ISENABLE, IMPORTYEAR, AUDBATCH, " +
"CADCD, GUID, INPUTTYPE, WSCD, SURFACE_CLASSIFY, OBJECT_NAME) " +
"VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
// 纵断面点表插入SQL
private static final String INSERT_VSPOINT_SQL =
"INSERT INTO SHZH_JCSJ.IA_M_VSPOINT " +
"(ZSURFACEID, TRANSECTNAME, FID, POINT, DISTANCE, DIRECTION, HDEELE, SMEELE, " +
"LGTD, LTTD, MODITIME, REMARK, GUID, CHANNEL) " +
"VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
// 检查纵断面主表重复的SQL
private static final String CHECK_VSURFACE_DUPLICATE_SQL =
"SELECT COUNT(*) FROM SHZH_JCSJ.IA_M_VSURFACE WHERE ZECD = ? and SURFACE_CLASSIFY = ?";
// 检查纵断面点表重复的SQL
private static final String CHECK_VSPOINT_DUPLICATE_SQL =
"SELECT COUNT(*) FROM SHZH_JCSJ.IA_M_VSPOINT WHERE ZSURFACEID = ? AND FID = ?";
public static void main(String[] args) {
// 测试用的固定路径
// args = new String[]{"C:\\Users\\gsiot\\Desktop\\项目资料\\山洪\\小流域\\111"};
// args = new String[]{"F:\\1111-湖工大50条成果-已通过初检-待入库"};
// args = new String[]{"F:\\3333-2024年度咸宁市8条20251017-已通过初检-待入库"};
// args = new String[]{"F:\\4444-长江科学院-黄冈28条-已通过初检-已统一表头-待入库"};
args = new String[]{"I:\\7777-华科-咸宁市8条1027-已通过初检-已统一表头-已入库"};
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;
int totalDuplicates = 0;
int totalPointDuplicates = 0;
System.out.println("找到 " + countyDirs.length + " 个县市文件夹");
for (File countyDir : countyDirs) {
String countyName = extractCountyName(countyDir.getName());
System.out.println("\n=== 处理县市: " + countyName + " ===");
try {
ProcessResult result = processCountyData(countyDir, countyName);
totalProcessed += result.processed;
totalDuplicates += result.duplicates;
totalPointDuplicates += result.pointDuplicates;
totalSuccess++;
System.out.println("✓ 成功处理 " + countyName +
",导入 " + result.processed + " 条记录,跳过 " + result.duplicates +
" 条重复记录,断面点跳过 " + result.pointDuplicates + " 条重复记录");
} catch (Exception e) {
System.err.println("✗ 处理县市 " + countyName + " 时出错: " + e.getMessage());
}
}
System.out.println("\n=== 处理完成 ===");
System.out.println("成功处理县市: " + totalSuccess + " 个");
System.out.println("总导入记录: " + totalProcessed + " 条");
System.out.println("纵断面主表跳过重复记录: " + totalDuplicates + " 条");
System.out.println("纵断面点表跳过重复记录: " + totalPointDuplicates + " 条");
}
private static ProcessResult processCountyData(File countyDir, String countyName) throws Exception {
int totalProcessed = 0;
int totalDuplicates = 0;
int totalPointDuplicates = 0;
// 查找小流域目录
File watershedDir = findWatershedDirectory(countyDir);
if (watershedDir == null) {
System.out.println("在 " + countyName + " 下未找到小流域目录");
return new ProcessResult(0, 0, 0);
}
System.out.println("找到小流域目录: " + watershedDir.getName());
// 查找所有水系目录
File[] sxDirs = findSxDirectories(watershedDir);
if (sxDirs == null || sxDirs.length == 0) {
System.out.println("在 " + watershedDir.getPath() + " 下未找到水系目录");
return new ProcessResult(0, 0, 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());
ProcessResult result = processSxData(sxDir, countyName);
totalProcessed += result.processed;
totalDuplicates += result.duplicates;
totalPointDuplicates += result.pointDuplicates;
System.out.println("水系 " + sxDir.getName() + " 导入 " + result.processed + " 条记录,跳过 " +
result.duplicates + " 条重复记录,断面点跳过 " + result.pointDuplicates + " 条重复记录");
}
return new ProcessResult(totalProcessed, totalDuplicates, totalPointDuplicates);
}
private static ProcessResult processSxData(File sxDir, String countyName) throws Exception {
int processedCount = 0;
int duplicateCount = 0;
int pointDuplicateCount = 0;
// 按照新的目录结构查找文件
File crossSectionDir = findCrossSectionDirectory(sxDir);
if (crossSectionDir == null) {
System.out.println("在 " + sxDir.getPath() + " 下未找到纵断面成果表目录");
return new ProcessResult(0, 0, 0);
}
System.out.println("找到纵断面成果表目录: " + crossSectionDir.getPath());
// 查找所有Excel文件
File[] excelFiles = findExcelFiles(crossSectionDir);
if (excelFiles == null || excelFiles.length == 0) {
System.out.println("在 " + crossSectionDir.getPath() + " 下未找到纵断面Excel文件");
return new ProcessResult(0, 0, 0);
}
System.out.println("找到 " + excelFiles.length + " 个纵断面Excel文件:");
for (File excelFile : excelFiles) {
System.out.println(" - " + excelFile.getName());
}
// 提取流域编码
String watershedCode = CommonUtils.extractWatershedCode(sxDir.getName());
System.out.println("流域编码: " + watershedCode);
// 处理每个Excel文件
for (File excelFile : excelFiles) {
System.out.println("\n处理文件: " + excelFile.getName());
try {
// 验证文件是否为有效Excel文件
if (!isValidExcelFile(excelFile)) {
System.err.println("跳过无效的Excel文件: " + excelFile.getName());
continue;
}
ProcessResult result = readExcelAndImport(excelFile, countyName, watershedCode);
processedCount += result.processed;
duplicateCount += result.duplicates;
pointDuplicateCount += result.pointDuplicates;
System.out.println("文件 " + excelFile.getName() + " 导入 " + result.processed +
" 条记录,跳过 " + result.duplicates + " 条重复记录");
} catch (Exception e) {
System.err.println("处理文件 " + excelFile.getName() + " 时出错: " + e.getMessage());
if (e.getMessage().contains("valid OOXML")) {
System.err.println(" 文件可能损坏或格式不正确,跳过此文件");
}
// 继续处理下一个文件
}
}
return new ProcessResult(processedCount, duplicateCount, pointDuplicateCount);
}
/**
* Excel
*/
private static boolean isValidExcelFile(File file) {
if (!file.exists() || !file.isFile()) {
return false;
}
// 检查文件扩展名
String fileName = file.getName().toLowerCase();
if (!fileName.endsWith(".xlsx")) {
System.err.println("文件扩展名不是.xlsx: " + file.getName());
return false;
}
// 检查文件大小
if (file.length() == 0) {
System.err.println("文件大小为0: " + file.getName());
return false;
}
// 尝试打开文件验证格式
try (FileInputStream fis = new FileInputStream(file)) {
// 只读取文件头进行验证,不加载整个文件
byte[] header = new byte[4];
if (fis.read(header) != 4) {
return false;
}
// Excel文件的文件头特征
if (header[0] != 0x50 || header[1] != 0x4B || header[2] != 0x03 || header[3] != 0x04) {
System.err.println("文件头不符合Excel格式: " + file.getName());
return false;
}
return true;
} catch (Exception e) {
System.err.println("验证Excel文件失败: " + file.getName() + " - " + e.getMessage());
return false;
}
}
private static ProcessResult readExcelAndImport(File excelFile, String countyName, String wscd) throws Exception {
int importedCount = 0;
int duplicateCount = 0;
int pointDuplicateCount = 0;
// 先读取所有数据到内存
List<Object[]> vsurfaceDataList = new ArrayList<>();
List<Object[]> vspointDataList = new ArrayList<>();
readExcelData(wscd, excelFile, vsurfaceDataList, vspointDataList);
if (vsurfaceDataList.isEmpty()) {
System.out.println("未读取到有效数据");
return new ProcessResult(0, 0, 0);
}
System.out.println("成功读取 " + vsurfaceDataList.size() + " 条纵断面数据,包含 " +
vspointDataList.size() + " 个断面点,开始导入数据库...");
// 批量导入数据库
ProcessResult result = batchInsertData(vsurfaceDataList, vspointDataList);
return result;
}
private static void readExcelData(String wscd, File excelFile,
List<Object[]> vsurfaceDataList,
List<Object[]> vspointDataList) throws Exception {
try (FileInputStream fis = new FileInputStream(excelFile);
Workbook workbook = new XSSFWorkbook(fis)) {
String surfaceClassify=excelFile.getName();
Pattern pattern = Pattern.compile("^[a-zA-Z0-9]+");
Matcher matcher = pattern.matcher(surfaceClassify);
if(matcher.find()){
surfaceClassify=matcher.group();
}else{
System.out.println("工作表表名有问题: " + surfaceClassify);
}
// 遍历所有工作表
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);
// 解析纵断面主表数据
Object[] vsurfaceData = parseVsurfaceData(sheet, sheetName, wscd, surfaceClassify);
if (vsurfaceData != null) {
vsurfaceDataList.add(vsurfaceData);
System.out.println("✓ 解析纵断面主表数据成功: " + sheetName);
// 解析断面点数据
List<Object[]> points = parseVspointData(sheet, (String) vsurfaceData[19]); // guid作为vsurfaceID
vspointDataList.addAll(points);
System.out.println("✓ 解析 " + points.size() + " 个断面点数据");
} else {
System.out.println("✗ 解析纵断面主表数据失败: " + sheetName);
}
}
}
}
private static Object[] parseVsurfaceData(Sheet sheet, String sheetName, String wscd, String surfaceClassify) {
try {
Object[] data = new Object[24]; // 对应24个插入参数
int index = 0;
// 根据Excel格式解析数据
// 第1行C列-所在位置
String location = getCellValue(sheet, 0, 2); // C1单元格
// 第2行C列-所在沟道G列-行政区划代码
String channel = getCellValue(sheet, 1, 2); // C2单元格
String adminCode = getCellValue(sheet, 1, 6); // G2单元格
// 第3行C列-是否跨县
String isCrossCounty = getCellValue(sheet, 2, 2); // C3单元格
// 第4行C列-控制点纬度G列-控制点高程
String baseLatitude = getCellValue(sheet, 3, 2); // C4单元格 - 控制点纬度
String baseElevation = getCellValue(sheet, 3, 6); // G4单元格 - 控制点高程
// 第5行C列-高程系G列-测量方法
String elevationType = getCellValue(sheet, 4, 2); // C5单元格 - 高程系
String method = getCellValue(sheet, 4, 6); // G5单元格 - 测量方法
// 控制点经度在Excel中没有明确位置设为空
String baseLongitude = null;
// 1. ZECD - 纵断面编码 (工作表名)
data[index++] = sheetName;
// 2. ADCD - 行政区划代码
data[index++] = getSafeString(adminCode);
// 3. CHANNEL - 所在沟道
data[index++] = getSafeString(channel);
// 4. ADDRESS - 所在位置
data[index++] = getSafeString(location);
// 5. ISCTOWN - 是否跨县
data[index++] = getSafeString(isCrossCounty);
// 6. BASEELE - 控制点高程
data[index++] = getSafeString(baseElevation);
// 7. BASELGTD - 控制点经度
data[index++] = getSafeString(baseLongitude);
// 8. BASELTTD - 控制点纬度
data[index++] = getSafeString(baseLatitude);
// 9. ELETYPE - 高程系
data[index++] = getSafeString(elevationType);
// 10. METHOD - 测量方法
data[index++] = getSafeString(method);
// 11. SIGNER - 填写人姓名(默认为空)
data[index++] = null;
// 12. AUDID - 审核批次号(默认为空)
data[index++] = null;
// 13. STATUS - 状态默认1-待审核)
data[index++] = "1";
// 14. REMARK - 备注
data[index++] = null;
// 15. MODITIME - 时间戳
data[index++] = new Timestamp(System.currentTimeMillis());
// 16. ISENABLE - 启用状态
data[index++] = "1";
// 17. IMPORTYEAR - 导入年份
data[index++] = "2025";
// 18. AUDBATCH - 审核批次
data[index++] = "BATCH_" + System.currentTimeMillis();
// 19. CADCD - 县级编码(从行政区划代码提取)
data[index++] = adminCode != null && adminCode.length() >= 6 ?
adminCode.substring(0, 6)+"000000000" : "";
// 20. GUID - 唯一标识
String guid = UUID.randomUUID().toString();
data[index++] = guid;
// 21. INPUTTYPE - 录入方式
data[index++] = "1";
// 22. WSCD - 流域编码
data[index++] = wscd;
// 23. SURFACE_CLASSIFY - 断面分类
data[index++] = surfaceClassify;
// 24. OBJECT_NAME - 对象名称(使用沟道名称)
data[index++] = null;
return data;
} catch (Exception e) {
System.err.println("解析纵断面主表数据失败: " + e.getMessage());
e.printStackTrace();
return null;
}
}
private static List<Object[]> parseVspointData(Sheet sheet, String vsurfaceId) {
List<Object[]> points = new ArrayList<>();
try {
// 找到数据开始行从第7行开始序号列开始
int startRow = 6; // 根据Excel格式数据从第7行开始
System.out.println("断面点数据从第 " + (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[] pointData = parseVspointRowData(row, vsurfaceId, i - startRow + 1);
if (pointData != null) {
points.add(pointData);
}
}
} catch (Exception e) {
System.err.println("解析断面点数据失败: " + e.getMessage());
e.printStackTrace();
}
return points;
}
private static Object[] parseVspointRowData(Row row, String vsurfaceId, int fid) {
try {
Object[] data = new Object[14]; // 对应14个插入参数
int index = 0;
// 1. ZSURFACEID - 纵断面主表ID
data[index++] = vsurfaceId;
// 2. TRANSECTNAME - 断面名称(使用测量点)
String measurePoint = getCellStringValue(row.getCell(1));
data[index++] = getSafeString(measurePoint);
// 3. FID - 断面序号
data[index++] = fid;
// 4. POINT - 断面信息-测量点
data[index++] = getSafeString(measurePoint);
// 5. DISTANCE - 断面信息-距离(m) - 第3列
data[index++] = parseDoubleWithDefault(getCellStringValue(row.getCell(2)));
// 6. DIRECTION - 量距方向(°) - 第4列
data[index++] = parseDoubleWithDefault(getCellStringValue(row.getCell(3)));
// 7. HDEELE - 断面信息-河底高程(m) - 第5列
data[index++] = parseDoubleWithDefault(getCellStringValue(row.getCell(4)));
// 8. SMEELE - 断面信息-水面高程(m) - 第6列
data[index++] = parseDoubleWithDefault(getCellStringValue(row.getCell(5)));
// 9. LGTD - 经度(°) - 第7列
data[index++] = parseDoubleWithDefault(getCellStringValue(row.getCell(6)));
// 10. LTTD - 纬度(°) - 第8列
data[index++] = parseDoubleWithDefault(getCellStringValue(row.getCell(7)));
// 11. MODITIME - 时间戳
data[index++] = new Timestamp(System.currentTimeMillis());
// 12. REMARK - 备注
data[index++] = null;
// 13. GUID - 唯一标识
data[index++] = UUID.randomUUID().toString();
// 14. CHANNEL - 量距方向(°) - 使用第4列的值
data[index++] = parseDoubleWithDefault(getCellStringValue(row.getCell(3)));
return data;
} catch (Exception e) {
System.err.println("解析断面点行数据失败: " + e.getMessage());
return null;
}
}
private static ProcessResult batchInsertData(List<Object[]> vsurfaceDataList, List<Object[]> vspointDataList) {
int importedCount = 0;
int duplicateCount = 0;
int pointDuplicateCount = 0;
Connection conn = null;
PreparedStatement vsurfacePstmt = null;
PreparedStatement vspointPstmt = null;
PreparedStatement checkVsurfaceDupPstmt = null;
PreparedStatement checkVspointDupPstmt = null;
try {
conn = DatabaseUtil.getConnection();
if (conn == null) {
System.err.println("无法获取数据库连接");
return new ProcessResult(0, 0, 0);
}
vsurfacePstmt = conn.prepareStatement(INSERT_VSURFACE_SQL);
vspointPstmt = conn.prepareStatement(INSERT_VSPOINT_SQL);
checkVsurfaceDupPstmt = conn.prepareStatement(CHECK_VSURFACE_DUPLICATE_SQL);
checkVspointDupPstmt = conn.prepareStatement(CHECK_VSPOINT_DUPLICATE_SQL);
conn.setAutoCommit(false); // 开启事务
// 处理纵断面主表数据
for (Object[] rowData : vsurfaceDataList) {
try {
String zecd = (String) rowData[0];
String surface_clasify = (String) rowData[22];
// 检查纵断面是否重复
checkVsurfaceDupPstmt.setString(1, zecd);
checkVsurfaceDupPstmt.setString(2, surface_clasify);
try (ResultSet rs = checkVsurfaceDupPstmt.executeQuery()) {
if (rs.next() && rs.getInt(1) > 0) {
duplicateCount++;
System.out.println("跳过重复纵断面: " + zecd);
continue;
}
}
// 插入数据 - 设置所有参数
setVsurfaceParameters(vsurfacePstmt, rowData);
vsurfacePstmt.executeUpdate();
importedCount++;
System.out.println("✓ 插入纵断面记录: " + zecd);
} catch (Exception e) {
System.err.println("纵断面数据插入失败: " + e.getMessage());
e.printStackTrace();
}
}
// 处理纵断面点表数据
int pointImportedCount = 0;
for (Object[] pointData : vspointDataList) {
try {
String vsurfaceId = (String) pointData[0];
Integer fid = (Integer) pointData[2];
// 检查断面点是否重复
checkVspointDupPstmt.setString(1, vsurfaceId);
checkVspointDupPstmt.setInt(2, fid);
try (ResultSet rs = checkVspointDupPstmt.executeQuery()) {
if (rs.next() && rs.getInt(1) > 0) {
pointDuplicateCount++;
continue;
}
}
// 插入数据 - 设置所有参数
setVspointParameters(vspointPstmt, pointData);
vspointPstmt.addBatch();
pointImportedCount++;
// 每10条执行一次批量插入
if (pointImportedCount % 10 == 0) {
vspointPstmt.executeBatch();
vspointPstmt.clearBatch(); // 清空批量
System.out.println("已批量插入 " + pointImportedCount + " 条断面点记录");
}
} catch (Exception e) {
System.err.println("断面点数据插入失败: " + e.getMessage());
e.printStackTrace();
}
}
// 执行剩余的断面点批量插入
if (pointImportedCount > 0) {
vspointPstmt.executeBatch();
System.out.println("最终批量插入完成,共 " + pointImportedCount + " 条断面点记录");
}
conn.commit(); // 提交事务
System.out.println("事务提交成功");
} catch (Exception e) {
System.err.println("批量插入数据失败: " + e.getMessage());
e.printStackTrace();
if (conn != null) {
try {
conn.rollback();
System.out.println("事务回滚成功");
} catch (Exception rollbackEx) {
System.err.println("事务回滚失败: " + rollbackEx.getMessage());
}
}
} finally {
// 关闭资源
closeResource(checkVspointDupPstmt);
closeResource(checkVsurfaceDupPstmt);
closeResource(vspointPstmt);
closeResource(vsurfacePstmt);
closeResource(conn);
}
return new ProcessResult(importedCount, duplicateCount, pointDuplicateCount);
}
// 设置纵断面主表参数
private static void setVsurfaceParameters(PreparedStatement pstmt, Object[] rowData) throws Exception {
for (int i = 0; i < rowData.length; i++) {
Object value = rowData[i];
if (value == null) {
pstmt.setNull(i + 1, java.sql.Types.NULL);
} else if (value instanceof String) {
pstmt.setString(i + 1, (String) value);
} else if (value instanceof Double) {
pstmt.setDouble(i + 1, (Double) value);
} else if (value instanceof Integer) {
pstmt.setInt(i + 1, (Integer) value);
} else if (value instanceof Timestamp) {
pstmt.setTimestamp(i + 1, (Timestamp) value);
} else {
pstmt.setObject(i + 1, value);
}
}
}
// 设置纵断面点表参数
private static void setVspointParameters(PreparedStatement pstmt, Object[] pointData) throws Exception {
for (int i = 0; i < pointData.length; i++) {
Object value = pointData[i];
if (value == null) {
pstmt.setNull(i + 1, java.sql.Types.NULL);
} else if (value instanceof String) {
pstmt.setString(i + 1, (String) value);
} else if (value instanceof Double) {
pstmt.setDouble(i + 1, (Double) value);
} else if (value instanceof Integer) {
pstmt.setInt(i + 1, (Integer) value);
} else if (value instanceof Timestamp) {
pstmt.setTimestamp(i + 1, (Timestamp) value);
} else {
pstmt.setObject(i + 1, value);
}
}
}
// 安全关闭资源的方法
private static void closeResource(AutoCloseable resource) {
if (resource != null) {
try {
resource.close();
} catch (Exception e) {
System.err.println("关闭资源时出错: " + e.getMessage());
}
}
}
// 辅助方法安全获取字符串避免null
private static String getSafeString(String value) {
return value != null ? value : "";
}
// 辅助方法解析Double提供默认值
private static Double parseDoubleWithDefault(String value) {
if (value != null && !value.trim().isEmpty()) {
try {
return Double.parseDouble(value.trim());
} catch (NumberFormatException e) {
return 0.0;
}
}
return 0.0;
}
// 辅助方法
private static class ProcessResult {
int processed;
int duplicates;
int pointDuplicates;
ProcessResult(int processed, int duplicates, int pointDuplicates) {
this.processed = processed;
this.duplicates = duplicates;
this.pointDuplicates = pointDuplicates;
}
}
// 目录查找方法(保持不变)
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[] findSxDirectories(File watershedDir) {
File[] subDirs = watershedDir.listFiles(File::isDirectory);
if (subDirs != null) {
List<File> sxDirs = new ArrayList<>();
for (File subDir : subDirs) {
if (subDir.getName().contains("水系") || subDir.getName().matches("^HBWF.*")) {
sxDirs.add(subDir);
}
}
return sxDirs.toArray(new File[0]);
}
return null;
}
private static File findCrossSectionDirectory(File sxDir) {
// 按照新目录结构:水系目录 > 电子数据 > 测量数据 > 防治对象断面成果 > 纵断面成果表
File electronicDataDir = findSubDirectory(sxDir, "电子数据");
if (electronicDataDir == null) {
System.out.println("在 " + sxDir.getPath() + " 下未找到电子数据目录");
return null;
}
File measureDataDir = findSubDirectory(electronicDataDir, "测量数据");
if (measureDataDir == null) {
System.out.println("在 " + electronicDataDir.getPath() + " 下未找到测量数据目录");
return null;
}
File sectionResultDir = findSubDirectory(measureDataDir, "防治对象断面成果");
if (sectionResultDir == null) {
System.out.println("在 " + measureDataDir.getPath() + " 下未找到防治对象断面成果目录");
return null;
}
File crossSectionDir = findSubDirectory(sectionResultDir, "纵断面成果表");
if (crossSectionDir == null) {
System.out.println("在 " + sectionResultDir.getPath() + " 下未找到纵断面成果表目录");
return null;
}
return crossSectionDir;
}
private static File findSubDirectory(File parentDir, String dirName) {
File[] subDirs = parentDir.listFiles(File::isDirectory);
if (subDirs != null) {
for (File subDir : subDirs) {
if (subDir.getName().equals(dirName)) {
return subDir;
}
}
// 如果没有精确匹配,尝试包含匹配
for (File subDir : subDirs) {
if (subDir.getName().contains(dirName)) {
return subDir;
}
}
}
return null;
}
private static File[] findExcelFiles(File crossSectionDir) {
File[] files = crossSectionDir.listFiles((dir, name) ->
name.toLowerCase().endsWith(".xlsx"));
return files != null ? files : new File[0];
}
private static String extractCountyName(String dirName) {
return dirName.contains("、") ? dirName.split("、")[1].trim() : dirName;
}
private static String getCellValue(Sheet sheet, int rowNum, int colNum) {
Row row = sheet.getRow(rowNum);
if (row != null) {
Cell cell = row.getCell(colNum);
return getCellStringValue(cell);
}
return null;
}
private static String getCellStringValue(Cell cell) {
if (cell == null) return null;
try {
switch (cell.getCellType()) {
case STRING:
return cell.getStringCellValue().trim();
case NUMERIC:
double num = cell.getNumericCellValue();
return (num == (long) num) ? String.valueOf((long) num) : String.valueOf(num);
case BOOLEAN:
return String.valueOf(cell.getBooleanCellValue());
default:
return null;
}
} catch (Exception 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;
}
}
}

View File

@ -0,0 +1,864 @@
package org.example;
import org.apache.poi.openxml4j.util.ZipSecureFile;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
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.sql.ResultSet;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* ---------Excel
*/
public class IaShzhVsurfaceDataImporter2 {
// 纵断面主表插入SQL
private static final String INSERT_VSURFACE_SQL =
"INSERT INTO SHZH_JCSJ.IA_M_VSURFACE " +
"(ZECD, ADCD, CHANNEL, ADDRESS, ISCTOWN, BASEELE, BASELGTD, BASELTTD, ELETYPE, " +
"METHOD, SIGNER, AUDID, STATUS, REMARK, MODITIME, ISENABLE, IMPORTYEAR, AUDBATCH, " +
"CADCD, GUID, INPUTTYPE, WSCD, SURFACE_CLASSIFY, OBJECT_NAME) " +
"VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
// 纵断面点表插入SQL
private static final String INSERT_VSPOINT_SQL =
"INSERT INTO SHZH_JCSJ.IA_M_VSPOINT " +
"(ZSURFACEID, TRANSECTNAME, FID, POINT, DISTANCE, DIRECTION, HDEELE, SMEELE, " +
"LGTD, LTTD, MODITIME, REMARK, GUID, CHANNEL) " +
"VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
// 检查纵断面主表重复的SQL
private static final String CHECK_VSURFACE_DUPLICATE_SQL =
"SELECT COUNT(*) FROM SHZH_JCSJ.IA_M_VSURFACE WHERE ZECD = ? and SURFACE_CLASSIFY = ?";
// 检查纵断面点表重复的SQL
private static final String CHECK_VSPOINT_DUPLICATE_SQL =
"SELECT COUNT(*) FROM SHZH_JCSJ.IA_M_VSPOINT WHERE ZSURFACEID = ? AND FID = ?";
public static void main(String[] args) {
// 测试用的固定路径
// args = new String[]{"C:\\Users\\gsiot\\Desktop\\项目资料\\山洪\\小流域\\111"};
// args = new String[]{"F:\\1111-湖工大50条成果-已通过初检-待入库"};
// args = new String[]{"F:\\3333-2024年度咸宁市8条20251017-已通过初检-待入库"};
// args = new String[]{"F:\\4444-长江科学院-黄冈28条-已通过初检-已统一表头-待入库"};
args = new String[]{"C:\\Users\\gsiot\\Desktop\\项目资料\\山洪\\小流域\\111"};
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;
int totalDuplicates = 0;
int totalPointDuplicates = 0;
System.out.println("找到 " + countyDirs.length + " 个县市文件夹");
for (File countyDir : countyDirs) {
String countyName = extractCountyName(countyDir.getName());
System.out.println("\n=== 处理县市: " + countyName + " ===");
try {
ProcessResult result = processCountyData(countyDir, countyName);
totalProcessed += result.processed;
totalDuplicates += result.duplicates;
totalPointDuplicates += result.pointDuplicates;
totalSuccess++;
System.out.println("✓ 成功处理 " + countyName +
",导入 " + result.processed + " 条记录,跳过 " + result.duplicates +
" 条重复记录,断面点跳过 " + result.pointDuplicates + " 条重复记录");
} catch (Exception e) {
System.err.println("✗ 处理县市 " + countyName + " 时出错: " + e.getMessage());
}
}
System.out.println("\n=== 处理完成 ===");
System.out.println("成功处理县市: " + totalSuccess + " 个");
System.out.println("总导入记录: " + totalProcessed + " 条");
System.out.println("纵断面主表跳过重复记录: " + totalDuplicates + " 条");
System.out.println("纵断面点表跳过重复记录: " + totalPointDuplicates + " 条");
}
private static ProcessResult processCountyData(File countyDir, String countyName) throws Exception {
int totalProcessed = 0;
int totalDuplicates = 0;
int totalPointDuplicates = 0;
// 查找小流域目录
File watershedDir = findWatershedDirectory(countyDir);
if (watershedDir == null) {
System.out.println("在 " + countyName + " 下未找到小流域目录");
return new ProcessResult(0, 0, 0);
}
System.out.println("找到小流域目录: " + watershedDir.getName());
// 查找所有水系目录
File[] sxDirs = findSxDirectories(watershedDir);
if (sxDirs == null || sxDirs.length == 0) {
System.out.println("在 " + watershedDir.getPath() + " 下未找到水系目录");
return new ProcessResult(0, 0, 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());
ProcessResult result = processSxData(sxDir, countyName);
totalProcessed += result.processed;
totalDuplicates += result.duplicates;
totalPointDuplicates += result.pointDuplicates;
System.out.println("水系 " + sxDir.getName() + " 导入 " + result.processed + " 条记录,跳过 " +
result.duplicates + " 条重复记录,断面点跳过 " + result.pointDuplicates + " 条重复记录");
}
return new ProcessResult(totalProcessed, totalDuplicates, totalPointDuplicates);
}
private static ProcessResult processSxData(File sxDir, String countyName) throws Exception {
int processedCount = 0;
int duplicateCount = 0;
int pointDuplicateCount = 0;
// 按照新的目录结构查找文件
File crossSectionDir = findCrossSectionDirectory(sxDir);
if (crossSectionDir == null) {
System.out.println("在 " + sxDir.getPath() + " 下未找到纵断面成果表目录");
return new ProcessResult(0, 0, 0);
}
System.out.println("找到纵断面成果表目录: " + crossSectionDir.getPath());
// 查找所有Excel文件
File[] excelFiles = findExcelFiles(crossSectionDir);
if (excelFiles == null || excelFiles.length == 0) {
System.out.println("在 " + crossSectionDir.getPath() + " 下未找到纵断面Excel文件");
return new ProcessResult(0, 0, 0);
}
System.out.println("找到 " + excelFiles.length + " 个纵断面Excel文件:");
for (File excelFile : excelFiles) {
System.out.println(" - " + excelFile.getName());
}
// 提取流域编码
String watershedCode = CommonUtils.extractWatershedCode(sxDir.getName());
System.out.println("流域编码: " + watershedCode);
// 处理每个Excel文件
for (File excelFile : excelFiles) {
System.out.println("\n处理文件: " + excelFile.getName());
try {
// 验证文件是否为有效Excel文件
if (!isValidExcelFile(excelFile)) {
System.err.println("跳过无效的Excel文件: " + excelFile.getName());
continue;
}
ProcessResult result = readExcelAndImport(excelFile, countyName, watershedCode);
processedCount += result.processed;
duplicateCount += result.duplicates;
pointDuplicateCount += result.pointDuplicates;
System.out.println("文件 " + excelFile.getName() + " 导入 " + result.processed +
" 条记录,跳过 " + result.duplicates + " 条重复记录");
} catch (Exception e) {
System.err.println("处理文件 " + excelFile.getName() + " 时出错: " + e.getMessage());
if (e.getMessage().contains("valid OOXML")) {
System.err.println(" 文件可能损坏或格式不正确,跳过此文件");
}
// 继续处理下一个文件
}
}
return new ProcessResult(processedCount, duplicateCount, pointDuplicateCount);
}
/**
* Excel
*/
private static boolean isValidExcelFile(File file) {
if (!file.exists() || !file.isFile()) {
return false;
}
// 检查文件扩展名
String fileName = file.getName().toLowerCase();
if (!fileName.endsWith(".xlsx")) {
System.err.println("文件扩展名不是.xlsx: " + file.getName());
return false;
}
// 检查文件大小
if (file.length() == 0) {
System.err.println("文件大小为0: " + file.getName());
return false;
}
// 尝试打开文件验证格式
try (FileInputStream fis = new FileInputStream(file)) {
// 只读取文件头进行验证,不加载整个文件
byte[] header = new byte[4];
if (fis.read(header) != 4) {
return false;
}
// Excel文件的文件头特征
if (header[0] != 0x50 || header[1] != 0x4B || header[2] != 0x03 || header[3] != 0x04) {
System.err.println("文件头不符合Excel格式: " + file.getName());
return false;
}
return true;
} catch (Exception e) {
System.err.println("验证Excel文件失败: " + file.getName() + " - " + e.getMessage());
return false;
}
}
private static ProcessResult readExcelAndImport(File excelFile, String countyName, String wscd) throws Exception {
int importedCount = 0;
int duplicateCount = 0;
int pointDuplicateCount = 0;
// 先读取所有数据到内存
List<Object[]> vsurfaceDataList = new ArrayList<>();
List<Object[]> vspointDataList = new ArrayList<>();
readExcelData(wscd, excelFile, vsurfaceDataList, vspointDataList);
if (vsurfaceDataList.isEmpty()) {
System.out.println("未读取到有效数据");
return new ProcessResult(0, 0, 0);
}
System.out.println("成功读取 " + vsurfaceDataList.size() + " 条纵断面数据,包含 " +
vspointDataList.size() + " 个断面点,开始导入数据库...");
// 批量导入数据库
ProcessResult result = batchInsertData(vsurfaceDataList, vspointDataList);
return result;
}
private static void readExcelData(String wscd, File excelFile,
List<Object[]> vsurfaceDataList,
List<Object[]> vspointDataList) throws Exception {
// 保存原始设置
double originalRatio = ZipSecureFile.getMinInflateRatio();
try {
// 临时调整安全阈值
ZipSecureFile.setMinInflateRatio(0.001);
try (FileInputStream fis = new FileInputStream(excelFile);
Workbook workbook = new XSSFWorkbook(fis)) {
String surfaceClassify=excelFile.getName();
Pattern pattern = Pattern.compile("^[a-zA-Z0-9]+");
Matcher matcher = pattern.matcher(surfaceClassify);
if(matcher.find()){
surfaceClassify=matcher.group();
}else{
System.out.println("工作表表名有问题: " + surfaceClassify);
}
// 遍历所有工作表
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);
try {
// 解析纵断面主表数据
Object[] vsurfaceData = parseVsurfaceData(sheet, sheetName, wscd, surfaceClassify);
if (vsurfaceData != null) {
vsurfaceDataList.add(vsurfaceData);
System.out.println("✓ 解析纵断面主表数据成功: " + sheetName);
// 解析断面点数据
List<Object[]> points = parseVspointData(sheet, (String) vsurfaceData[19]);
vspointDataList.addAll(points);
System.out.println("✓ 解析 " + points.size() + " 个断面点数据");
}
} catch (Exception e) {
System.err.println("解析工作表 " + sheetName + " 时出错: " + e.getMessage());
}
}
}
} finally {
// 恢复原始设置
ZipSecureFile.setMinInflateRatio(originalRatio);
}
}
private static Object[] parseVsurfaceData(Sheet sheet, String sheetName, String wscd, String surfaceClassify) {
try {
Object[] data = new Object[24]; // 对应24个插入参数
int index = 0;
// 根据Excel格式解析数据
// 第1行C列-所在位置
String location = getCellValue(sheet, 0, 2); // C1单元格
// 第2行C列-所在沟道G列-行政区划代码
String channel = getCellValue(sheet, 1, 2); // C2单元格
String adminCode = getCellValue(sheet, 1, 6); // G2单元格
// 第3行C列-是否跨县
String isCrossCounty = getCellValue(sheet, 2, 2); // C3单元格
// 第4行C列-控制点纬度G列-控制点高程
String baseLatitude = getCellValue(sheet, 3, 2); // C4单元格 - 控制点纬度
String baseElevation = getCellValue(sheet, 3, 6); // G4单元格 - 控制点高程
// 第5行C列-高程系G列-测量方法
String elevationType = getCellValue(sheet, 4, 2); // C5单元格 - 高程系
String method = getCellValue(sheet, 4, 6); // G5单元格 - 测量方法
// 控制点经度在Excel中没有明确位置设为空
String baseLongitude = null;
// 1. ZECD - 纵断面编码 (工作表名)
data[index++] = sheetName;
// 2. ADCD - 行政区划代码
data[index++] = getSafeString(adminCode);
// 3. CHANNEL - 所在沟道
data[index++] = getSafeString(channel);
// 4. ADDRESS - 所在位置
data[index++] = getSafeString(location);
// 5. ISCTOWN - 是否跨县
data[index++] = getSafeString(isCrossCounty);
// 6. BASEELE - 控制点高程
data[index++] = getSafeString(baseElevation);
// 7. BASELGTD - 控制点经度
data[index++] = getSafeString(baseLongitude);
// 8. BASELTTD - 控制点纬度
data[index++] = getSafeString(baseLatitude);
// 9. ELETYPE - 高程系
data[index++] = getSafeString(elevationType);
// 10. METHOD - 测量方法
data[index++] = getSafeString(method);
// 11. SIGNER - 填写人姓名(默认为空)
data[index++] = null;
// 12. AUDID - 审核批次号(默认为空)
data[index++] = null;
// 13. STATUS - 状态默认1-待审核)
data[index++] = "1";
// 14. REMARK - 备注
data[index++] = null;
// 15. MODITIME - 时间戳
data[index++] = new Timestamp(System.currentTimeMillis());
// 16. ISENABLE - 启用状态
data[index++] = "1";
// 17. IMPORTYEAR - 导入年份
data[index++] = "2025";
// 18. AUDBATCH - 审核批次
data[index++] = "BATCH_" + System.currentTimeMillis();
// 19. CADCD - 县级编码(从行政区划代码提取)
data[index++] = adminCode != null && adminCode.length() >= 6 ?
adminCode.substring(0, 6)+"000000000" : "";
// 20. GUID - 唯一标识
String guid = UUID.randomUUID().toString();
data[index++] = guid;
// 21. INPUTTYPE - 录入方式
data[index++] = "1";
// 22. WSCD - 流域编码
data[index++] = wscd;
// 23. SURFACE_CLASSIFY - 断面分类
data[index++] = surfaceClassify;
// 24. OBJECT_NAME - 对象名称(使用沟道名称)
data[index++] = null;
return data;
} catch (Exception e) {
System.err.println("解析纵断面主表数据失败: " + e.getMessage());
e.printStackTrace();
return null;
}
}
private static List<Object[]> parseVspointData(Sheet sheet, String vsurfaceId) {
List<Object[]> points = new ArrayList<>();
try {
// 找到数据开始行从第7行开始序号列开始
int startRow = 6; // 根据Excel格式数据从第7行开始
System.out.println("断面点数据从第 " + (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[] pointData = parseVspointRowData(row, vsurfaceId, i - startRow + 1);
if (pointData != null) {
points.add(pointData);
}
}
} catch (Exception e) {
System.err.println("解析断面点数据失败: " + e.getMessage());
e.printStackTrace();
}
return points;
}
private static Object[] parseVspointRowData(Row row, String vsurfaceId, int fid) {
try {
Object[] data = new Object[14]; // 对应14个插入参数
int index = 0;
// 1. ZSURFACEID - 纵断面主表ID
data[index++] = vsurfaceId;
// 2. TRANSECTNAME - 断面名称(使用测量点)
String measurePoint = getCellStringValue(row.getCell(1));
data[index++] = getSafeString(measurePoint);
// 3. FID - 断面序号
data[index++] = fid;
// 4. POINT - 断面信息-测量点
data[index++] = getSafeString(measurePoint);
// 5. DISTANCE - 断面信息-距离(m) - 第3列
data[index++] = parseDoubleWithDefault(getCellStringValue(row.getCell(2)));
// 6. DIRECTION - 量距方向(°) - 第4列
data[index++] = parseDoubleWithDefault(getCellStringValue(row.getCell(3)));
// 7. HDEELE - 断面信息-河底高程(m) - 第5列
data[index++] = parseDoubleWithDefault(getCellStringValue(row.getCell(4)));
// 8. SMEELE - 断面信息-水面高程(m) - 第6列
data[index++] = parseDoubleWithDefault(getCellStringValue(row.getCell(5)));
// 9. LGTD - 经度(°) - 第7列
data[index++] = parseDoubleWithDefault(getCellStringValue(row.getCell(6)));
// 10. LTTD - 纬度(°) - 第8列
data[index++] = parseDoubleWithDefault(getCellStringValue(row.getCell(7)));
// 11. MODITIME - 时间戳
data[index++] = new Timestamp(System.currentTimeMillis());
// 12. REMARK - 备注
data[index++] = null;
// 13. GUID - 唯一标识
data[index++] = UUID.randomUUID().toString();
// 14. CHANNEL - 量距方向(°) - 使用第4列的值
data[index++] = parseDoubleWithDefault(getCellStringValue(row.getCell(3)));
return data;
} catch (Exception e) {
System.err.println("解析断面点行数据失败: " + e.getMessage());
return null;
}
}
private static ProcessResult batchInsertData(List<Object[]> vsurfaceDataList, List<Object[]> vspointDataList) {
int importedCount = 0;
int duplicateCount = 0;
int pointDuplicateCount = 0;
Connection conn = null;
PreparedStatement vsurfacePstmt = null;
PreparedStatement vspointPstmt = null;
PreparedStatement checkVsurfaceDupPstmt = null;
PreparedStatement checkVspointDupPstmt = null;
try {
conn = DatabaseUtil.getConnection();
if (conn == null) {
System.err.println("无法获取数据库连接");
return new ProcessResult(0, 0, 0);
}
vsurfacePstmt = conn.prepareStatement(INSERT_VSURFACE_SQL);
vspointPstmt = conn.prepareStatement(INSERT_VSPOINT_SQL);
checkVsurfaceDupPstmt = conn.prepareStatement(CHECK_VSURFACE_DUPLICATE_SQL);
checkVspointDupPstmt = conn.prepareStatement(CHECK_VSPOINT_DUPLICATE_SQL);
conn.setAutoCommit(false); // 开启事务
// 处理纵断面主表数据
for (Object[] rowData : vsurfaceDataList) {
try {
String zecd = (String) rowData[0];
String surface_clasify = (String) rowData[22];
// 检查纵断面是否重复
checkVsurfaceDupPstmt.setString(1, zecd);
checkVsurfaceDupPstmt.setString(2, surface_clasify);
try (ResultSet rs = checkVsurfaceDupPstmt.executeQuery()) {
if (rs.next() && rs.getInt(1) > 0) {
duplicateCount++;
System.out.println("跳过重复纵断面: " + zecd);
continue;
}
}
// 插入数据 - 设置所有参数
setVsurfaceParameters(vsurfacePstmt, rowData);
vsurfacePstmt.executeUpdate();
importedCount++;
System.out.println("✓ 插入纵断面记录: " + zecd);
} catch (Exception e) {
System.err.println("纵断面数据插入失败: " + e.getMessage());
e.printStackTrace();
}
}
// 处理纵断面点表数据
int pointImportedCount = 0;
for (Object[] pointData : vspointDataList) {
try {
String vsurfaceId = (String) pointData[0];
Integer fid = (Integer) pointData[2];
// 检查断面点是否重复
checkVspointDupPstmt.setString(1, vsurfaceId);
checkVspointDupPstmt.setInt(2, fid);
try (ResultSet rs = checkVspointDupPstmt.executeQuery()) {
if (rs.next() && rs.getInt(1) > 0) {
pointDuplicateCount++;
continue;
}
}
// 插入数据 - 设置所有参数
setVspointParameters(vspointPstmt, pointData);
vspointPstmt.addBatch();
pointImportedCount++;
// 每10条执行一次批量插入
if (pointImportedCount % 10 == 0) {
vspointPstmt.executeBatch();
vspointPstmt.clearBatch(); // 清空批量
System.out.println("已批量插入 " + pointImportedCount + " 条断面点记录");
}
} catch (Exception e) {
System.err.println("断面点数据插入失败: " + e.getMessage());
e.printStackTrace();
}
}
// 执行剩余的断面点批量插入
if (pointImportedCount > 0) {
vspointPstmt.executeBatch();
System.out.println("最终批量插入完成,共 " + pointImportedCount + " 条断面点记录");
}
conn.commit(); // 提交事务
System.out.println("事务提交成功");
} catch (Exception e) {
System.err.println("批量插入数据失败: " + e.getMessage());
e.printStackTrace();
if (conn != null) {
try {
conn.rollback();
System.out.println("事务回滚成功");
} catch (Exception rollbackEx) {
System.err.println("事务回滚失败: " + rollbackEx.getMessage());
}
}
} finally {
// 关闭资源
closeResource(checkVspointDupPstmt);
closeResource(checkVsurfaceDupPstmt);
closeResource(vspointPstmt);
closeResource(vsurfacePstmt);
closeResource(conn);
}
return new ProcessResult(importedCount, duplicateCount, pointDuplicateCount);
}
// 设置纵断面主表参数
private static void setVsurfaceParameters(PreparedStatement pstmt, Object[] rowData) throws Exception {
for (int i = 0; i < rowData.length; i++) {
Object value = rowData[i];
if (value == null) {
pstmt.setNull(i + 1, java.sql.Types.NULL);
} else if (value instanceof String) {
pstmt.setString(i + 1, (String) value);
} else if (value instanceof Double) {
pstmt.setDouble(i + 1, (Double) value);
} else if (value instanceof Integer) {
pstmt.setInt(i + 1, (Integer) value);
} else if (value instanceof Timestamp) {
pstmt.setTimestamp(i + 1, (Timestamp) value);
} else {
pstmt.setObject(i + 1, value);
}
}
}
// 设置纵断面点表参数
private static void setVspointParameters(PreparedStatement pstmt, Object[] pointData) throws Exception {
for (int i = 0; i < pointData.length; i++) {
Object value = pointData[i];
if (value == null) {
pstmt.setNull(i + 1, java.sql.Types.NULL);
} else if (value instanceof String) {
pstmt.setString(i + 1, (String) value);
} else if (value instanceof Double) {
pstmt.setDouble(i + 1, (Double) value);
} else if (value instanceof Integer) {
pstmt.setInt(i + 1, (Integer) value);
} else if (value instanceof Timestamp) {
pstmt.setTimestamp(i + 1, (Timestamp) value);
} else {
pstmt.setObject(i + 1, value);
}
}
}
// 安全关闭资源的方法
private static void closeResource(AutoCloseable resource) {
if (resource != null) {
try {
resource.close();
} catch (Exception e) {
System.err.println("关闭资源时出错: " + e.getMessage());
}
}
}
// 辅助方法安全获取字符串避免null
private static String getSafeString(String value) {
return value != null ? value : "";
}
// 辅助方法解析Double提供默认值
private static Double parseDoubleWithDefault(String value) {
if (value != null && !value.trim().isEmpty()) {
try {
return Double.parseDouble(value.trim());
} catch (NumberFormatException e) {
return 0.0;
}
}
return 0.0;
}
// 辅助方法
private static class ProcessResult {
int processed;
int duplicates;
int pointDuplicates;
ProcessResult(int processed, int duplicates, int pointDuplicates) {
this.processed = processed;
this.duplicates = duplicates;
this.pointDuplicates = pointDuplicates;
}
}
// 目录查找方法(保持不变)
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[] findSxDirectories(File watershedDir) {
File[] subDirs = watershedDir.listFiles(File::isDirectory);
if (subDirs != null) {
List<File> sxDirs = new ArrayList<>();
for (File subDir : subDirs) {
if (subDir.getName().contains("水系") || subDir.getName().matches("^HBWFF.*")) {
sxDirs.add(subDir);
}
}
return sxDirs.toArray(new File[0]);
}
return null;
}
private static File findCrossSectionDirectory(File sxDir) {
// 按照新目录结构:水系目录 > 电子数据 > 测量数据 > 防治对象断面成果 > 纵断面成果表
File electronicDataDir = findSubDirectory(sxDir, "电子数据");
if (electronicDataDir == null) {
System.out.println("在 " + sxDir.getPath() + " 下未找到电子数据目录");
return null;
}
File measureDataDir = findSubDirectory(electronicDataDir, "测量数据");
if (measureDataDir == null) {
System.out.println("在 " + electronicDataDir.getPath() + " 下未找到测量数据目录");
return null;
}
File sectionResultDir = findSubDirectory(measureDataDir, "防治对象断面成果");
if (sectionResultDir == null) {
System.out.println("在 " + measureDataDir.getPath() + " 下未找到防治对象断面成果目录");
return null;
}
File crossSectionDir = findSubDirectory(sectionResultDir, "纵断面成果表");
if (crossSectionDir == null) {
System.out.println("在 " + sectionResultDir.getPath() + " 下未找到纵断面成果表目录");
return null;
}
return crossSectionDir;
}
private static File findSubDirectory(File parentDir, String dirName) {
File[] subDirs = parentDir.listFiles(File::isDirectory);
if (subDirs != null) {
for (File subDir : subDirs) {
if (subDir.getName().equals(dirName)) {
return subDir;
}
}
// 如果没有精确匹配,尝试包含匹配
for (File subDir : subDirs) {
if (subDir.getName().contains(dirName)) {
return subDir;
}
}
}
return null;
}
private static File[] findExcelFiles(File crossSectionDir) {
File[] files = crossSectionDir.listFiles((dir, name) ->
name.toLowerCase().endsWith(".xlsx"));
return files != null ? files : new File[0];
}
private static String extractCountyName(String dirName) {
return dirName.contains("、") ? dirName.split("、")[1].trim() : dirName;
}
private static String getCellValue(Sheet sheet, int rowNum, int colNum) {
Row row = sheet.getRow(rowNum);
if (row != null) {
Cell cell = row.getCell(colNum);
return getCellStringValue(cell);
}
return null;
}
private static String getCellStringValue(Cell cell) {
if (cell == null) return null;
try {
switch (cell.getCellType()) {
case STRING:
return cell.getStringCellValue().trim();
case NUMERIC:
double num = cell.getNumericCellValue();
return (num == (long) num) ? String.valueOf((long) num) : String.valueOf(num);
case BOOLEAN:
return String.valueOf(cell.getBooleanCellValue());
default:
return null;
}
} catch (Exception 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;
}
}
}

View File

@ -0,0 +1,588 @@
// MountainFloodStHdpImporter.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.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
/**
* 8====
*/
public class IaStHdpDataImporter {
// 防治对象-监测站点关系表插入SQL
private static final String INSERT_ST_HDP_SQL =
"INSERT INTO SHZH_JCSJ.IA_ST_HDP (" +
"ADCD, PCD, FSOURCE, STCD, TYPE, LGTD, LTTD, REMARK, ISENABLE, IMPORTYEAR, " +
"INPUTTYPE, AUDID, STATUS, SIGNER, CADCD, GUID, AUDBATCH, WSCD, PRENAME, STNM" +
") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
// 检查防治对象-监测站点重复的SQL
private static final String CHECK_ST_HDP_DUPLICATE_SQL =
"SELECT COUNT(*) FROM SHZH_JCSJ.IA_ST_HDP " +
"WHERE PCD = ? AND STCD = ? AND STNM = ?";
public static void main(String[] args) {
// 先测试数据库连接
if (!testDatabaseConnection()) {
System.err.println("数据库连接测试失败,程序退出");
return;
}
// 测试用的固定路径
// args = new String[]{"F:\\1111-湖工大50条成果-已通过初检-待入库"};
// args = new String[]{"F:\\4444-长江科学院-黄冈28条-已通过初检-已统一表头-待入库"};
args = new String[]{"I:\\8888-长科院-孝昌县8条1028-已通过初检-已统一表头-待入库"};
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 {
processAllStHdpTables(baseDirectory);
} catch (Exception e) {
System.err.println("处理过程中发生错误: " + e.getMessage());
e.printStackTrace();
}
}
private static boolean testDatabaseConnection() {
try {
Connection conn = DatabaseUtil.getConnection();
if (conn != null && !conn.isClosed()) {
System.out.println("✓ 数据库连接测试成功");
conn.close();
return true;
}
} catch (Exception e) {
System.err.println("✗ 数据库连接测试失败: " + e.getMessage());
}
return false;
}
private static void processAllStHdpTables(File baseDir) {
File[] countyDirs = baseDir.listFiles(File::isDirectory);
if (countyDirs == null) {
System.out.println("在基础目录下未找到任何县市文件夹");
return;
}
int totalProcessed = 0;
int totalSuccess = 0;
int totalDuplicates = 0;
System.out.println("开始处理防治对象-监测站点关系表...");
System.out.println("找到 " + countyDirs.length + " 个县市文件夹");
for (File countyDir : countyDirs) {
String countyName = extractCountyName(countyDir.getName());
System.out.println("\n=== 处理县市: " + countyName + " ===");
try {
ProcessResult result = processCountyStHdpData(countyDir, countyName);
totalProcessed += result.processed;
totalDuplicates += result.duplicates;
totalSuccess++;
System.out.println("✓ 成功处理 " + countyName +
",导入 " + result.processed + " 条记录,跳过 " + result.duplicates + " 条重复记录");
} catch (Exception e) {
System.err.println("✗ 处理县市 " + countyName + " 时出错: " + e.getMessage());
e.printStackTrace();
}
}
System.out.println("\n=== 防治对象-监测站点关系表处理完成 ===");
System.out.println("成功处理县市: " + totalSuccess + " 个");
System.out.println("总导入记录: " + totalProcessed + " 条");
System.out.println("总跳过重复记录: " + totalDuplicates + " 条");
}
private static ProcessResult processCountyStHdpData(File countyDir, String countyName) throws Exception {
int totalProcessed = 0;
int totalDuplicates = 0;
// 查找小流域目录
File watershedDir = findWatershedDirectory(countyDir);
if (watershedDir == null) {
System.out.println("在 " + countyName + " 下未找到小流域目录");
return new ProcessResult(0, 0);
}
System.out.println("找到小流域目录: " + watershedDir.getName());
// 查找所有水系目录
File[] sxDirs = findSxDirectories(watershedDir);
if (sxDirs == null || sxDirs.length == 0) {
System.out.println("在 " + watershedDir.getPath() + " 下未找到水系目录");
return new ProcessResult(0, 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());
ProcessResult result = processSxStHdpData(sxDir, countyName);
totalProcessed += result.processed;
totalDuplicates += result.duplicates;
System.out.println("水系 " + sxDir.getName() + " 导入 " + result.processed + " 条记录,跳过 " + result.duplicates + " 条重复记录");
}
return new ProcessResult(totalProcessed, totalDuplicates);
}
private static ProcessResult processSxStHdpData(File sxDir, String countyName) throws Exception {
int processedCount = 0;
int duplicateCount = 0;
// 查找成果报表目录
File reportDir = findReportDirectory(sxDir);
if (reportDir == null) {
System.out.println("在 " + sxDir.getPath() + " 下未找到成果报表目录");
return new ProcessResult(0, 0);
}
System.out.println("找到成果报表目录: " + reportDir.getPath());
// 查找Excel文件
File excelFile = findStHdpExcelFile(reportDir);
if (excelFile == null) {
System.out.println("在 " + reportDir.getPath() + " 下未找到表8 防治对象-监测站点关系表.xlsx");
return new ProcessResult(0, 0);
}
System.out.println("找到防治对象-监测站点关系表: " + excelFile.getPath());
// 提取流域编码
String watershedCode = CommonUtils.extractWatershedCode(sxDir.getName());
System.out.println("流域编码: " + watershedCode);
// 读取Excel文件并导入数据库
ProcessResult result = readStHdpExcelAndImport(excelFile, countyName, watershedCode);
return result;
}
private static ProcessResult readStHdpExcelAndImport(File excelFile, String countyName, String watershedCode) throws Exception {
int importedCount = 0;
int duplicateCount = 0;
// 读取所有数据到内存
List<Object[]> stHdpDataList = readStHdpExcelData(excelFile, countyName, watershedCode);
if (stHdpDataList.isEmpty()) {
System.out.println("未读取到有效数据");
return new ProcessResult(0, 0);
}
System.out.println("成功读取 " + stHdpDataList.size() + " 条数据,开始导入数据库...");
// 批量导入数据库
ProcessResult result = batchInsertStHdpData(stHdpDataList);
return result;
}
private static List<Object[]> readStHdpExcelData(File excelFile, String countyName, String watershedCode) throws Exception {
List<Object[]> 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 ("填表说明".equals(sheetName)) {
System.out.println("跳过填表说明工作表");
continue;
}
System.out.println("处理工作表: " + sheetName);
int startRow = findStHdpDataStartRow(sheet);
if (startRow == -1) {
System.out.println("在工作表 " + sheetName + " 中未找到数据开始行");
continue;
}
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(2);
if (serialCell == null || isCellEmpty(serialCell)) {
continue;
}
// 解析监测站点1数据
Object[] station1Data = parseStHdpRowData(row, countyName, watershedCode, 1);
if (station1Data != null) {
dataList.add(station1Data);
}
// 解析监测站点2数据
Object[] station2Data = parseStHdpRowData(row, countyName, watershedCode, 2);
if (station2Data != null) {
dataList.add(station2Data);
}
if (station1Data != null || station2Data != null) {
System.out.println("✓ 解析第 " + (i + 1) + " 行数据成功,生成 " +
(station1Data != null ? 1 : 0) + "+" + (station2Data != null ? 1 : 0) + " 条记录");
}
}
}
} catch (Exception e) {
System.err.println("读取Excel文件失败: " + e.getMessage());
throw e;
}
return dataList;
}
private static int findStHdpDataStartRow(Sheet sheet) {
for (int i = 1; i <= sheet.getLastRowNum(); i++) {
Row row = sheet.getRow(i);
if (row != null) {
Cell cell = row.getCell(2);
if (cell != null && !isCellEmpty(cell)) {
return i;
// 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[] parseStHdpRowData(Row row, String countyName, String watershedCode, int stationIndex) {
try {
Object[] data = new Object[20]; // 对应20个参数
int index = 0;
// 防治对象编码 (C列)
String pcd = getCellStringValue(row.getCell(2));
if (pcd == null || pcd.trim().isEmpty()) {
return null; // 防治对象编码为空,跳过
}
// ADCD - 行政区划编码 (从防治对象编码提取前6位 + 000000)
String adcd = pcd.length() >= 9 ? pcd.substring(0, 9) + "000000" : pcd + "000000";
data[index++] = adcd;
// PCD - 防治对象代码
data[index++] = pcd;
// FSOURCE - 洪水来源 (D列)
data[index++] = getCellStringValue(row.getCell(3));
// 根据站点索引确定列位置
// 站点1: 列4-8 (编码,名称,类型,经度,纬度)
// 站点2: 列9-13 (编码,名称,类型,经度,纬度)
int baseCol = (stationIndex == 1) ? 4 : 9;
// STCD - 监测站点编码
String stcd = getCellStringValue(row.getCell(baseCol));
if (stcd == null || stcd.trim().isEmpty()) {
return null; // 监测站点编码为空,跳过
}
data[index++] = stcd;
// TYPE - 监测站点类型
data[index++] = getCellStringValue(row.getCell(baseCol + 2));
// LGTD - 经度
String lngStr = getCellStringValue(row.getCell(baseCol + 3));
if (lngStr != null && !lngStr.trim().isEmpty()) {
try {
data[index++] = Double.parseDouble(lngStr.trim());
} catch (NumberFormatException e) {
System.err.println("经度格式错误: " + lngStr);
data[index++] = null;
}
} else {
data[index++] = null;
}
// LTTD - 纬度
String latStr = getCellStringValue(row.getCell(baseCol + 4));
if (latStr != null && !latStr.trim().isEmpty()) {
try {
data[index++] = Double.parseDouble(latStr.trim());
} catch (NumberFormatException e) {
System.err.println("纬度格式错误: " + latStr);
data[index++] = null;
}
} else {
data[index++] = null;
}
// REMARK - 备注 (O列)
data[index++] = getCellStringValue(row.getCell(14));
// 固定值字段
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++] = pcd.length() >= 6 ? pcd.substring(0, 6) + "000000000" : pcd; // CADCD - 县级编码
// GUID - 唯一标识
data[index++] = UUID.randomUUID().toString();
// AUDBATCH
data[index++] = "BATCH_ST_" + System.currentTimeMillis();
// WSCD - 流域编码
data[index++] = watershedCode;
// PRENAME - 防灾对象名称 (B列)
data[index++] = getCellStringValue(row.getCell(1));
// STNM - 监测站点名称
data[index++] = getCellStringValue(row.getCell(baseCol + 1));
return data;
} catch (Exception e) {
System.err.println("解析监测站点" + stationIndex + "数据失败: " + e.getMessage());
e.printStackTrace();
return null;
}
}
private static ProcessResult batchInsertStHdpData(List<Object[]> stHdpDataList) {
int importedCount = 0;
int duplicateCount = 0;
try (Connection conn = DatabaseUtil.getConnection();
PreparedStatement stHdpPstmt = conn.prepareStatement(INSERT_ST_HDP_SQL);
PreparedStatement checkStHdpDupPstmt = conn.prepareStatement(CHECK_ST_HDP_DUPLICATE_SQL)) {
conn.setAutoCommit(false); // 开启事务
// 使用Set来跟踪已处理的数据避免内存中重复
Set<String> processedStHdpKeys = new HashSet<>();
for (Object[] rowData : stHdpDataList) {
try {
// 检查是否重复
String pcd = (String) rowData[1]; // PCD在索引1
String stcd = (String) rowData[3]; // STCD在索引3
String stnm = (String) rowData[19]; // STNM在索引19
// 检查必要字段是否为空
if (pcd == null || stcd == null || stnm == null) {
System.out.println("跳过数据不完整的记录: PCD=" + pcd + ", STCD=" + stcd);
continue;
}
// 生成唯一键,先检查内存中是否已处理
String stHdpKey = pcd + "|" + stcd + "|" + stnm;
if (processedStHdpKeys.contains(stHdpKey)) {
duplicateCount++;
System.out.println("跳过内存中重复记录: " + pcd + " - " + stnm);
continue;
}
// 检查数据库中是否已存在
checkStHdpDupPstmt.setString(1, pcd);
checkStHdpDupPstmt.setString(2, stcd);
checkStHdpDupPstmt.setString(3, stnm);
try (ResultSet rs = checkStHdpDupPstmt.executeQuery()) {
if (rs.next() && rs.getInt(1) > 0) {
duplicateCount++;
System.out.println("跳过数据库中重复记录: " + pcd + " - " + stnm);
continue;
}
}
// 插入数据
for (int i = 0; i < rowData.length; i++) {
stHdpPstmt.setObject(i + 1, rowData[i]);
}
stHdpPstmt.addBatch();
importedCount++;
processedStHdpKeys.add(stHdpKey);
// 每10条执行一次批量插入
if (importedCount % 10 == 0) {
stHdpPstmt.executeBatch();
System.out.println("已批量插入 " + importedCount + " 条记录到防治对象-监测站点关系表");
}
} catch (Exception e) {
System.err.println("单条数据插入失败: " + e.getMessage());
e.printStackTrace();
}
}
// 执行剩余的批量插入
if (importedCount > 0) {
stHdpPstmt.executeBatch();
System.out.println("最终批量插入完成,共 " + importedCount + " 条记录到防治对象-监测站点关系表");
}
conn.commit(); // 提交事务
System.out.println("防治对象-监测站点关系表事务提交成功");
} catch (Exception e) {
System.err.println("批量插入防治对象-监测站点关系表数据失败: " + e.getMessage());
e.printStackTrace();
}
return new ProcessResult(importedCount, duplicateCount);
}
// 辅助方法
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[] findSxDirectories(File watershedDir) {
File[] subDirs = watershedDir.listFiles(File::isDirectory);
if (subDirs != null) {
List<File> sxDirs = new ArrayList<>();
for (File subDir : subDirs) {
if (subDir.getName().contains("水系") || subDir.getName().matches("^HBWF.*")) {
sxDirs.add(subDir);
}
}
return sxDirs.toArray(new File[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 findStHdpExcelFile(File reportDir) {
File[] files = reportDir.listFiles((dir, name) ->
name.equals("表8 防治对象-监测站点关系表.xlsx") ||
name.contains("防治对象-监测站点关系表") ||
name.toLowerCase().endsWith(".xlsx"));
if (files != null && files.length > 0) {
for (File file : files) {
if (file.getName().equals("表8 防治对象-监测站点关系表.xlsx")) {
return file;
}
}
for (File file : files) {
if (file.getName().contains("防治对象-监测站点关系表")) {
return file;
}
}
return files[0];
}
return null;
}
private static String extractCountyName(String dirName) {
return dirName.contains("、") ? dirName.split("、")[1].trim() : dirName;
}
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();
return (num == (long) num) ? String.valueOf((long) num) : 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 null;
}
}
default:
return null;
}
} catch (Exception 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;
}
}
// 处理结果类
private static class ProcessResult {
int processed;
int duplicates;
ProcessResult(int processed, int duplicates) {
this.processed = processed;
this.duplicates = duplicates;
}
}
}

View File

@ -0,0 +1,639 @@
// 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.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
public class MountainFloodDataImporter {
// 防灾对象表插入SQL
private static final String INSERT_HDP_SQL =
"INSERT INTO SHZH_JCSJ.IA_SHZH_HDP(ADCD, ADNM, TYPE, PCOUNT, RVNM, RVCD, BRNAME, BRCD, " +
"DAMNAME, DAMCD, DZRVNM, DZRVCD, ISSZ, ISJW, ISDW, ISGT, ISYS, ISDT, ISGD, ISML, " +
"REMARK, ISENABLE, IMPORTYEAR, ISKJ, PRENAME, PRECODE, ISLHHP, ISNSL, SIGNER, CADCD, " +
"GUID, AUDBATCH, INPUTTYPE, AUDID, STATUS, WSCD) \n" +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, " +
"?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?)";
// 防灾对象河流信息表插入SQL
private static final String INSERT_RV_INFO_SQL =
"INSERT INTO SHZH_JCSJ.IA_RV_INFO (" +
"PRECODE, PRENAME, RVCD, RVNM, WSCD" +
") VALUES (?, ?, ?, ?, ?)";
// 检查重复的SQL基于县编码、名称、编码、类型、人口
private static final String CHECK_DUPLICATE_SQL =
"SELECT COUNT(*) FROM SHZH_JCSJ.IA_SHZH_HDP " +
"WHERE ADCD = ? AND PRENAME = ? AND PRECODE = ? AND TYPE = ? AND PCOUNT = ?";
public static void main(String[] args) {
// 先测试数据库连接
if (!testDatabaseConnection()) {
System.err.println("数据库连接测试失败,程序退出");
return;
}
// 测试用的固定路径
args = new String[]{"F:\\9月29日湖工大提交小流域数据全\\湖工大9.29"};
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 boolean testDatabaseConnection() {
try {
Connection conn = DatabaseUtil.getConnection();
if (conn != null && !conn.isClosed()) {
System.out.println("✓ 数据库连接测试成功");
conn.close();
return true;
}
} catch (Exception e) {
System.err.println("✗ 数据库连接测试失败: " + e.getMessage());
}
return false;
}
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;
int totalDuplicates = 0;
System.out.println("找到 " + countyDirs.length + " 个县市文件夹");
for (File countyDir : countyDirs) {
String countyName = extractCountyName(countyDir.getName());
System.out.println("\n=== 处理县市: " + countyName + " ===");
try {
ProcessResult result = processCountyData(countyDir, countyName);
totalProcessed += result.processed;
totalDuplicates += result.duplicates;
totalSuccess++;
System.out.println("✓ 成功处理 " + countyName +
",导入 " + result.processed + " 条记录,跳过 " + result.duplicates + " 条重复记录");
} catch (Exception e) {
System.err.println("✗ 处理县市 " + countyName + " 时出错: " + e.getMessage());
}
}
System.out.println("\n=== 处理完成 ===");
System.out.println("成功处理县市: " + totalSuccess + " 个");
System.out.println("总导入记录: " + totalProcessed + " 条");
System.out.println("总跳过重复记录: " + totalDuplicates + " 条");
}
private static ProcessResult processCountyData(File countyDir, String countyName) throws Exception {
int totalProcessed = 0;
int totalDuplicates = 0;
// 查找小流域目录
File watershedDir = findWatershedDirectory(countyDir);
if (watershedDir == null) {
System.out.println("在 " + countyName + " 下未找到小流域目录");
return new ProcessResult(0, 0);
}
System.out.println("找到小流域目录: " + watershedDir.getName());
// 查找所有水系目录
File[] sxDirs = findSxDirectories(watershedDir);
if (sxDirs == null || sxDirs.length == 0) {
System.out.println("在 " + watershedDir.getPath() + " 下未找到水系目录");
return new ProcessResult(0, 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());
ProcessResult result = processSxData(sxDir, countyName);
totalProcessed += result.processed;
totalDuplicates += result.duplicates;
System.out.println("水系 " + sxDir.getName() + " 导入 " + result.processed + " 条记录,跳过 " + result.duplicates + " 条重复记录");
}
return new ProcessResult(totalProcessed, totalDuplicates);
}
private static ProcessResult processSxData(File sxDir, String countyName) throws Exception {
int processedCount = 0;
int duplicateCount = 0;
// 查找成果报表目录
File reportDir = findReportDirectory(sxDir);
if (reportDir == null) {
System.out.println("在 " + sxDir.getPath() + " 下未找到成果报表目录");
return new ProcessResult(0, 0);
}
System.out.println("找到成果报表目录: " + reportDir.getPath());
// 查找Excel文件
File excelFile = findExcelFile(reportDir);
if (excelFile == null) {
System.out.println("在 " + reportDir.getPath() + " 下未找到表1山洪灾害防治对象名录.xlsx");
return new ProcessResult(0, 0);
}
System.out.println("找到Excel文件: " + excelFile.getPath());
// 提取流域编码
String watershedCode = extractWatershedCode(sxDir.getName());
System.out.println("流域编码: " + watershedCode);
// 读取Excel文件并导入数据库
ProcessResult result = readExcelAndImport(excelFile, countyName, watershedCode);
return result;
}
private static ProcessResult readExcelAndImport(File excelFile, String countyName, String watershedCode) throws Exception {
int importedCount = 0;
int duplicateCount = 0;
// 先读取所有数据到内存
List<Object[]> hdpDataList = new ArrayList<>();
List<Object[]> rvInfoDataList = new ArrayList<>();
readExcelData(excelFile, countyName, watershedCode, hdpDataList, rvInfoDataList);
if (hdpDataList.isEmpty()) {
System.out.println("未读取到有效数据");
return new ProcessResult(0, 0);
}
System.out.println("成功读取 " + hdpDataList.size() + " 条数据,开始导入数据库...");
// 批量导入数据库
ProcessResult result = batchInsertData(hdpDataList, rvInfoDataList);
return result;
}
private static String extractCountyCode(Sheet sheet) {
// 从第二行提取县代码
Row headerRow = sheet.getRow(1);
if (headerRow != null) {
Cell codeCell = headerRow.getCell(9); // 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(22); // 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(14); // H列 - 乡镇名称
if (codeCell != null) {
return getCellStringValue(codeCell);
}
}
return ""; // 默认值
}
private static void readExcelData(File excelFile, String countyName, String watershedCode,
List<Object[]> hdpDataList, List<Object[]> rvInfoDataList) throws Exception {
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 countyCode = extractCountyCode(sheet);
String adcd = extractAdcd(sheet);
String adnm = extractAdnm(sheet);
int startRow = findDataStartRow(sheet);
if (startRow == -1) {
System.out.println("未找到数据开始行");
return;
}
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[] hdpData = parseRowData(row, countyName, watershedCode, countyCode,adcd,adnm);
if (hdpData != null) {
hdpDataList.add(hdpData);
// 同时生成河流信息表数据
Object[] rvInfoData = parseRvInfoData(hdpData);
if (rvInfoData != null) {
rvInfoDataList.add(rvInfoData);
}
System.out.println("✓ 解析第 " + (i + 1) + " 行数据成功");
} else {
System.out.println("✗ 解析第 " + (i + 1) + " 行数据失败");
}
}
}
}
}
private static ProcessResult batchInsertData(List<Object[]> hdpDataList, List<Object[]> rvInfoDataList) {
int importedCount = 0;
int duplicateCount = 0;
try (Connection conn = DatabaseUtil.getConnection();
PreparedStatement hdpPstmt = conn.prepareStatement(INSERT_HDP_SQL);
PreparedStatement rvInfoPstmt = conn.prepareStatement(INSERT_RV_INFO_SQL);
PreparedStatement checkDupPstmt = conn.prepareStatement(CHECK_DUPLICATE_SQL)) {
conn.setAutoCommit(false); // 开启事务
// 处理防灾对象表数据
for (Object[] rowData : hdpDataList) {
try {
// 检查是否重复
String adcd = (String) rowData[0];
String prename = (String) rowData[24]; // PRENAME在索引24
String precode = (String) rowData[25]; // PRECODE在索引25
String type = (String) rowData[2]; // TYPE在索引2
Integer pcount = (Integer) rowData[3]; // PCOUNT在索引3
checkDupPstmt.setString(1, adcd);
checkDupPstmt.setString(2, prename);
checkDupPstmt.setString(3, precode);
checkDupPstmt.setString(4, type);
checkDupPstmt.setObject(5, pcount);
try (ResultSet rs = checkDupPstmt.executeQuery()) {
if (rs.next() && rs.getInt(1) > 0) {
duplicateCount++;
System.out.println("跳过重复记录: " + prename + " (" + precode + ")");
continue;
}
}
// 插入数据
for (int i = 0; i < rowData.length; i++) {
hdpPstmt.setObject(i + 1, rowData[i]);
}
hdpPstmt.addBatch();
importedCount++;
// 每10条执行一次批量插入
if (importedCount % 10 == 0) {
hdpPstmt.executeBatch();
System.out.println("已批量插入 " + importedCount + " 条记录到防灾对象表");
}
} catch (Exception e) {
System.err.println("单条数据插入失败: " + e.getMessage());
// 继续处理下一条数据
}
}
// 执行剩余的批量插入
if (importedCount % 10 != 0) {
hdpPstmt.executeBatch();
}
// 处理河流信息表数据
int rvImportedCount = 0;
for (Object[] rvData : rvInfoDataList) {
try {
for (int i = 0; i < rvData.length; i++) {
rvInfoPstmt.setObject(i + 1, rvData[i]);
}
rvInfoPstmt.addBatch();
rvImportedCount++;
if (rvImportedCount % 10 == 0) {
rvInfoPstmt.executeBatch();
}
} catch (Exception e) {
System.err.println("河流信息表数据插入失败: " + e.getMessage());
}
}
// 执行剩余的河流信息批量插入
if (rvImportedCount % 10 != 0) {
rvInfoPstmt.executeBatch();
}
conn.commit(); // 提交事务
System.out.println("成功导入 " + importedCount + " 条记录到防灾对象表");
System.out.println("成功导入 " + rvImportedCount + " 条记录到河流信息表");
} catch (Exception e) {
System.err.println("批量插入数据失败: " + e.getMessage());
e.printStackTrace();
}
return new ProcessResult(importedCount, duplicateCount);
}
// 解析河流信息表数据
private static Object[] parseRvInfoData(Object[] hdpData) {
try {
Object[] rvData = new Object[5];
// PRECODE
rvData[0] = hdpData[25]; // PRECODE在索引25
// PRENAME
rvData[1] = hdpData[24]; // PRENAME在索引24
// RVCD - 河流代码
rvData[2] = hdpData[5]; // RVCD在索引5
// RVNM - 河流名称
rvData[3] = hdpData[4]; // RVNM在索引4
// WSCD - 流域编码
rvData[4] = hdpData[35]; // WSCD在索引35
return rvData;
} catch (Exception e) {
System.err.println("解析河流信息数据失败: " + e.getMessage());
return null;
}
}
// 其他辅助方法保持不变...
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[] findSxDirectories(File watershedDir) {
File[] subDirs = watershedDir.listFiles(File::isDirectory);
if (subDirs != null) {
List<File> sxDirs = new ArrayList<>();
for (File subDir : subDirs) {
// 包含"水系"或者是类似HBWFF开头的文件夹都认为是水系文件夹
if (subDir.getName().contains("水系") || subDir.getName().matches("^HBWFF.*")) {
sxDirs.add(subDir);
}
}
return sxDirs.toArray(new File[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("表1山洪灾害防治对象名录.xlsx") || name.toLowerCase().endsWith(".xlsx"));
if (files != null && files.length > 0) {
for (File file : files) {
if (file.getName().equals("表1山洪灾害防治对象名录.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) {
String[] parts = dirName.split("水系");
String str = parts[0].trim();
int start = str.length() -2;
return parts.length > 0 ? str.substring(0,start) : dirName;
}
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);
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 String getCellStringValue(Cell cell) {
if (cell == null) return null;
try {
switch (cell.getCellType()) {
case STRING: return cell.getStringCellValue().trim();
case NUMERIC:
double num = cell.getNumericCellValue();
return (num == (long) num) ? String.valueOf((long) num) : String.valueOf(num);
case BOOLEAN: return String.valueOf(cell.getBooleanCellValue());
default: return null;
}
} catch (Exception 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;
}
}
private static String getCountyCode(String objectCode) {
return (objectCode != null && objectCode.length() >= 6) ?
objectCode.substring(0, 6) + "000000" : null;
}
// 处理结果类
private static class ProcessResult {
int processed;
int duplicates;
ProcessResult(int processed, int duplicates) {
this.processed = processed;
this.duplicates = duplicates;
}
}
// parseRowData方法保持不变...
private static Object[] parseRowData(Row row, String countyName, String watershedCode, String countyCode,String adcd ,String adnm) {
try {
Object[] data = new Object[36]; // 对应36个参数
int index = 0;
// ADCD - 行政区划代码 (C列)
String objectCode = getCellStringValue(row.getCell(2));
data[index++] = adcd;
// ADNM - 行政区划名称 (B列 + 县市名称)
String objectName = getCellStringValue(row.getCell(1));
data[index++] = adnm;
// TYPE - 类型 (D列)
data[index++] = getCellStringValue(row.getCell(3));
// PCOUNT - 人口 (E列)
String populationStr = getCellStringValue(row.getCell(4));
if (populationStr != null && !populationStr.trim().isEmpty()) {
try {
data[index++] = Integer.parseInt(populationStr.trim());
} catch (NumberFormatException e) {
data[index++] = null;
}
} else {
data[index++] = null;
}
// RVNM - 河流名称 (F列)
data[index++] = getCellStringValue(row.getCell(5));
// RVCD - 河流代码 (G列)
data[index++] = getCellStringValue(row.getCell(6));
// BRNAME - 桥梁名称 (H列)
data[index++] = getCellStringValue(row.getCell(7));
// BRCD - 桥梁编码 (I列)
data[index++] = getCellStringValue(row.getCell(8));
// DAMNAME - 塘坝名称 (J列)
data[index++] = getCellStringValue(row.getCell(9));
// DAMCD - 塘坝编码 (K列)
data[index++] = getCellStringValue(row.getCell(10));
// DZRVNM - 多支河流名称 (L列)
data[index++] = getCellStringValue(row.getCell(11));
// DZRVCD - 多支河流代码 (M列)
data[index++] = getCellStringValue(row.getCell(12));
// 风险隐患要素 (N~S列)
data[index++] = getCellStringValue(row.getCell(13)); // ISSZ
data[index++] = getCellStringValue(row.getCell(14)); // ISJW
data[index++] = getCellStringValue(row.getCell(15)); // ISDW
data[index++] = getCellStringValue(row.getCell(16)); // ISGT
data[index++] = getCellStringValue(row.getCell(17)); // ISYS
data[index++] = getCellStringValue(row.getCell(18)); // ISDT
// 风险隐患影响类型 (T~Y列)
data[index++] = getCellStringValue(row.getCell(19)); // ISGD
data[index++] = getCellStringValue(row.getCell(20)); // ISML
// REMARK - 备注 (Z列)
data[index++] = getCellStringValue(row.getCell(25));
// 固定值字段
data[index++] = "1"; // ISENABLE
data[index++] = "2025"; // IMPORTYEAR
data[index++] = null; // ISKJ
data[index++] = objectName; // PRENAME
data[index++] = objectCode; // PRECODE
data[index++] = null; // ISLHHP
data[index++] = null; // ISNSL
data[index++] = null; // SIGNER
data[index++] = countyCode; // CADCD
// GUID - 唯一标识
data[index++] = UUID.randomUUID().toString();
// 其他固定字段
data[index++] = "BATCH_" + System.currentTimeMillis(); // AUDBATCH
data[index++] = "1"; // INPUTTYPE
data[index++] = null; // AUDID
data[index++] = "1"; // STATUS
// WSCD - 流域编码
data[index++] = watershedCode;
return data;
} catch (Exception e) {
System.err.println("解析行数据失败: " + e.getMessage());
return null;
}
}
}

View File

@ -0,0 +1,8 @@
package org.example;
public class Test {
public static void main(String[] args) {
String str = "WFG26305L0000000ZACS0011";
System.out.println(str.length());
}
}

View File

@ -0,0 +1,296 @@
// WatershedDataCleaner.java
package org.example;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
public class WatershedDataCleaner {
/**
*
* @param watershedCodes
* @return
*/
public static CleanResult deleteByWatershedCodes(List<String> watershedCodes) {
if (watershedCodes == null || watershedCodes.isEmpty()) {
return new CleanResult(0, "小流域编码列表为空,无需删除");
}
Connection conn = null;
CleanResult result = new CleanResult();
try {
conn = DatabaseUtil.getConnection();
conn.setAutoCommit(false); // 开启事务
System.out.println("开始删除 " + watershedCodes.size() + " 个小流域的相关数据...");
System.out.println("小流域编码列表: " + watershedCodes);
// 依次删除各个表的数据
result.table1Count = deleteFromTable1(conn, watershedCodes);
result.table2Count = deleteFromTable2(conn, watershedCodes);
result.table3Count = deleteFromTable3(conn, watershedCodes);
result.table4Count = deleteFromTable4(conn, watershedCodes);
result.table5_7Count = deleteFromTable5_7(conn, watershedCodes);
result.table8Count = deleteFromTable8(conn, watershedCodes);
result.hsPointCount = deleteFromHSPoint(conn, watershedCodes);
result.hSurfaceCount = deleteFromHSurface(conn, watershedCodes);
result.vsPointCount = deleteFromVSPoint(conn, watershedCodes);
result.vSurfaceCount = deleteFromVSurface(conn, watershedCodes);
// 提交事务
conn.commit();
result.success = true;
result.message = "数据删除完成";
System.out.println("✓ " + result.getMessage());
} catch (Exception e) {
// 回滚事务
if (conn != null) {
try {
conn.rollback();
} catch (SQLException ex) {
System.err.println("回滚事务失败: " + ex.getMessage());
}
}
result.success = false;
result.message = "删除过程中发生错误: " + e.getMessage();
System.err.println("✗ " + result.getMessage());
e.printStackTrace();
} finally {
// 恢复自动提交并关闭连接
if (conn != null) {
try {
conn.setAutoCommit(true);
conn.close();
} catch (SQLException e) {
System.err.println("关闭连接失败: " + e.getMessage());
}
}
}
return result;
}
/**
* 1 - IA_SHZH_HDP
*/
private static int deleteFromTable1(Connection conn, List<String> watershedCodes) throws SQLException {
String sql = "DELETE FROM \"SHZH_JCSJ\".\"IA_SHZH_HDP\" WHERE \"WSCD\" = ?";
return executeBatchDelete(conn, sql, watershedCodes, "IA_SHZH_HDP");
}
/**
* 2 - IA_RBAD_INFO
*/
private static int deleteFromTable2(Connection conn, List<String> watershedCodes) throws SQLException {
String sql = "DELETE FROM \"SHZH_JCSJ\".\"IA_RBAD_INFO\" WHERE \"WSCD\" = ?";
return executeBatchDelete(conn, sql, watershedCodes, "IA_RBAD_INFO");
}
/**
* 3 - IA_GLA_INFO
*/
private static int deleteFromTable3(Connection conn, List<String> watershedCodes) throws SQLException {
String sql = "DELETE FROM \"SHZH_JCSJ\".\"IA_GLA_INFO\" WHERE \"WSCD\" = ?";
return executeBatchDelete(conn, sql, watershedCodes, "IA_GLA_INFO");
}
/**
* 4 - IA_EFTS_TOWN
*/
private static int deleteFromTable4(Connection conn, List<String> watershedCodes) throws SQLException {
String sql = "DELETE FROM \"SHZH_JCSJ\".\"IA_EFTS_TOWN\" WHERE \"WSCD\" = ?";
return executeBatchDelete(conn, sql, watershedCodes, "IA_EFTS_TOWN");
}
/**
* 5,6,7 - IA_SHZH_HDP_POINT
*/
private static int deleteFromTable5_7(Connection conn, List<String> watershedCodes) throws SQLException {
String sql = "DELETE FROM \"SHZH_JCSJ\".\"IA_SHZH_HDP_POINT\" WHERE \"WSCD\" = ?";
return executeBatchDelete(conn, sql, watershedCodes, "IA_SHZH_HDP_POINT");
}
/**
* 8 - IA_ST_HDP
*/
private static int deleteFromTable8(Connection conn, List<String> watershedCodes) throws SQLException {
String sql = "DELETE FROM \"SHZH_JCSJ\".\"IA_ST_HDP\" WHERE \"WSCD\" = ?";
return executeBatchDelete(conn, sql, watershedCodes, "IA_ST_HDP");
}
/**
* - IA_M_HSURFACE
*/
private static int deleteFromHSurface(Connection conn, List<String> watershedCodes) throws SQLException {
String sql = "DELETE FROM \"SHZH_JCSJ\".\"IA_M_HSURFACE\" WHERE \"WSCD\" = ?";
return executeBatchDelete(conn, sql, watershedCodes, "IA_M_HSURFACE");
}
/**
* - IA_M_HSPOINT
*/
private static int deleteFromHSPoint(Connection conn, List<String> watershedCodes) throws SQLException {
String sql = "DELETE FROM \"SHZH_JCSJ\".\"IA_M_HSPOINT\" WHERE \"HSURFACEID\" IN (SELECT GUID FROM \"SHZH_JCSJ\".\"IA_M_HSURFACE\" WHERE \"WSCD\" = ?)";
return executeBatchDelete(conn, sql, watershedCodes, "IA_M_HSPOINT");
}
/**
* - IA_M_VSURFACE
*/
private static int deleteFromVSurface(Connection conn, List<String> watershedCodes) throws SQLException {
String sql = "DELETE FROM \"SHZH_JCSJ\".\"IA_M_VSURFACE\" WHERE \"WSCD\" = ?";
return executeBatchDelete(conn, sql, watershedCodes, "IA_M_VSURFACE");
}
/**
* - IA_M_VSPOINT
*/
private static int deleteFromVSPoint(Connection conn, List<String> watershedCodes) throws SQLException {
String sql = "DELETE FROM \"SHZH_JCSJ\".\"IA_M_VSPOINT\" WHERE WHERE \"ZSURFACEID\" IN (SELECT GUID FROM \"SHZH_JCSJ\".\"IA_M_VSURFACE\" WHERE \"WSCD\" = ?)";
return executeBatchDelete(conn, sql, watershedCodes, "IA_M_VSPOINT");
}
/**
*
*/
private static int executeBatchDelete(Connection conn, String sql, List<String> watershedCodes, String tableName) throws SQLException {
int totalDeleted = 0;
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
for (String code : watershedCodes) {
// 先查询要删除的记录数
int countBefore = getRecordCount(conn, tableName, code);
if (countBefore > 0) {
pstmt.setString(1, code);
int deleted = pstmt.executeUpdate();
totalDeleted += deleted;
System.out.println(" 表 " + tableName + " - 流域 " + code + ": 删除 " + deleted + " 条记录");
} else {
System.out.println(" 表 " + tableName + " - 流域 " + code + ": 无记录可删除");
}
}
}
return totalDeleted;
}
/**
*
*/
private static int getRecordCount(Connection conn, String tableName, String watershedCode) throws SQLException {
String sql = "SELECT COUNT(*) FROM \"SHZH_JCSJ\".\"" + tableName + "\" WHERE \"WSCD\" = ?";
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setString(1, watershedCode);
try (ResultSet rs = pstmt.executeQuery()) {
if (rs.next()) {
return rs.getInt(1);
}
}
}
return 0;
}
/**
*
*/
public static class CleanResult {
private boolean success;
private String message;
private int table1Count; // IA_SHZH_HDP
private int table2Count; // IA_RBAD_INFO
private int table3Count; // IA_GLA_INFO
private int table4Count; // IA_EFTS_TOWN
private int table5_7Count; // IA_SHZH_HDP_POINT
private int table8Count; // IA_ST_HDP
private int hSurfaceCount; // IA_M_HSURFACE
private int hsPointCount; // IA_M_HSPOINT
private int vSurfaceCount; // IA_M_VSURFACE
private int vsPointCount; // IA_M_VSPOINT
public CleanResult() {}
public CleanResult(int totalCount, String message) {
this.success = true;
this.message = message;
}
// Getter 方法
public boolean isSuccess() { return success; }
public String getMessage() { return message; }
public int getTable1Count() { return table1Count; }
public int getTable2Count() { return table2Count; }
public int getTable3Count() { return table3Count; }
public int getTable4Count() { return table4Count; }
public int getTable5_7Count() { return table5_7Count; }
public int getTable8Count() { return table8Count; }
public int gethSurfaceCount() { return hSurfaceCount; }
public int getHsPointCount() { return hsPointCount; }
public int getvSurfaceCount() { return vSurfaceCount; }
public int getVsPointCount() { return vsPointCount; }
/**
*
*/
public int getTotalDeleted() {
return table1Count + table2Count + table3Count + table4Count +
table5_7Count + table8Count + hSurfaceCount + hsPointCount +
vSurfaceCount + vsPointCount;
}
/**
*
*/
public void printDetailedResult() {
System.out.println("\n=== 删除结果详情 ===");
System.out.println("状态: " + (success ? "成功" : "失败"));
System.out.println("消息: " + message);
System.out.println("各表删除记录数:");
System.out.println(" IA_SHZH_HDP (防治对象): " + table1Count);
System.out.println(" IA_RBAD_INFO (跨沟): " + table2Count);
System.out.println(" IA_GLA_INFO (沟滩占地): " + table3Count);
System.out.println(" IA_EFTS_TOWN (外洪顶托): " + table4Count);
System.out.println(" IA_SHZH_HDP_POINT (三合一): " + table5_7Count);
System.out.println(" IA_ST_HDP (防治对象关联站点): " + table8Count);
System.out.println(" IA_M_HSPOINT (横断面点): " + hsPointCount);
System.out.println(" IA_M_HSURFACE (横断面): " + hSurfaceCount);
System.out.println(" IA_M_VSPOINT (纵断面点): " + vsPointCount);
System.out.println(" IA_M_VSURFACE (纵断面): " + vSurfaceCount);
System.out.println("总删除记录数: " + getTotalDeleted());
}
}
/**
*
*/
public static void main(String[] args) {
// 测试数据
List<String> testWatershedCodes = Arrays.asList(
"HBWFA8900124H00000",
"HBWFA8900125M00000",
"HBWFA8900126F00000",
"HBWFA8900127000000",
"HBWFAA200123o00000",
"HBWFAA200125cE0000",
"HBWFAA200127c00000",
"HBWFAA200127m00000",
"HBWFAA200127t00000",
"HBWFAA20012g000000",
"HBWFAA2103N0000000",
"HBWFAA2106F0000000",
"HBWFAA210G00000000",
"HBWFADJ00125000000"
);
System.out.println("开始测试删除操作...");
CleanResult result = deleteByWatershedCodes(testWatershedCodes);
result.printDetailedResult();
}
}