You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

176 lines
7.3 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package com.dsideal.base.Tools.JkyNewData;
import cn.idev.excel.*;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import com.dsideal.base.Tools.JkyNewData.Util.CloseLogUtil;
import com.dsideal.base.Tools.JkyNewData.Util.ColumnConfig;
import com.dsideal.base.Tools.JkyNewData.Util.ExcelUtil;
import com.dsideal.base.Tools.Util.LocalMysqlConnectUtil;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static com.dsideal.base.Tools.JkyNewData.Util.CommonUtil.log;
public class SchoolCountSummary {
// 配置文件
public static final String configDir = "D:/dsWork/YunNanDsBase/src/main/java/com/dsideal/base/Tools/JkyNewData/Data/";
public static final String excelPath = "D:/dsWork/2025年收集的人口与教育数据库20250328/2015-2020年的数据/基础教育";
public static void main(String[] args) throws FileNotFoundException {
// 一、关闭日志输出
CloseLogUtil.Init();
// 二、初始化数据库连接
LocalMysqlConnectUtil.Init();
// 三、清空数据表
String sql = "truncate table t_yn_school_count";
Db.update(sql);
// 四、获取所有配置文件
File dir = new File(configDir);
File[] configFiles = dir.listFiles((d, name) -> name.matches("SchoolCount_\\d{4}\\.json"));
if (configFiles != null) {
for (File configFile : configFiles) {
// 从文件名中提取年份
String fileName = configFile.getName();
String year = fileName.substring("SchoolCount_".length(), fileName.length() - 5);
log(String.format("开始处理年份:%s", year));
// 读取配置文件
JSONObject config = JSON.parseObject(new FileReader(configFile));
String filePath = String.format(excelPath + "/%s.xlsx", year);
// 创建一个Map来存储所有处理结果
Map<String, Map<String, Map<String, Integer>>> allResults = new HashMap<>();
// 循环处理每种学校类型
for (String schoolType : config.keySet()) {
log(String.format("开始处理学校类型:%s", schoolType));
// 获取当前学校类型的配置
JSONObject typeConfig = config.getJSONObject(schoolType);
Map<String, ColumnConfig> columnConfigs = new HashMap<>();
//表头的行数
int skipRows = typeConfig.getIntValue("skipRows");
// 转换配置为ColumnConfig对象
for (String key : typeConfig.keySet()) {
if (key.equals("skipRows")) continue;
JSONObject colConfig = typeConfig.getJSONObject(key);
columnConfigs.put(key, new ColumnConfig(
colConfig.getIntValue("index"),
colConfig.getString("name"),
colConfig.getString("type")
));
}
// 处理当前学校类型的数据
allResults.put(schoolType, processSheet(filePath, schoolType, skipRows, columnConfigs));
log(String.format("处理学校类型:%s完成", schoolType));
}
log(String.format("处理年份:%s完成", year));
// 保存统计结果到数据库
log(String.format("开始保存年份:%s到数据库", year));
saveToDatabase(allResults, Integer.parseInt(year));
log(String.format("保存年份:%s到数据库完成", year));
}
}
log("所有年份处理完成");
}
/**
* 处理指定 Sheet 表的数据
*
* @param filePath 文件路径
* @param sheetName Sheet 表名称
* @param skipRows 跳过的行数
* @param columnConfigs 列配置
* @return 处理结果Map
*/
private static Map<String, Map<String, Integer>> processSheet(String filePath, String sheetName, int skipRows, Map<String, ColumnConfig> columnConfigs) {
// 从指定行开始读取使用Map接收数据
List<Map<String, Object>> dataList = FastExcel.read(filePath)
.sheet(sheetName)
.headRowNumber(skipRows)
.doReadSync();
// 使用 Map 进行分组统计
Map<String, Map<String, Integer>> cityDistrictMap = new HashMap<>();
for (Map<String, Object> data : dataList) {
try {
// 根据列配置获取数据
String city = ExcelUtil.getColumnValue(data, columnConfigs.get("city"));
String district = ExcelUtil.getColumnValue(data, columnConfigs.get("district"));
int count = ExcelUtil.getColumnValueAsInt(data, columnConfigs.get("schoolCount"));
if (count > 0) {
// 如果市不存在,创建新的 Map
cityDistrictMap.putIfAbsent(city, new HashMap<>());
// 累加区对应的学校数量
cityDistrictMap.get(city).merge(district, count, Integer::sum);
}
} catch (Exception e) {
System.err.println("处理数据行时出错: " + data);
e.printStackTrace();
}
}
return cityDistrictMap;
}
/**
* 将统计结果保存到数据库
*
* @param allResults 所有处理结果
* @param year 年份
*/
private static void saveToDatabase(Map<String, Map<String, Map<String, Integer>>> allResults, int year) {
// 先删除该年份的旧数据
Db.delete("DELETE FROM t_yn_school_count WHERE year = ?", year);
// 遍历所有结果并保存
for (Map.Entry<String, Map<String, Map<String, Integer>>> schoolTypeEntry : allResults.entrySet()) {
String schoolType = schoolTypeEntry.getKey();
for (Map.Entry<String, Map<String, Integer>> cityEntry : schoolTypeEntry.getValue().entrySet()) {
String city = cityEntry.getKey();
for (Map.Entry<String, Integer> districtEntry : cityEntry.getValue().entrySet()) {
String district = districtEntry.getKey();
int count = districtEntry.getValue();
// 创建记录
Record record = new Record();
record.set("school_type", schoolType)
.set("city", city)
.set("district", district)
.set("school_count", count)
.set("year", year);
// 保存到数据库
Db.save("t_yn_school_count", record);
}
}
}
System.out.println("数据已成功保存到数据库");
}
}