data-importer/src/main/java/org/example/IaGlaInfoDataImporter.java

548 lines
20 KiB
Java

// MountainFloodDataImporter.java
package org.example;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.File;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 表3
*/
public class IaGlaInfoDataImporter {
// IA_GLA_INFO表的插入SQL
private static final String INSERT_SQL =
"INSERT INTO SHZH_JCSJ.IA_GLA_INFO (" +
"ADCD, ADNM, NAME, CD, LGTD, LTTD, TYPE, WIDTH, LENGTH, STYPE, " +
"R2, RVNM, RVCD, REMARK, ISENABLE, IMPORTYEAR, INPUTTYPE, AUDID, STATUS, " +
"SIGNER, CADCD, GUID, AUDBATCH, WSCD" +
") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
public static void main(String[] args) {
// 测试用的固定路径
// args = new String[]{"F:\\1111-湖工大50条成果-已通过初检-待入库"};
// args = new String[]{"F:\\3333-2024年度咸宁市8条20251017-已通过初检-待入库"};
// args = new String[]{"F:\\4444-长江科学院-黄冈28条-已通过初检-已统一表头-待入库"};
// args = new String[]{"F:\\小流域\\5555-长江科学院20条10.23-已通过初检-已统一表头-待入库\\5555-长江科学院20条10.23-已通过初检-已统一表头-待入库"};
args = new String[]{"F:\\04 小流域成果\\2024年度\\第二批次成果\\4444-长江科学院-黄冈28条1201-已通过初检-空间格式通过-已统一表头-待入库"};
if (args.length == 0) {
System.out.println("请提供湖工大9.29目录路径作为参数");
return;
}
String baseDir = args[0];
File baseDirectory = new File(baseDir);
if (!baseDirectory.exists() || !baseDirectory.isDirectory()) {
System.out.println("指定的目录不存在或不是有效目录: " + baseDir);
return;
}
System.out.println("开始处理目录: " + baseDir);
try {
processAllCounties(baseDirectory);
} catch (Exception e) {
System.err.println("处理过程中发生错误: " + e.getMessage());
e.printStackTrace();
}
}
private static void processAllCounties(File baseDir) {
File[] countyDirs = baseDir.listFiles(File::isDirectory);
if (countyDirs == null) {
System.out.println("在基础目录下未找到任何县市文件夹");
return;
}
int totalProcessed = 0;
int totalSuccess = 0;
System.out.println("找到 " + countyDirs.length + " 个县市文件夹");
for (File countyDir : countyDirs) {
String countyName = extractCountyName(countyDir.getName());
System.out.println("\n=== 处理县市: " + countyName + " ===");
try {
int processed = processCountyData(countyDir, countyName);
totalProcessed += processed;
totalSuccess++;
System.out.println("✓ 成功处理 " + countyName + ",导入 " + processed + " 条记录");
} catch (Exception e) {
System.err.println("✗ 处理县市 " + countyName + " 时出错: " + e.getMessage());
}
}
System.out.println("\n=== 处理完成 ===");
System.out.println("成功处理县市: " + totalSuccess + " 个");
System.out.println("总导入记录: " + totalProcessed + " 条");
}
private static int processCountyData(File countyDir, String countyName) throws Exception {
int totalProcessed = 0;
// 查找小流域目录
File watershedDir = findWatershedDirectory(countyDir);
if (watershedDir == null) {
System.out.println("在 " + countyName + " 下未找到小流域目录");
return 0;
}
System.out.println("找到小流域目录: " + watershedDir.getName());
// 查找所有水系目录
File[] sxDirs = findSxDirectories(watershedDir);
if (sxDirs == null || sxDirs.length == 0) {
System.out.println("在 " + watershedDir.getPath() + " 下未找到水系目录");
return 0;
}
System.out.println("找到 " + sxDirs.length + " 个水系文件夹:");
for (File sxDir : sxDirs) {
System.out.println(" - " + sxDir.getName());
}
// 遍历处理每个水系文件夹
for (File sxDir : sxDirs) {
System.out.println("\n处理水系: " + sxDir.getName());
int processed = processSxData(sxDir, countyName);
totalProcessed += processed;
System.out.println("水系 " + sxDir.getName() + " 导入 " + processed + " 条记录");
}
return totalProcessed;
}
private static File[] findSxDirectories(File watershedDir) {
File[] subDirs = watershedDir.listFiles(File::isDirectory);
if (subDirs != null) {
List<File> sxDirs = new ArrayList<>();
for (File subDir : subDirs) {
if (subDir.getName().contains("水系") || subDir.getName().matches("^HBW.*")) {
sxDirs.add(subDir);
}
}
return sxDirs.toArray(new File[0]);
}
return null;
}
private static int processSxData(File sxDir, String countyName) throws Exception {
int processedCount = 0;
// 查找成果报表目录
File reportDir = findReportDirectory(sxDir);
if (reportDir == null) {
System.out.println("在 " + sxDir.getPath() + " 下未找到成果报表目录");
return 0;
}
System.out.println("找到成果报表目录: " + reportDir.getPath());
// 查找Excel文件
File excelFile = findExcelFile(reportDir);
if (excelFile == null) {
System.out.println("在 " + reportDir.getPath() + " 下未找到表3沟滩占地情况调查成果表.xlsx");
return 0;
}
System.out.println("找到Excel文件: " + excelFile.getPath());
// 提取流域编码
String watershedCode = extractWatershedCode(sxDir.getName());
System.out.println("流域编码: " + watershedCode);
// 读取Excel文件并导入数据库
processedCount = readExcelAndImport(excelFile, countyName, watershedCode);
return processedCount;
}
private static File findWatershedDirectory(File countyDir) {
File[] subDirs = countyDir.listFiles(File::isDirectory);
if (subDirs != null) {
for (File subDir : subDirs) {
if (subDir.getName().contains("小流域")) {
return subDir;
}
}
if (subDirs.length > 0) return subDirs[0];
}
return null;
}
private static File findReportDirectory(File sxDir) {
File[] subDirs = sxDir.listFiles(File::isDirectory);
if (subDirs != null) {
for (File subDir : subDirs) {
if (subDir.getName().contains("成果报表")) {
return subDir;
}
}
if (subDirs.length > 0) return subDirs[0];
}
return null;
}
private static File findExcelFile(File reportDir) {
File[] files = reportDir.listFiles((dir, name) ->
name.equals("表3沟滩占地情况调查成果表.xlsx") || name.toLowerCase().endsWith(".xlsx"));
if (files != null && files.length > 0) {
for (File file : files) {
if (file.getName().equals("表3沟滩占地情况调查成果表.xlsx")) {
return file;
}
}
return files[0];
}
return null;
}
private static String extractCountyName(String dirName) {
return dirName.contains("、") ? dirName.split("、")[1].trim() : dirName;
}
private static String extractWatershedCode(String dirName) {
Pattern pattern = Pattern.compile("^[a-zA-Z0-9]+");
Matcher matcher = pattern.matcher(dirName);
if(matcher.find()){
return matcher.group();
}else{
System.out.println("小流域编码文件夹有问题: " + dirName);
}
return dirName;
}
private static int readExcelAndImport(File excelFile, String countyName, String watershedCode) throws Exception {
int importedCount = 0;
// 先读取所有数据到内存
List<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(1));
if (name == null || name.trim().isEmpty() || "无".equals(name)) {
System.out.println("第 " + (row.getRowNum() + 1) + " 行编码为空,跳过该行");
return null;
}
Object[] data = new Object[24]; // 对应24个参数
int index = 0;
// ADCD - 行政区划代码
data[index++] = adcd;
// ADNM - 行政区划名称
data[index++] = adnm;
// NAME - 名称 (B列)
data[index++] = name;
// CD - 编号 (C列)
data[index++] = getCellStringValue(row.getCell(2));
// LGTD - 经度 (D列)
String lngStr = getCellStringValue(row.getCell(3));
data[index++] = parseDecimal(lngStr);
// LTTD - 纬度 (E列)
String latStr = getCellStringValue(row.getCell(4));
data[index++] = parseDecimal(latStr);
// TYPE - 类型 (F列)
data[index++] = getCellStringValue(row.getCell(5));
// WIDTH - 沟宽/m (G列)
String widthStr = getCellStringValue(row.getCell(6));
data[index++] = parseDecimal(widthStr);
// LENGTH - 沟深/m (H列)
String depthStr = getCellStringValue(row.getCell(7));
data[index++] = parseDecimal(depthStr);
// STYPE - 断面形态 (I列)
data[index++] = getCellStringValue(row.getCell(8));
// R2 - 阻水面积比/% (J列)
String r2Str = getCellStringValue(row.getCell(9));
data[index++] = parseDecimal(r2Str);
// RVNM - 河流名称 (K列)
data[index++] = getCellStringValue(row.getCell(10));
// RVCD - 河流代码 (L列)
data[index++] = getCellStringValue(row.getCell(11));
// REMARK - 备注 (M列)
data[index++] = getCellStringValue(row.getCell(12));
// 固定值字段
data[index++] = "1"; // ISENABLE
data[index++] = "2025"; // IMPORTYEAR
data[index++] = "1"; // INPUTTYPE
data[index++] = null; // AUDID
data[index++] = "1"; // STATUS
data[index++] = null; // SIGNER
data[index++] = countyCode; // CADCD
// GUID - 唯一标识
data[index++] = UUID.randomUUID().toString();
// AUDBATCH
data[index++] = "BATCH_" + System.currentTimeMillis();
// WSCD - 流域编码
data[index++] = watershedCode;
return data;
} catch (Exception e) {
System.err.println("解析行数据失败: " + e.getMessage());
return null;
}
}
private static int batchInsertData(List<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;
}
}
}