
背景需求
20260812人事干部问我如何获取全园幼儿"户籍""积分性质""优抚子女"的信息。




我看了一下,两个问题:
1、园园通还有6位幼儿没有导入,信息不全
2、园园通(小班)的孩子的户籍信息不一定正确(为了去掉标红,户籍所在市、户籍所在区都是默认选第一个,是不正确的,后续要修改)
3、园园通里面没有"五类居住证"的信息说明------必须班主任向家长收集。
解决方案
所以我说"做接龙表单"班主任复制模版,修改班级名称,黏贴班级幼儿姓名。
人事干部说:那这个任务由你负责
OK,没问题
一、制作接龙表单(接龙管家)
1、制作一个"收集表单"的模版



其实只有三个问题

如果选"外省",才会出现五类选择


选择优抚子女



表单设计非常简单
二、发布总群
1、人事干部发送了通知

马上又一位老师来问:她在旅游无法手动查询幼儿户籍信息

2、把统计的接龙管家分享


3.个别老师年龄大,不会操作,我找到他们班的班级信息表,把文件复制一个"托3班"


4、我自己班级的表单发布


发布到本班班级群

4、表单下载
13.42-14.49, 1小时后,第一份表单收集整齐发给我了

表单里面标题:署名、班级、户籍所在地(本市本区、本市外区、外省等)、非户籍幼儿五类选择、是否军人、武警、消防子女(优抚对象)


小班25人满额,表单正确

家长手填的班级果然不是统一样式,

为了后面"分班""分园区",必须把班级名称修改统一。
下次考虑做"年级""班级"的单选按钮

我又把中2班(我自己班)的表单下载(还没有收齐),准备先做Python程序,做多份表单合并。

因为刚升班,所以家长有的填写小2班,有的填写中2班




这个问题还是很严重的,家长和老师对于升班后的年级还是容易遗忘的。
所以还是要手动检查修改
三、测试班级合并

python
'''
把19个班级的接龙管家的EXCEL表格合并在一起
豆包 阿夏
20260812
'''
import os
from openpyxl import load_workbook, Workbook
# 配置路径
path=r'C:\Users\mhjg2\Desktop\20260812幼儿园户籍信息统计'
folder_path = path +r"\01 20260812班级统计EXCEL" # 要读取的文件夹名
output_file = path+r"\20260812全部班级合并.xlsx" # 输出文件名
# 创建新的汇总工作簿
wb_total = Workbook()
ws_total = wb_total.active
ws_total.title = "合并数据"
# 标记是否已经写入表头
header_written = False
# 遍历123文件夹下所有文件
for filename in os.listdir(folder_path):
# 只处理xlsx后缀
if filename.lower().endswith(".xlsx"):
file_full_path = os.path.join(folder_path, filename)
print(f"正在处理:{filename}")
# 打开单个Excel文件
wb = load_workbook(file_full_path)
ws = wb.active
# 循环读取每一行
for row in ws.iter_rows(values_only=True):
if not header_written:
# 写入表头
ws_total.append(row)
header_written = True
else:
# 跳过其他文件的表头(第一行)
if row == tuple(ws[1]):
continue
ws_total.append(row)
# 保存最终合并文件
wb_total.save(output_file)
print(f"合并完成,文件已生成:{output_file}")


存在问题:后面的表格也有第一行标题(不需要)



python
'''
把19个班级的接龙管家的EXCEL表格合并在一起
豆包 阿夏
20260812
'''
import os
from openpyxl import load_workbook, Workbook
# ========== 自定义路径配置 ==========
path = r'C:\Users\mhjg2\Desktop\20260812幼儿园户籍信息统计'
folder_path = path + r"\01 20260812班级统计EXCEL"
output_file = path + r"\20260812全部班级合并.xlsx"
# ====================================
# 创建新的汇总Excel
total_wb = Workbook()
total_ws = total_wb.active
total_ws.title = "合并汇总"
# 筛选文件夹内所有xlsx文件
excel_files = []
for file_name in os.listdir(folder_path):
if file_name.lower().endswith(".xlsx"):
full_file_path = os.path.join(folder_path, file_name)
excel_files.append(full_file_path)
if len(excel_files) == 0:
print("文件夹内未找到任何.xlsx格式Excel文件")
else:
# 遍历每一个Excel
for index, file in enumerate(excel_files):
print(f"正在处理文件:{os.path.basename(file)}")
# data_only=True 读取单元格最终显示数值,不保留公式
wb = load_workbook(file, data_only=True)
ws = wb.active
if index == 0:
# 第一个文件:完整写入,保留表头第一行
for row_data in ws.iter_rows(values_only=True):
total_ws.append(row_data)
else:
# 后续所有文件:从第2行开始读取,自动跳过表头
for row_data in ws.iter_rows(min_row=2, values_only=True):
total_ws.append(row_data)
# 保存合并后的文件
total_wb.save(output_file)
print(f"\n✅ 合并完成!\n文件保存路径:{output_file}")

这次只有第一行是标题行,下面就没有标题了,

四、测试如何提取户籍地人数、五类证件人数、没有人数的填0
思考如何统计
1、把户籍七类,分别统计出来------本市本区10人,本市外区5人,外省20人"(已经显示出来的文字)+港澳台都默认写0(不存在的区域,默认写0)
2、把居住证五类,分别统计出来------项目A10人,项目B5人,项目C20人"(已经显示出来的文字,名称太长了)+(没有提到的项目,默认写0人)
3.把优抚对象两类,都是选否,默认0,如果"有",再继续分类

把表格里的名字和家长微信号都删除,附件上传豆包





如果都提取出来,太长了,有500多条,太慢了


看起来不方便,还是做成EXCEL




显示列太多了,我只要 几列



现在统计出来数量了。但是需要区分"园区"。




如何把统计出来的数据加入"提交EXCEL"内

把"提交EXCEL"的空表作为附件上传



目前是1个小班(一分园),1个中班(总园)

位置不对,再测试一次


填写位置还是很乱






太好了,大班没有,就默认0。
还有托班




现在两个班级分别在两个园区,不知道同一个园区的两个小班人数是否可以累加。
我复制小2班,变成小3班(假表),是否可以累加。

把三个程序运行一次

最后,25人变成50人,本区11变成22人,成功


再测试一个 中2班表格复制改成大4班

中2班改成大4班

四个班级表,三个代码跑一次


也成功了。我修改大4班的几个孩子的户籍为港澳台外籍其他

三个代码运行后,顺利识别了"五类特殊户籍"

很好,现在继续做代码,补全班级数


班级数量是正确的,但是还有混龄班和特教班,需要补0(这两个班级通常没有,如果有的话,需要在代码标注,小X班是混龄班、中X班是特教班,才能识别出来)


不错GH 列都写了0,但是最右侧没有写



这是第一张表。每个格子都写了数字。
第二张表





没用,还是0

换Deepseek












反复测试无数次,终于正确获取

三、做混龄班
它提示没有可以不写,我就暂时不写0了

四、统计优抚对象

还不容易有一位孩子是优抚对象,否则我都不知道应该怎么做提取

另外我也修改假名单,做点假数据,便于提取
、

、





都是大班的,没有托小中的数据。








还是这个样子,

我仔细看了一下,把数字右移动3列,就正确了







气死了,还是改不出来
























终于正确了



把已经收齐的内容,做一遍
第一步:把收集的表单合并成一个工作表(必须每个文件打开,班级名称统一为大1班这样,不要出现大一班,大(1)班这种)



python
'''
第1步
把19个班级的接龙管家的EXCEL表格合并在一起
豆包 阿夏
20260812
'''
import os
from openpyxl import load_workbook, Workbook
# ========== 自定义路径配置 ==========
path = r'C:\Users\mhjg2\Desktop\20260812幼儿园户籍信息统计'
folder_path = path + r"\01 20260812班级统计EXCEL"
output_file = path + r"\20260812全部班级合并.xlsx"
# ====================================
# 创建新的汇总Excel
total_wb = Workbook()
total_ws = total_wb.active
total_ws.title = "合并汇总"
# 筛选文件夹内所有xlsx文件
excel_files = []
for file_name in os.listdir(folder_path):
if file_name.lower().endswith(".xlsx"):
full_file_path = os.path.join(folder_path, file_name)
excel_files.append(full_file_path)
if len(excel_files) == 0:
print("文件夹内未找到任何.xlsx格式Excel文件")
else:
# 遍历每一个Excel
for index, file in enumerate(excel_files):
print(f"正在处理文件:{os.path.basename(file)}")
# data_only=True 读取单元格最终显示数值,不保留公式
wb = load_workbook(file, data_only=True)
ws = wb.active
if index == 0:
# 第一个文件:完整写入,保留表头第一行
for row_data in ws.iter_rows(values_only=True):
total_ws.append(row_data)
else:
# 后续所有文件:从第2行开始读取,自动跳过表头
for row_data in ws.iter_rows(min_row=2, values_only=True):
total_ws.append(row_data)
# 保存合并后的文件
total_wb.save(output_file)
print(f"\n✅ 合并完成!\n文件保存路径:{output_file}")



第二步:
python
'''
第2步
从合并表里提取每个班级的相同列的内容和数量
豆包 阿夏
20260812
'''
import pandas as pd
# ===================== 路径配置 =====================
folder_path = r'C:\Users\mhjg2\Desktop\20260812幼儿园户籍信息统计'
source_file = f"{folder_path}\\20260812全部班级合并.xlsx"
output_file = f"{folder_path}\\分析.xlsx"
# 需要统计的指定列
stat_cols = [
"班级",
"户籍所在地",
"非户籍幼儿五类明细选择",
"是否属于军人子女",
"军人子女类型",
"是否属于武警消防子女",
"武警消防子女类型"
]
# 园区班级映射规则
park_map = {
"总园": ["中1","中2","中3","中4","中5","中6","大1","大2","大3","大4","大5"],
"一分园": ["托1","托2","小4","小5"],
"二分园": ["托3","小1","小2","小3"]
}
# 构建班级→园区字典
class_to_park = {}
for park, class_list in park_map.items():
for c in class_list:
class_to_park[c] = park
# ===================== 读取数据 =====================
df = pd.read_excel(source_file)
df_stat = df[stat_cols].copy()
# 提取班级前缀匹配园区(如"中2班"截取"中2")
def get_park(class_name):
if pd.isna(class_name):
return "未知园区"
c_short = str(class_name).replace("班","")
return class_to_park.get(c_short, "未知园区")
df_stat["园区"] = df_stat["班级"].apply(get_park)
total_rows = len(df_stat)
print(f"全部数据总行数:{total_rows}")
# ===================== 1. 全局总统计 =====================
global_data = []
for col in stat_cols:
count_series = df_stat[col].value_counts(dropna=False)
ratio_series = df_stat[col].value_counts(normalize=True, dropna=False)
for text_val, count in count_series.items():
global_data.append({
"统计范围": "全局全部",
"列名称": col,
"内容文本": text_val,
"出现次数": count,
"整体占比": f"{ratio_series[text_val]:.2%}"
})
df_global = pd.DataFrame(global_data)
# ===================== 2. 按园区+班级分层统计 =====================
park_class_data = []
# 先按园区分组,园区内再按班级分组
group_obj = df_stat.groupby(["园区", "班级"])
for (park_name, class_name), group_df in group_obj:
class_total = len(group_df)
print(f"【{park_name}-{class_name}】本班总人数:{class_total}")
for col in stat_cols:
count_series = group_df[col].value_counts(dropna=False)
ratio_series = group_df[col].value_counts(normalize=True, dropna=False)
for text_val, count in count_series.items():
park_class_data.append({
"园区": park_name,
"班级": class_name,
"列名称": col,
"内容文本": text_val,
"本班出现次数": count,
"本班内占比": f"{ratio_series[text_val]:.2%}"
})
df_park_class = pd.DataFrame(park_class_data)
# ===================== 写入分析.xlsx =====================
with pd.ExcelWriter(output_file, engine="openpyxl") as writer:
df_global.to_excel(writer, sheet_name="全局汇总统计", index=False)
df_park_class.to_excel(writer, sheet_name="园区班级分层统计", index=False)
print(f"\n统计完成!结果已保存至:{output_file}")
print("仅统计指定7列,并按【总园/一分园/二分园】+班级双层分类汇总")


各班的户籍种类不同、五大明细的种类也不同

右侧有出现频率(合并数据)

第3步:统计到工作表内
python
'''
第3步
把分析出来的数量写入指定的模版里
豆包 阿夏
20260812
'''
from openpyxl import load_workbook
from openpyxl.styles import Alignment
# ===================== 路径配置 =====================
folder = r'C:\Users\mhjg2\Desktop\20260812幼儿园户籍信息统计'
data_excel = f"{folder}\\分析.xlsx"
template_excel = f"{folder}\\1 2026学年闵行区幼儿园概况表(总分园填在一张表上)(1).xlsx"
out_excel = f"{folder}\\最终版_户籍统计表_无合并报错.xlsx"
# ===================== 园区班级映射规则 =====================
park_class_rule = {
"总园": ["中1", "中2", "中3", "中4", "中5", "中6", "大1", "大2", "大3", "大4", "大5"],
"一分园": ["托1", "托2", "小4", "小5"],
"二分园": ["托3", "小1", "小2", "小3"]
}
class_to_park = {}
for park, cls_list in park_class_rule.items():
for cls in cls_list:
class_to_park[cls] = park
# 班级转年级工具函数
def class_to_grade(class_name: str) -> str:
c = class_name.strip()
if "托" in c:
return "托班"
elif "小" in c:
return "小班"
elif "中" in c:
return "中班"
elif "大" in c:
return "大班"
return None
# ===================== 优抚表配置(修改:固定写入40/41/42行) =====================
park_write_row = {
"总园": 40,
"一分园": 41,
"二分园": 42
}
# 列组规则:(小计列, 托班列, 小班列, 中班列, 大班列)
col_rule = {
"军人现役_符合": (3, 4, 5, 6, 7), # C小计 D托 E小 F中 G大
"军人退役_符合": (13, 14, 15, 16, 17), # M小计 N托 O小 P中 Q大
"武警现役_符合": (24, 25, 26, 27, 28), # X小计 Y托 Z小 AA中 AB大
"武警退役_符合": (34, 35, 36, 37, 38) # AH小计 AI托 AJ小 AK中 AL大
}
# 优抚数据存储容器
army_warrior_total = {
"总园": {
"军人现役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0},
"军人退役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0},
"武警现役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0},
"武警退役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0}
},
"一分园": {
"军人现役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0},
"军人退役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0},
"武警现役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0},
"武警退役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0}
},
"二分园": {
"军人现役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0},
"军人退役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0},
"武警现役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0},
"武警退役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0}
}
}
# ===================== 读取数据源【分析.xlsx】提取优抚数据 =====================
wb_data = load_workbook(data_excel)
ws_data = wb_data["园区班级分层统计"]
rows_data = list(ws_data.iter_rows(values_only=True))
header = rows_data[0]
data_list = rows_data[1:]
print("===== 所有列名 =====")
for i, h in enumerate(header):
print(f"列{i}: {h}")
# 拆分三类数据
df_hukou = []
df_nonlocal = []
df_army_warrior = []
for row in data_list:
row_dict = dict(zip(header, row))
col_name = row_dict.get("列名称")
if col_name == "户籍所在地":
df_hukou.append(row_dict)
elif col_name == "非户籍幼儿五类明细选择":
df_nonlocal.append(row_dict)
elif col_name in ("军人子女类型", "武警消防子女类型"):
df_army_warrior.append(row_dict)
print(f"\n读取户籍记录总数:{len(df_hukou)}")
print(f"读取非户籍五类记录总数:{len(df_nonlocal)}")
print(f"读取军人/武警优抚记录总数:{len(df_army_warrior)}")
# ===================== 统计优抚子女数据(从分析表汇总) =====================
print("\n===== 统计军人武警优抚子女数据 =====")
for row_dict in df_army_warrior:
park = str(row_dict["园区"]).strip()
cls_name = str(row_dict["班级"]).strip()
col_type = row_dict["列名称"]
content = str(row_dict["内容文本"]).strip()
cnt = int(row_dict["本班出现次数"])
grade = class_to_grade(cls_name)
if park not in army_warrior_total or grade is None or cnt <= 0:
continue
target_key = None
if col_type == "军人子女类型":
if "现役" in content:
target_key = "军人现役"
elif "退役" in content:
target_key = "军人退役"
elif col_type == "武警消防子女类型":
if "现役" in content:
target_key = "武警现役"
elif "退役" in content:
target_key = "武警退役"
if target_key:
army_warrior_total[park][target_key][grade] += cnt
# 控制台打印核对数据
for park in ["总园", "一分园", "二分园"]:
print(f"\n【{park}】优抚汇总:")
for k, v in army_warrior_total[park].items():
total = sum(v.values())
print(f" {k} 合计{total} → 托{v['托班']} 小{v['小班']} 中{v['中班']} 大{v['大班']}")
# ===================== 1、主表托小中大户籍容器 =====================
parks = ["总园", "一分园", "二分园"]
park_student_data = {
"总园": {
"托班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0},
"小班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0},
"中班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0},
"大班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0}
},
"一分园": {
"托班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0},
"小班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0},
"中班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0},
"大班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0}
},
"二分园": {
"托班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0},
"小班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0},
"中班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0},
"大班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0}
}
}
# ===================== 2、开班数量统计 =====================
all_class_raw = set()
for r in data_list:
cls = dict(zip(header, r)).get("班级")
if cls:
all_class_raw.add(str(cls))
short_class_set = set()
for c in all_class_raw:
short_c = str(c).replace("班", "").strip()
short_class_set.add(short_c)
class_count = {
"总园": {"托班": 0, "小班": 0, "中班": 0, "大班": 0, "混龄班": 0, "特教班": 0, "合计": 0},
"一分园": {"托班": 0, "小班": 0, "中班": 0, "大班": 0, "混龄班": 0, "特教班": 0, "合计": 0},
"二分园": {"托班": 0, "小班": 0, "中班": 0, "大班": 0, "混龄班": 0, "特教班": 0, "合计": 0}
}
for sc in short_class_set:
if sc not in class_to_park:
continue
p = class_to_park[sc]
if "托" in sc:
class_count[p]["托班"] += 1
elif "小" in sc:
class_count[p]["小班"] += 1
elif "中" in sc:
class_count[p]["中班"] += 1
elif "大" in sc:
class_count[p]["大班"] += 1
elif "混" in sc:
class_count[p]["混龄班"] += 1
elif "特" in sc:
class_count[p]["特教班"] += 1
for p in class_count:
class_count[p]["合计"] = class_count[p]["托班"] + class_count[p]["小班"] + class_count[p]["中班"] + class_count[p]["大班"] + class_count[p]["混龄班"] + class_count[p]["特教班"]
print("\n===== 班级数量 =====")
for park in parks:
print(f" {park}: {class_count[park]}")
# ===================== 3、统计户籍数据 =====================
print("\n===== 统计户籍数据 =====")
for row_dict in df_hukou:
park = str(row_dict["园区"]).strip()
class_name = str(row_dict["班级"]).strip()
content = str(row_dict["内容文本"]).strip()
num = int(row_dict["本班出现次数"])
grade_main = None
if "托" in class_name:
grade_main = "托班"
elif "小" in class_name:
grade_main = "小班"
elif "中" in class_name:
grade_main = "中班"
elif "大" in class_name:
grade_main = "大班"
elif "混" in class_name:
grade_main = "混龄班"
elif "特" in class_name:
grade_main = "特教班"
if grade_main is None or park not in park_student_data:
continue
if "本市本区" in content:
park_student_data[park][grade_main]["本区"] += num
elif "本市外区" in content:
park_student_data[park][grade_main]["外区"] += num
elif "外省" in content:
park_student_data[park][grade_main]["外省"] += num
elif "港" in content or "香港" in content:
park_student_data[park][grade_main]["港"] += num
elif "澳" in content or "澳门" in content:
park_student_data[park][grade_main]["澳"] += num
elif "台" in content or "台湾" in content:
park_student_data[park][grade_main]["台"] += num
elif "外籍" in content:
park_student_data[park][grade_main]["外籍"] += num
else:
park_student_data[park][grade_main]["其他"] += num
print("✅ 户籍数据统计完成")
# ===================== 4、统计非本市户籍五类数据 =====================
print("\n===== 统计非户籍五类数据 =====")
class_grade_map = {}
for row in data_list:
row_dict = dict(zip(header, row))
if row_dict.get("列名称") == "班级":
park = str(row_dict.get("园区") or "").strip()
class_name = str(row_dict.get("班级") or "").strip()
if park and class_name:
grade = None
if "托" in class_name:
grade = "托班"
elif "小" in class_name:
grade = "小班"
elif "中" in class_name:
grade = "中班"
elif "大" in class_name:
grade = "大班"
if grade:
class_grade_map[(park, class_name)] = grade
non_local_data = {}
for park in parks:
non_local_data[park] = {
"type1": {"大班": 0, "中班": 0, "小班": 0},
"type2": {"大班": 0, "中班": 0, "小班": 0},
"type3": {"大班": 0, "中班": 0, "小班": 0},
"type4": {"大班": 0, "中班": 0, "小班": 0},
"type5": {"大班": 0, "中班": 0, "小班": 0}
}
for row_dict in df_nonlocal:
park = str(row_dict["园区"]).strip()
class_name = str(row_dict["班级"]).strip()
content = str(row_dict["内容文本"]).strip()
num = int(row_dict["本班出现次数"])
if not content or num == 0:
continue
if park not in parks:
continue
grade = class_grade_map.get((park, class_name))
if not grade:
continue
if grade not in ["大班", "中班", "小班"]:
continue
match_type = None
if "120" in content:
match_type = "type1"
elif "房产" in content and "积分不满" in content:
match_type = "type2"
elif "满6个月" in content and "不满" not in content:
match_type = "type3"
elif "不满6个月" in content:
match_type = "type4"
elif "无居住证" in content:
match_type = "type5"
if match_type:
non_local_data[park][match_type][grade] += num
type_names = {"type1": "积分120", "type2": "仅有房产", "type3": "社保满6", "type4": "社保不满6", "type5": "无居住证"}
for park in parks:
print(f"\n【{park}】")
has_data = False
for k, v in non_local_data[park].items():
total = sum(v.values())
if total > 0:
has_data = True
print(f" {type_names.get(k)}: 合计{total}, 大班={v['大班']}, 中班={v['中班']}, 小班={v['小班']}")
if not has_data:
print(" 无数据")
# ===================== 写入Excel基础数据(开班、户籍、非户籍) =====================
wb = load_workbook(template_excel)
ws = wb.active
cell_align = Alignment(horizontal="center", vertical="center", text_rotation=0)
row_upper = {"总园": 7, "一分园": 8, "二分园": 9}
row_detail = {"总园": 15, "一分园": 16, "二分园": 17}
# 列常量
B, C, D, E, F, G, H = 2, 3, 4, 5, 6, 7, 8
I, J, K, L, M, N = 9, 10, 11, 12, 13, 14
O, P, Q, R, S, T = 15, 16, 17, 18, 19, 20
U, V, W, X, Y, Z = 21, 22, 23, 24, 25, 26
AA, AB, AC, AD, AE, AF = 27, 28, 29, 30, 31, 32
AG, AH, AI, AJ, AK, AL, AM, AN, AO, AP, AQ, AR, AS, AT, AU = 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47
print("\n===== 开始写入Excel主表基础数据 =====")
for park in parks:
r_up = row_upper[park]
r_det = row_detail[park]
cnt = class_count[park]
stu = park_student_data[park]
nl = non_local_data[park]
# 开班数量 B~H
ws.cell(row=r_up, column=B, value=cnt["合计"]).alignment = cell_align
ws.cell(row=r_up, column=C, value=cnt["托班"]).alignment = cell_align
ws.cell(row=r_up, column=D, value=cnt["小班"]).alignment = cell_align
ws.cell(row=r_up, column=E, value=cnt["中班"]).alignment = cell_align
ws.cell(row=r_up, column=F, value=cnt["大班"]).alignment = cell_align
ws.cell(row=r_up, column=G, value=cnt["混龄班"]).alignment = cell_align
ws.cell(row=r_up, column=H, value=cnt["特教班"]).alignment = cell_align
ws.cell(row=r_up, column=AT, value=cnt["混龄班"]).alignment = cell_align
ws.cell(row=r_up, column=AU, value=cnt["特教班"]).alignment = cell_align
# 托班户籍 J~R
t = stu["托班"]
ws.cell(row=r_up, column=J, value=sum(t.values())).alignment = cell_align
ws.cell(row=r_up, column=K, value=t["本区"]).alignment = cell_align
ws.cell(row=r_up, column=L, value=t["外区"]).alignment = cell_align
ws.cell(row=r_up, column=M, value=t["外省"]).alignment = cell_align
ws.cell(row=r_up, column=N, value=t["港"]).alignment = cell_align
ws.cell(row=r_up, column=O, value=t["澳"]).alignment = cell_align
ws.cell(row=r_up, column=P, value=t["台"]).alignment = cell_align
ws.cell(row=r_up, column=Q, value=t["外籍"]).alignment = cell_align
ws.cell(row=r_up, column=R, value=t["其他"]).alignment = cell_align
# 小班户籍 S~AA
x = stu["小班"]
ws.cell(row=r_up, column=S, value=sum(x.values())).alignment = cell_align
ws.cell(row=r_up, column=T, value=x["本区"]).alignment = cell_align
ws.cell(row=r_up, column=U, value=x["外区"]).alignment = cell_align
ws.cell(row=r_up, column=V, value=x["外省"]).alignment = cell_align
ws.cell(row=r_up, column=W, value=x["港"]).alignment = cell_align
ws.cell(row=r_up, column=X, value=x["澳"]).alignment = cell_align
ws.cell(row=r_up, column=Y, value=x["台"]).alignment = cell_align
ws.cell(row=r_up, column=Z, value=x["外籍"]).alignment = cell_align
ws.cell(row=r_up, column=AA, value=x["其他"]).alignment = cell_align
# 中班户籍 AB~AJ
z = stu["中班"]
ws.cell(row=r_up, column=AB, value=sum(z.values())).alignment = cell_align
ws.cell(row=r_up, column=AC, value=z["本区"]).alignment = cell_align
ws.cell(row=r_up, column=AD, value=z["外区"]).alignment = cell_align
ws.cell(row=r_up, column=AE, value=z["外省"]).alignment = cell_align
ws.cell(row=r_up, column=AF, value=z["港"]).alignment = cell_align
ws.cell(row=r_up, column=AG, value=z["澳"]).alignment = cell_align
ws.cell(row=r_up, column=AH, value=z["台"]).alignment = cell_align
ws.cell(row=r_up, column=AI, value=z["外籍"]).alignment = cell_align
ws.cell(row=r_up, column=AJ, value=z["其他"]).alignment = cell_align
# 大班户籍 AK~AS
d = stu["大班"]
ws.cell(row=r_up, column=AK, value=sum(d.values())).alignment = cell_align
ws.cell(row=r_up, column=AL, value=d["本区"]).alignment = cell_align
ws.cell(row=r_up, column=AM, value=d["外区"]).alignment = cell_align
ws.cell(row=r_up, column=AN, value=d["外省"]).alignment = cell_align
ws.cell(row=r_up, column=AO, value=d["港"]).alignment = cell_align
ws.cell(row=r_up, column=AP, value=d["澳"]).alignment = cell_align
ws.cell(row=r_up, column=AQ, value=d["台"]).alignment = cell_align
ws.cell(row=r_up, column=AR, value=d["外籍"]).alignment = cell_align
ws.cell(row=r_up, column=AS, value=d["其他"]).alignment = cell_align
# 非户籍明细表
total_all = sum([sum(nl[t].values()) for t in nl])
ws.cell(row=r_det, column=B, value=total_all).alignment = cell_align
# type1
ws.cell(row=r_det, column=C, value=sum(nl["type1"].values())).alignment = cell_align
ws.cell(row=r_det, column=D, value=nl["type1"]["大班"]).alignment = cell_align
ws.cell(row=r_det, column=E, value=nl["type1"]["中班"]).alignment = cell_align
ws.cell(row=r_det, column=F, value=nl["type1"]["小班"]).alignment = cell_align
ws.cell(row=r_det, column=G, value=0).alignment = cell_align
ws.cell(row=r_det, column=H, value=0).alignment = cell_align
# type2
ws.cell(row=r_det, column=I, value=sum(nl["type2"].values())).alignment = cell_align
ws.cell(row=r_det, column=J, value=nl["type2"]["大班"]).alignment = cell_align
ws.cell(row=r_det, column=K, value=nl["type2"]["中班"]).alignment = cell_align
ws.cell(row=r_det, column=L, value=nl["type2"]["小班"]).alignment = cell_align
ws.cell(row=r_det, column=M, value=0).alignment = cell_align
ws.cell(row=r_det, column=N, value=0).alignment = cell_align
# type3
ws.cell(row=r_det, column=O, value=sum(nl["type3"].values())).alignment = cell_align
ws.cell(row=r_det, column=P, value=nl["type3"]["大班"]).alignment = cell_align
ws.cell(row=r_det, column=Q, value=nl["type3"]["中班"]).alignment = cell_align
ws.cell(row=r_det, column=R, value=nl["type3"]["小班"]).alignment = cell_align
ws.cell(row=r_det, column=S, value=0).alignment = cell_align
ws.cell(row=r_det, column=T, value=0).alignment = cell_align
# type4
ws.cell(row=r_det, column=U, value=sum(nl["type4"].values())).alignment = cell_align
ws.cell(row=r_det, column=V, value=nl["type4"]["大班"]).alignment = cell_align
ws.cell(row=r_det, column=W, value=nl["type4"]["中班"]).alignment = cell_align
ws.cell(row=r_det, column=X, value=nl["type4"]["小班"]).alignment = cell_align
ws.cell(row=r_det, column=Y, value=0).alignment = cell_align
ws.cell(row=r_det, column=Z, value=0).alignment = cell_align
# type5
ws.cell(row=r_det, column=AA, value=sum(nl["type5"].values())).alignment = cell_align
ws.cell(row=r_det, column=AB, value=nl["type5"]["大班"]).alignment = cell_align
ws.cell(row=r_det, column=AC, value=nl["type5"]["中班"]).alignment = cell_align
ws.cell(row=r_det, column=AD, value=nl["type5"]["小班"]).alignment = cell_align
ws.cell(row=r_det, column=AE, value=0).alignment = cell_align
ws.cell(row=r_det, column=AF, value=0).alignment = cell_align
print(f" ✅ {park} 基础数据写入完成")
# ===================== 优抚子女明细写入【全部小计加异常捕获,固定40/41/42行】 =====================
print("\n===== 写入军人武警优抚子女明细表格 =====")
for park_name, write_r in park_write_row.items():
data = army_warrior_total[park_name]
# 1. 军人现役 符合本园条件
cols = col_rule["军人现役_符合"]
try:
cell_obj = ws.cell(write_r, cols[0], value=sum(data["军人现役"].values()))
cell_obj.alignment = cell_align
except AttributeError:
pass
ws.cell(write_r, cols[1], value=data["军人现役"]["托班"]).alignment = cell_align
ws.cell(write_r, cols[2], value=data["军人现役"]["小班"]).alignment = cell_align
ws.cell(write_r, cols[3], value=data["军人现役"]["中班"]).alignment = cell_align
ws.cell(write_r, cols[4], value=data["军人现役"]["大班"]).alignment = cell_align
# 2. 军人退役 符合本园条件
cols = col_rule["军人退役_符合"]
try:
cell_obj = ws.cell(write_r, cols[0], value=sum(data["军人退役"].values()))
cell_obj.alignment = cell_align
except AttributeError:
pass
ws.cell(write_r, cols[1], value=data["军人退役"]["托班"]).alignment = cell_align
ws.cell(write_r, cols[2], value=data["军人退役"]["小班"]).alignment = cell_align
ws.cell(write_r, cols[3], value=data["军人退役"]["中班"]).alignment = cell_align
ws.cell(write_r, cols[4], value=data["军人退役"]["大班"]).alignment = cell_align
# 3. 武警现役 符合本园条件
cols = col_rule["武警现役_符合"]
try:
cell_obj = ws.cell(write_r, cols[0], value=sum(data["武警现役"].values()))
cell_obj.alignment = cell_align
except AttributeError:
pass
ws.cell(write_r, cols[1], value=data["武警现役"]["托班"]).alignment = cell_align
ws.cell(write_r, cols[2], value=data["武警现役"]["小班"]).alignment = cell_align
ws.cell(write_r, cols[3], value=data["武警现役"]["中班"]).alignment = cell_align
ws.cell(write_r, cols[4], value=data["武警现役"]["大班"]).alignment = cell_align
# 4. 武警退役 符合本园条件
cols = col_rule["武警退役_符合"]
try:
cell_obj = ws.cell(write_r, cols[0], value=sum(data["武警退役"].values()))
cell_obj.alignment = cell_align
except AttributeError:
pass
ws.cell(write_r, cols[1], value=data["武警退役"]["托班"]).alignment = cell_align
ws.cell(write_r, cols[2], value=data["武警退役"]["小班"]).alignment = cell_align
ws.cell(write_r, cols[3], value=data["武警退役"]["中班"]).alignment = cell_align
ws.cell(write_r, cols[4], value=data["武警退役"]["大班"]).alignment = cell_align
print("✅ 优抚子女明细全部写入完成,大班数据已锁定每组最后单元格")
# 文件保存关闭
wb.save(out_excel)
wb.close()
wb_data.save(data_excel)
wb_data.close()
print(f"\n🎉 全部程序执行完毕!输出文件路径:\n{out_excel}")


核对1:班级数

正确

所属园区


随机抽检查正确性








数据全部正确。好开心。
这个模版里面用了公式



AI编程改起来飞速
python
'''
第3步
把分析出来的数量写入指定的模版里(保留原模版的公式,小计、总计,都不要填入数字)
豆包 阿夏
20260812
'''
from openpyxl import load_workbook
from openpyxl.styles import Alignment
# ===================== 路径配置 =====================
folder = r'C:\Users\mhjg2\Desktop\20260812幼儿园户籍信息统计'
data_excel = f"{folder}\\分析.xlsx"
template_excel = f"{folder}\\1 2026学年闵行区幼儿园概况表(总分园填在一张表上)(1).xlsx"
out_excel = f"{folder}\\统计2.xlsx" # 输出文件名改为统计2.xlsx
# ===================== 园区班级映射规则 =====================
park_class_rule = {
"总园": ["中1", "中2", "中3", "中4", "中5", "中6", "大1", "大2", "大3", "大4", "大5"],
"一分园": ["托1", "托2", "小4", "小5"],
"二分园": ["托3", "小1", "小2", "小3"]
}
class_to_park = {}
for park, cls_list in park_class_rule.items():
for cls in cls_list:
class_to_park[cls] = park
# 班级转年级工具函数
def class_to_grade(class_name: str) -> str:
c = class_name.strip()
if "托" in c:
return "托班"
elif "小" in c:
return "小班"
elif "中" in c:
return "中班"
elif "大" in c:
return "大班"
return None
# ===================== 优抚表配置(固定写入40/41/42行) =====================
park_write_row = {
"总园": 40,
"一分园": 41,
"二分园": 42
}
# 列组规则:(小计列, 托班列, 小班列, 中班列, 大班列)
col_rule = {
"军人现役_符合": (3, 4, 5, 6, 7), # C小计 D托 E小 F中 G大
"军人退役_符合": (13, 14, 15, 16, 17), # M小计 N托 O小 P中 Q大
"武警现役_符合": (24, 25, 26, 27, 28), # X小计 Y托 Z小 AA中 AB大
"武警退役_符合": (34, 35, 36, 37, 38) # AH小计 AI托 AJ小 AK中 AL大
}
# 优抚数据存储容器
army_warrior_total = {
"总园": {
"军人现役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0},
"军人退役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0},
"武警现役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0},
"武警退役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0}
},
"一分园": {
"军人现役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0},
"军人退役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0},
"武警现役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0},
"武警退役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0}
},
"二分园": {
"军人现役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0},
"军人退役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0},
"武警现役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0},
"武警退役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0}
}
}
# ===================== 读取数据源【分析.xlsx】提取优抚数据 =====================
wb_data = load_workbook(data_excel)
ws_data = wb_data["园区班级分层统计"]
rows_data = list(ws_data.iter_rows(values_only=True))
header = rows_data[0]
data_list = rows_data[1:]
print("===== 所有列名 =====")
for i, h in enumerate(header):
print(f"列{i}: {h}")
# 拆分三类数据
df_hukou = []
df_nonlocal = []
df_army_warrior = []
for row in data_list:
row_dict = dict(zip(header, row))
col_name = row_dict.get("列名称")
if col_name == "户籍所在地":
df_hukou.append(row_dict)
elif col_name == "非户籍幼儿五类明细选择":
df_nonlocal.append(row_dict)
elif col_name in ("军人子女类型", "武警消防子女类型"):
df_army_warrior.append(row_dict)
print(f"\n读取户籍记录总数:{len(df_hukou)}")
print(f"读取非户籍五类记录总数:{len(df_nonlocal)}")
print(f"读取军人/武警优抚记录总数:{len(df_army_warrior)}")
# ===================== 统计优抚子女数据(从分析表汇总) =====================
print("\n===== 统计军人武警优抚子女数据 =====")
for row_dict in df_army_warrior:
park = str(row_dict["园区"]).strip()
cls_name = str(row_dict["班级"]).strip()
col_type = row_dict["列名称"]
content = str(row_dict["内容文本"]).strip()
cnt = int(row_dict["本班出现次数"])
grade = class_to_grade(cls_name)
if park not in army_warrior_total or grade is None or cnt <= 0:
continue
target_key = None
if col_type == "军人子女类型":
if "现役" in content:
target_key = "军人现役"
elif "退役" in content:
target_key = "军人退役"
elif col_type == "武警消防子女类型":
if "现役" in content:
target_key = "武警现役"
elif "退役" in content:
target_key = "武警退役"
if target_key:
army_warrior_total[park][target_key][grade] += cnt
# 控制台打印核对数据
for park in ["总园", "一分园", "二分园"]:
print(f"\n【{park}】优抚汇总:")
for k, v in army_warrior_total[park].items():
total = sum(v.values())
print(f" {k} 合计{total} → 托{v['托班']} 小{v['小班']} 中{v['中班']} 大{v['大班']}")
# ===================== 1、主表托小中大户籍容器 =====================
parks = ["总园", "一分园", "二分园"]
park_student_data = {
"总园": {
"托班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0},
"小班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0},
"中班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0},
"大班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0}
},
"一分园": {
"托班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0},
"小班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0},
"中班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0},
"大班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0}
},
"二分园": {
"托班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0},
"小班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0},
"中班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0},
"大班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0}
}
}
# ===================== 2、开班数量统计 =====================
all_class_raw = set()
for r in data_list:
cls = dict(zip(header, r)).get("班级")
if cls:
all_class_raw.add(str(cls))
short_class_set = set()
for c in all_class_raw:
short_c = str(c).replace("班", "").strip()
short_class_set.add(short_c)
class_count = {
"总园": {"托班": 0, "小班": 0, "中班": 0, "大班": 0, "混龄班": 0, "特教班": 0},
"一分园": {"托班": 0, "小班": 0, "中班": 0, "大班": 0, "混龄班": 0, "特教班": 0},
"二分园": {"托班": 0, "小班": 0, "中班": 0, "大班": 0, "混龄班": 0, "特教班": 0}
}
for sc in short_class_set:
if sc not in class_to_park:
continue
p = class_to_park[sc]
if "托" in sc:
class_count[p]["托班"] += 1
elif "小" in sc:
class_count[p]["小班"] += 1
elif "中" in sc:
class_count[p]["中班"] += 1
elif "大" in sc:
class_count[p]["大班"] += 1
elif "混" in sc:
class_count[p]["混龄班"] += 1
elif "特" in sc:
class_count[p]["特教班"] += 1
print("\n===== 班级数量 =====")
for park in parks:
print(f" {park}: {class_count[park]}")
# ===================== 3、统计户籍数据 =====================
print("\n===== 统计户籍数据 =====")
for row_dict in df_hukou:
park = str(row_dict["园区"]).strip()
class_name = str(row_dict["班级"]).strip()
content = str(row_dict["内容文本"]).strip()
num = int(row_dict["本班出现次数"])
grade_main = None
if "托" in class_name:
grade_main = "托班"
elif "小" in class_name:
grade_main = "小班"
elif "中" in class_name:
grade_main = "中班"
elif "大" in class_name:
grade_main = "大班"
elif "混" in class_name:
grade_main = "混龄班"
elif "特" in class_name:
grade_main = "特教班"
if grade_main is None or park not in park_student_data:
continue
if "本市本区" in content:
park_student_data[park][grade_main]["本区"] += num
elif "本市外区" in content:
park_student_data[park][grade_main]["外区"] += num
elif "外省" in content:
park_student_data[park][grade_main]["外省"] += num
elif "港" in content or "香港" in content:
park_student_data[park][grade_main]["港"] += num
elif "澳" in content or "澳门" in content:
park_student_data[park][grade_main]["澳"] += num
elif "台" in content or "台湾" in content:
park_student_data[park][grade_main]["台"] += num
elif "外籍" in content:
park_student_data[park][grade_main]["外籍"] += num
else:
park_student_data[park][grade_main]["其他"] += num
print("✅ 户籍数据统计完成")
# ===================== 4、统计非本市户籍五类数据 =====================
print("\n===== 统计非户籍五类数据 =====")
class_grade_map = {}
for row in data_list:
row_dict = dict(zip(header, row))
if row_dict.get("列名称") == "班级":
park = str(row_dict.get("园区") or "").strip()
class_name = str(row_dict.get("班级") or "").strip()
if park and class_name:
grade = None
if "托" in class_name:
grade = "托班"
elif "小" in class_name:
grade = "小班"
elif "中" in class_name:
grade = "中班"
elif "大" in class_name:
grade = "大班"
if grade:
class_grade_map[(park, class_name)] = grade
non_local_data = {}
for park in parks:
non_local_data[park] = {
"type1": {"大班": 0, "中班": 0, "小班": 0},
"type2": {"大班": 0, "中班": 0, "小班": 0},
"type3": {"大班": 0, "中班": 0, "小班": 0},
"type4": {"大班": 0, "中班": 0, "小班": 0},
"type5": {"大班": 0, "中班": 0, "小班": 0}
}
for row_dict in df_nonlocal:
park = str(row_dict["园区"]).strip()
class_name = str(row_dict["班级"]).strip()
content = str(row_dict["内容文本"]).strip()
num = int(row_dict["本班出现次数"])
if not content or num == 0:
continue
if park not in parks:
continue
grade = class_grade_map.get((park, class_name))
if not grade:
continue
if grade not in ["大班", "中班", "小班"]:
continue
match_type = None
if "120" in content:
match_type = "type1"
elif "房产" in content and "积分不满" in content:
match_type = "type2"
elif "满6个月" in content and "不满" not in content:
match_type = "type3"
elif "不满6个月" in content:
match_type = "type4"
elif "无居住证" in content:
match_type = "type5"
if match_type:
non_local_data[park][match_type][grade] += num
type_names = {"type1": "积分120", "type2": "仅有房产", "type3": "社保满6", "type4": "社保不满6", "type5": "无居住证"}
for park in parks:
print(f"\n【{park}】")
has_data = False
for k, v in non_local_data[park].items():
total = sum(v.values())
if total > 0:
has_data = True
print(f" {type_names.get(k)}: 合计{total}, 大班={v['大班']}, 中班={v['中班']}, 小班={v['小班']}")
if not has_data:
print(" 无数据")
# ===================== 写入Excel基础数据(只填明细,保留模板公式合计) =====================
# read_only=False 完整加载模板所有格式、公式、合并单元格
wb = load_workbook(template_excel)
ws = wb.active
cell_align = Alignment(horizontal="center", vertical="center", text_rotation=0)
row_upper = {"总园": 7, "一分园": 8, "二分园": 9}
row_detail = {"总园": 15, "一分园": 16, "二分园": 17}
# 列常量
B, C, D, E, F, G, H = 2, 3, 4, 5, 6, 7, 8
I, J, K, L, M, N = 9, 10, 11, 12, 13, 14
O, P, Q, R, S, T = 15, 16, 17, 18, 19, 20
U, V, W, X, Y, Z = 21, 22, 23, 24, 25, 26
AA, AB, AC, AD, AE, AF = 27, 28, 29, 30, 31, 32
AG, AH, AI, AJ, AK, AL, AM, AN, AO, AP, AQ, AR, AS, AT, AU = 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47
print("\n===== 开始写入Excel明细数据(保留原有公式) =====")
for park in parks:
r_up = row_upper[park]
r_det = row_detail[park]
cnt = class_count[park]
stu = park_student_data[park]
nl = non_local_data[park]
# 开班数量:只填托/小/中/大/混/特明细列,B合计列不写入(模板公式自动算)
ws.cell(row=r_up, column=C, value=cnt["托班"]).alignment = cell_align
ws.cell(row=r_up, column=D, value=cnt["小班"]).alignment = cell_align
ws.cell(row=r_up, column=E, value=cnt["中班"]).alignment = cell_align
ws.cell(row=r_up, column=F, value=cnt["大班"]).alignment = cell_align
ws.cell(row=r_up, column=G, value=cnt["混龄班"]).alignment = cell_align
ws.cell(row=r_up, column=H, value=cnt["特教班"]).alignment = cell_align
ws.cell(row=r_up, column=AT, value=cnt["混龄班"]).alignment = cell_align
ws.cell(row=r_up, column=AU, value=cnt["特教班"]).alignment = cell_align
# 托班户籍明细:本区/外区/外省/港/澳/台/外籍/其他,J小计不写入
t = stu["托班"]
ws.cell(row=r_up, column=K, value=t["本区"]).alignment = cell_align
ws.cell(row=r_up, column=L, value=t["外区"]).alignment = cell_align
ws.cell(row=r_up, column=M, value=t["外省"]).alignment = cell_align
ws.cell(row=r_up, column=N, value=t["港"]).alignment = cell_align
ws.cell(row=r_up, column=O, value=t["澳"]).alignment = cell_align
ws.cell(row=r_up, column=P, value=t["台"]).alignment = cell_align
ws.cell(row=r_up, column=Q, value=t["外籍"]).alignment = cell_align
ws.cell(row=r_up, column=R, value=t["其他"]).alignment = cell_align
# 小班户籍明细,S小计跳过
x = stu["小班"]
ws.cell(row=r_up, column=T, value=x["本区"]).alignment = cell_align
ws.cell(row=r_up, column=U, value=x["外区"]).alignment = cell_align
ws.cell(row=r_up, column=V, value=x["外省"]).alignment = cell_align
ws.cell(row=r_up, column=W, value=x["港"]).alignment = cell_align
ws.cell(row=r_up, column=X, value=x["澳"]).alignment = cell_align
ws.cell(row=r_up, column=Y, value=x["台"]).alignment = cell_align
ws.cell(row=r_up, column=Z, value=x["外籍"]).alignment = cell_align
ws.cell(row=r_up, column=AA, value=x["其他"]).alignment = cell_align
# 中班户籍明细,AB小计跳过
z = stu["中班"]
ws.cell(row=r_up, column=AC, value=z["本区"]).alignment = cell_align
ws.cell(row=r_up, column=AD, value=z["外区"]).alignment = cell_align
ws.cell(row=r_up, column=AE, value=z["外省"]).alignment = cell_align
ws.cell(row=r_up, column=AF, value=z["港"]).alignment = cell_align
ws.cell(row=r_up, column=AG, value=z["澳"]).alignment = cell_align
ws.cell(row=r_up, column=AH, value=z["台"]).alignment = cell_align
ws.cell(row=r_up, column=AI, value=z["外籍"]).alignment = cell_align
ws.cell(row=r_up, column=AJ, value=z["其他"]).alignment = cell_align
# 大班户籍明细,AK小计跳过
d = stu["大班"]
ws.cell(row=r_up, column=AL, value=d["本区"]).alignment = cell_align
ws.cell(row=r_up, column=AM, value=d["外区"]).alignment = cell_align
ws.cell(row=r_up, column=AN, value=d["外省"]).alignment = cell_align
ws.cell(row=r_up, column=AO, value=d["港"]).alignment = cell_align
ws.cell(row=r_up, column=AP, value=d["澳"]).alignment = cell_align
ws.cell(row=r_up, column=AQ, value=d["台"]).alignment = cell_align
ws.cell(row=r_up, column=AR, value=d["外籍"]).alignment = cell_align
ws.cell(row=r_up, column=AS, value=d["其他"]).alignment = cell_align
# 非户籍明细表:只填大班/中班/小班明细,每组首列小计不覆盖
# type1 C小计跳过 D=大班 E=中班 F=小班 G/H固定0
ws.cell(row=r_det, column=D, value=nl["type1"]["大班"]).alignment = cell_align
ws.cell(row=r_det, column=E, value=nl["type1"]["中班"]).alignment = cell_align
ws.cell(row=r_det, column=F, value=nl["type1"]["小班"]).alignment = cell_align
ws.cell(row=r_det, column=G, value=0).alignment = cell_align
ws.cell(row=r_det, column=H, value=0).alignment = cell_align
# type2 I小计跳过 J=大班 K=中班 L=小班
ws.cell(row=r_det, column=J, value=nl["type2"]["大班"]).alignment = cell_align
ws.cell(row=r_det, column=K, value=nl["type2"]["中班"]).alignment = cell_align
ws.cell(row=r_det, column=L, value=nl["type2"]["小班"]).alignment = cell_align
ws.cell(row=r_det, column=M, value=0).alignment = cell_align
ws.cell(row=r_det, column=N, value=0).alignment = cell_align
# type3 O小计跳过 P=大班 Q=中班 R=小班
ws.cell(row=r_det, column=P, value=nl["type3"]["大班"]).alignment = cell_align
ws.cell(row=r_det, column=Q, value=nl["type3"]["中班"]).alignment = cell_align
ws.cell(row=r_det, column=R, value=nl["type3"]["小班"]).alignment = cell_align
ws.cell(row=r_det, column=S, value=0).alignment = cell_align
ws.cell(row=r_det, column=T, value=0).alignment = cell_align
# type4 U小计跳过 V=大班 W=中班 X=小班
ws.cell(row=r_det, column=V, value=nl["type4"]["大班"]).alignment = cell_align
ws.cell(row=r_det, column=W, value=nl["type4"]["中班"]).alignment = cell_align
ws.cell(row=r_det, column=X, value=nl["type4"]["小班"]).alignment = cell_align
ws.cell(row=r_det, column=Y, value=0).alignment = cell_align
ws.cell(row=r_det, column=Z, value=0).alignment = cell_align
# type5 AA小计跳过 AB=大班 AC=中班 AD=小班
ws.cell(row=r_det, column=AB, value=nl["type5"]["大班"]).alignment = cell_align
ws.cell(row=r_det, column=AC, value=nl["type5"]["中班"]).alignment = cell_align
ws.cell(row=r_det, column=AD, value=nl["type5"]["小班"]).alignment = cell_align
ws.cell(row=r_det, column=AE, value=0).alignment = cell_align
ws.cell(row=r_det, column=AF, value=0).alignment = cell_align
print(f" ✅ {park} 明细数据写入完成(保留模板公式)")
# ===================== 优抚子女明细写入:仅填托/小/中/大,小计列完全不动 =====================
print("\n===== 写入军人武警优抚子女明细(保留模板公式) =====")
for park_name, write_r in park_write_row.items():
data = army_warrior_total[park_name]
# 1. 军人现役 符合:C小计不写,只填D托 E小 F中 G大
cols = col_rule["军人现役_符合"]
ws.cell(write_r, cols[1], value=data["军人现役"]["托班"]).alignment = cell_align
ws.cell(write_r, cols[2], value=data["军人现役"]["小班"]).alignment = cell_align
ws.cell(write_r, cols[3], value=data["军人现役"]["中班"]).alignment = cell_align
ws.cell(write_r, cols[4], value=data["军人现役"]["大班"]).alignment = cell_align
# 2. 军人退役 符合:M小计不写
cols = col_rule["军人退役_符合"]
ws.cell(write_r, cols[1], value=data["军人退役"]["托班"]).alignment = cell_align
ws.cell(write_r, cols[2], value=data["军人退役"]["小班"]).alignment = cell_align
ws.cell(write_r, cols[3], value=data["军人退役"]["中班"]).alignment = cell_align
ws.cell(write_r, cols[4], value=data["军人退役"]["大班"]).alignment = cell_align
# 3. 武警现役 符合:X小计不写
cols = col_rule["武警现役_符合"]
ws.cell(write_r, cols[1], value=data["武警现役"]["托班"]).alignment = cell_align
ws.cell(write_r, cols[2], value=data["武警现役"]["小班"]).alignment = cell_align
ws.cell(write_r, cols[3], value=data["武警现役"]["中班"]).alignment = cell_align
ws.cell(write_r, cols[4], value=data["武警现役"]["大班"]).alignment = cell_align
# 4. 武警退役 符合:AH小计不写
cols = col_rule["武警退役_符合"]
ws.cell(write_r, cols[1], value=data["武警退役"]["托班"]).alignment = cell_align
ws.cell(write_r, cols[2], value=data["武警退役"]["小班"]).alignment = cell_align
ws.cell(write_r, cols[3], value=data["武警退役"]["中班"]).alignment = cell_align
ws.cell(write_r, cols[4], value=data["武警退役"]["大班"]).alignment = cell_align
print("✅ 优抚明细写入完成,所有小计/合计单元格未覆盖,保留Excel原有公式")
# 文件保存:另存新文件,模板原文件完全不修改
wb.save(out_excel)
wb.close()
# 数据源文件仅关闭不重写,避免破坏原分析表
wb_data.close()
print(f"\n🎉 全部程序执行完毕!输出文件路径:\n{out_excel}")




是否要补全0
我之前做托幼人数上报,系统里必须把所有数据都填写,空数据就补0
但是这次要不要补0呢



修改思路
1、我的园区是按 一分园、二分园,根据园所编号 是一分园01,总园02,二分园03。

2、文件名明确要求,不要补0


python
'''
第3步
把分析出来的数量写入指定的模版里(保留原模版的公式,小计、总计,都不要填入数字)
不要补0
豆包 阿夏
20260812
'''
from openpyxl import load_workbook
from openpyxl.styles import Alignment
# ===================== 路径配置 =====================
folder = r'C:\Users\mhjg2\Desktop\20260812幼儿园户籍信息统计'
data_excel = f"{folder}\\分析.xlsx"
template_excel = f"{folder}\\1 2026学年闵行区幼儿园概况表(总分园填在一张表上)(1).xlsx"
out_excel = f"{folder}\\统计2.xlsx"
# ===================== 园区班级映射规则 =====================
park_class_rule = {
"总园": ["中1", "中2", "中3", "中4", "中5", "中6", "大1", "大2", "大3", "大4", "大5"],
"一分园": ["托1", "托2", "小4", "小5"],
"二分园": ["托3", "小1", "小2", "小3"]
}
class_to_park = {}
for park, cls_list in park_class_rule.items():
for cls in cls_list:
class_to_park[cls] = park
# 班级转年级工具函数
def class_to_grade(class_name: str) -> str:
c = class_name.strip()
if "托" in c:
return "托班"
elif "小" in c:
return "小班"
elif "中" in c:
return "中班"
elif "大" in c:
return "大班"
return None
# ===================== 优抚表配置(固定写入40/41/42行) =====================
park_write_row = {
"总园": 40,
"一分园": 41,
"二分园": 42
}
# 列组规则:(小计列, 托班列, 小班列, 中班列, 大班列)
col_rule = {
"军人现役_符合": (3, 4, 5, 6, 7), # C小计 D托 E小 F中 G大
"军人退役_符合": (13, 14, 15, 16, 17), # M小计 N托 O小 P中 Q大
"武警现役_符合": (24, 25, 26, 27, 28), # X小计 Y托 Z小 AA中 AB大
"武警退役_符合": (34, 35, 36, 37, 38) # AH小计 AI托 AJ小 AK中 AL大
}
# 优抚数据存储容器
army_warrior_total = {
"总园": {
"军人现役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0},
"军人退役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0},
"武警现役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0},
"武警退役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0}
},
"一分园": {
"军人现役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0},
"军人退役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0},
"武警现役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0},
"武警退役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0}
},
"二分园": {
"军人现役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0},
"军人退役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0},
"武警现役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0},
"武警退役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0}
}
}
# ===================== 读取数据源【分析.xlsx】提取优抚数据 =====================
wb_data = load_workbook(data_excel)
ws_data = wb_data["园区班级分层统计"]
rows_data = list(ws_data.iter_rows(values_only=True))
header = rows_data[0]
data_list = rows_data[1:]
print("===== 所有列名 =====")
for i, h in enumerate(header):
print(f"列{i}: {h}")
# 拆分三类数据
df_hukou = []
df_nonlocal = []
df_army_warrior = []
for row in data_list:
row_dict = dict(zip(header, row))
col_name = row_dict.get("列名称")
if col_name == "户籍所在地":
df_hukou.append(row_dict)
elif col_name == "非户籍幼儿五类明细选择":
df_nonlocal.append(row_dict)
elif col_name in ("军人子女类型", "武警消防子女类型"):
df_army_warrior.append(row_dict)
print(f"\n读取户籍记录总数:{len(df_hukou)}")
print(f"读取非户籍五类记录总数:{len(df_nonlocal)}")
print(f"读取军人/武警优抚记录总数:{len(df_army_warrior)}")
# ===================== 统计优抚子女数据(从分析表汇总) =====================
print("\n===== 统计军人武警优抚子女数据 =====")
for row_dict in df_army_warrior:
park = str(row_dict["园区"]).strip()
cls_name = str(row_dict["班级"]).strip()
col_type = row_dict["列名称"]
content = str(row_dict["内容文本"]).strip()
cnt = int(row_dict["本班出现次数"])
grade = class_to_grade(cls_name)
if park not in army_warrior_total or grade is None or cnt <= 0:
continue
target_key = None
if col_type == "军人子女类型":
if "现役" in content:
target_key = "军人现役"
elif "退役" in content:
target_key = "军人退役"
elif col_type == "武警消防子女类型":
if "现役" in content:
target_key = "武警现役"
elif "退役" in content:
target_key = "武警退役"
if target_key:
army_warrior_total[park][target_key][grade] += cnt
# 控制台打印核对数据
for park in ["总园", "一分园", "二分园"]:
print(f"\n【{park}】优抚汇总:")
for k, v in army_warrior_total[park].items():
total = sum(v.values())
print(f" {k} 合计{total} → 托{v['托班']} 小{v['小班']} 中{v['中班']} 大{v['大班']}")
# ===================== 1、主表托小中大户籍容器 =====================
parks = ["总园", "一分园", "二分园"]
park_student_data = {
"总园": {
"托班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0},
"小班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0},
"中班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0},
"大班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0}
},
"一分园": {
"托班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0},
"小班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0},
"中班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0},
"大班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0}
},
"二分园": {
"托班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0},
"小班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0},
"中班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0},
"大班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0}
}
}
# ===================== 2、开班数量统计 =====================
all_class_raw = set()
for r in data_list:
cls = dict(zip(header, r)).get("班级")
if cls:
all_class_raw.add(str(cls))
short_class_set = set()
for c in all_class_raw:
short_c = str(c).replace("班", "").strip()
short_class_set.add(short_c)
class_count = {
"总园": {"托班": 0, "小班": 0, "中班": 0, "大班": 0, "混龄班": 0, "特教班": 0},
"一分园": {"托班": 0, "小班": 0, "中班": 0, "大班": 0, "混龄班": 0, "特教班": 0},
"二分园": {"托班": 0, "小班": 0, "中班": 0, "大班": 0, "混龄班": 0, "特教班": 0}
}
for sc in short_class_set:
if sc not in class_to_park:
continue
p = class_to_park[sc]
if "托" in sc:
class_count[p]["托班"] += 1
elif "小" in sc:
class_count[p]["小班"] += 1
elif "中" in sc:
class_count[p]["中班"] += 1
elif "大" in sc:
class_count[p]["大班"] += 1
elif "混" in sc:
class_count[p]["混龄班"] += 1
elif "特" in sc:
class_count[p]["特教班"] += 1
print("\n===== 班级数量 =====")
for park in parks:
print(f" {park}: {class_count[park]}")
# ===================== 3、统计户籍数据 =====================
print("\n===== 统计户籍数据 =====")
for row_dict in df_hukou:
park = str(row_dict["园区"]).strip()
class_name = str(row_dict["班级"]).strip()
content = str(row_dict["内容文本"]).strip()
num = int(row_dict["本班出现次数"])
grade_main = None
if "托" in class_name:
grade_main = "托班"
elif "小" in class_name:
grade_main = "小班"
elif "中" in class_name:
grade_main = "中班"
elif "大" in class_name:
grade_main = "大班"
elif "混" in class_name:
grade_main = "混龄班"
elif "特" in class_name:
grade_main = "特教班"
if grade_main is None or park not in park_student_data:
continue
if "本市本区" in content:
park_student_data[park][grade_main]["本区"] += num
elif "本市外区" in content:
park_student_data[park][grade_main]["外区"] += num
elif "外省" in content:
park_student_data[park][grade_main]["外省"] += num
elif "港" in content or "香港" in content:
park_student_data[park][grade_main]["港"] += num
elif "澳" in content or "澳门" in content:
park_student_data[park][grade_main]["澳"] += num
elif "台" in content or "台湾" in content:
park_student_data[park][grade_main]["台"] += num
elif "外籍" in content:
park_student_data[park][grade_main]["外籍"] += num
else:
park_student_data[park][grade_main]["其他"] += num
print("✅ 户籍数据统计完成")
# ===================== 4、统计非本市户籍五类数据 =====================
print("\n===== 统计非户籍五类数据 =====")
class_grade_map = {}
for row in data_list:
row_dict = dict(zip(header, row))
if row_dict.get("列名称") == "班级":
park = str(row_dict.get("园区") or "").strip()
class_name = str(row_dict.get("班级") or "").strip()
if park and class_name:
grade = None
if "托" in class_name:
grade = "托班"
elif "小" in class_name:
grade = "小班"
elif "中" in class_name:
grade = "中班"
elif "大" in class_name:
grade = "大班"
if grade:
class_grade_map[(park, class_name)] = grade
non_local_data = {}
for park in parks:
non_local_data[park] = {
"type1": {"大班": 0, "中班": 0, "小班": 0},
"type2": {"大班": 0, "中班": 0, "小班": 0},
"type3": {"大班": 0, "中班": 0, "小班": 0},
"type4": {"大班": 0, "中班": 0, "小班": 0},
"type5": {"大班": 0, "中班": 0, "小班": 0}
}
for row_dict in df_nonlocal:
park = str(row_dict["园区"]).strip()
class_name = str(row_dict["班级"]).strip()
content = str(row_dict["内容文本"]).strip()
num = int(row_dict["本班出现次数"])
if not content or num == 0:
continue
if park not in parks:
continue
grade = class_grade_map.get((park, class_name))
if not grade:
continue
if grade not in ["大班", "中班", "小班"]:
continue
match_type = None
if "120" in content:
match_type = "type1"
elif "房产" in content and "积分不满" in content:
match_type = "type2"
elif "满6个月" in content and "不满" not in content:
match_type = "type3"
elif "不满6个月" in content:
match_type = "type4"
elif "无居住证" in content:
match_type = "type5"
if match_type:
non_local_data[park][match_type][grade] += num
type_names = {"type1": "积分120", "type2": "仅有房产", "type3": "社保满6", "type4": "社保不满6", "type5": "无居住证"}
for park in parks:
print(f"\n【{park}】")
has_data = False
for k, v in non_local_data[park].items():
total = sum(v.values())
if total > 0:
has_data = True
print(f" {type_names.get(k)}: 合计{total}, 大班={v['大班']}, 中班={v['中班']}, 小班={v['小班']}")
if not has_data:
print(" 无数据")
# ===================== 写入Excel基础数据(0值不写入,保留模板空白,不碰小计公式) =====================
wb = load_workbook(template_excel)
ws = wb.active
cell_align = Alignment(horizontal="center", vertical="center", text_rotation=0)
row_upper = {"总园": 7, "一分园": 8, "二分园": 9}
row_detail = {"总园": 15, "一分园": 16, "二分园": 17}
# 列常量
B, C, D, E, F, G, H = 2, 3, 4, 5, 6, 7, 8
I, J, K, L, M, N = 9, 10, 11, 12, 13, 14
O, P, Q, R, S, T = 15, 16, 17, 18, 19, 20
U, V, W, X, Y, Z = 21, 22, 23, 24, 25, 26
AA, AB, AC, AD, AE, AF = 27, 28, 29, 30, 31, 32
AG, AH, AI, AJ, AK, AL, AM, AN, AO, AP, AQ, AR, AS, AT, AU = 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47
print("\n===== 开始写入Excel明细数据(0值不填充,保留原有公式) =====")
for park in parks:
r_up = row_upper[park]
r_det = row_detail[park]
cnt = class_count[park]
stu = park_student_data[park]
nl = non_local_data[park]
# 开班明细:数值>0才写入
if cnt["托班"] > 0:
ws.cell(row=r_up, column=C, value=cnt["托班"]).alignment = cell_align
if cnt["小班"] > 0:
ws.cell(row=r_up, column=D, value=cnt["小班"]).alignment = cell_align
if cnt["中班"] > 0:
ws.cell(row=r_up, column=E, value=cnt["中班"]).alignment = cell_align
if cnt["大班"] > 0:
ws.cell(row=r_up, column=F, value=cnt["大班"]).alignment = cell_align
if cnt["混龄班"] > 0:
ws.cell(row=r_up, column=G, value=cnt["混龄班"]).alignment = cell_align
ws.cell(row=r_up, column=AT, value=cnt["混龄班"]).alignment = cell_align
if cnt["特教班"] > 0:
ws.cell(row=r_up, column=H, value=cnt["特教班"]).alignment = cell_align
ws.cell(row=r_up, column=AU, value=cnt["特教班"]).alignment = cell_align
# 托班户籍明细
t = stu["托班"]
if t["本区"] > 0:
ws.cell(row=r_up, column=K, value=t["本区"]).alignment = cell_align
if t["外区"] > 0:
ws.cell(row=r_up, column=L, value=t["外区"]).alignment = cell_align
if t["外省"] > 0:
ws.cell(row=r_up, column=M, value=t["外省"]).alignment = cell_align
if t["港"] > 0:
ws.cell(row=r_up, column=N, value=t["港"]).alignment = cell_align
if t["澳"] > 0:
ws.cell(row=r_up, column=O, value=t["澳"]).alignment = cell_align
if t["台"] > 0:
ws.cell(row=r_up, column=P, value=t["台"]).alignment = cell_align
if t["外籍"] > 0:
ws.cell(row=r_up, column=Q, value=t["外籍"]).alignment = cell_align
if t["其他"] > 0:
ws.cell(row=r_up, column=R, value=t["其他"]).alignment = cell_align
# 小班户籍明细
x = stu["小班"]
if x["本区"] > 0:
ws.cell(row=r_up, column=T, value=x["本区"]).alignment = cell_align
if x["外区"] > 0:
ws.cell(row=r_up, column=U, value=x["外区"]).alignment = cell_align
if x["外省"] > 0:
ws.cell(row=r_up, column=V, value=x["外省"]).alignment = cell_align
if x["港"] > 0:
ws.cell(row=r_up, column=W, value=x["港"]).alignment = cell_align
if x["澳"] > 0:
ws.cell(row=r_up, column=X, value=x["澳"]).alignment = cell_align
if x["台"] > 0:
ws.cell(row=r_up, column=Y, value=x["台"]).alignment = cell_align
if x["外籍"] > 0:
ws.cell(row=r_up, column=Z, value=x["外籍"]).alignment = cell_align
if x["其他"] > 0:
ws.cell(row=r_up, column=AA, value=x["其他"]).alignment = cell_align
# 中班户籍明细
z = stu["中班"]
if z["本区"] > 0:
ws.cell(row=r_up, column=AC, value=z["本区"]).alignment = cell_align
if z["外区"] > 0:
ws.cell(row=r_up, column=AD, value=z["外区"]).alignment = cell_align
if z["外省"] > 0:
ws.cell(row=r_up, column=AE, value=z["外省"]).alignment = cell_align
if z["港"] > 0:
ws.cell(row=r_up, column=AF, value=z["港"]).alignment = cell_align
if z["澳"] > 0:
ws.cell(row=r_up, column=AG, value=z["澳"]).alignment = cell_align
if z["台"] > 0:
ws.cell(row=r_up, column=AH, value=z["台"]).alignment = cell_align
if z["外籍"] > 0:
ws.cell(row=r_up, column=AI, value=z["外籍"]).alignment = cell_align
if z["其他"] > 0:
ws.cell(row=r_up, column=AJ, value=z["其他"]).alignment = cell_align
# 大班户籍明细
d = stu["大班"]
if d["本区"] > 0:
ws.cell(row=r_up, column=AL, value=d["本区"]).alignment = cell_align
if d["外区"] > 0:
ws.cell(row=r_up, column=AM, value=d["外区"]).alignment = cell_align
if d["外省"] > 0:
ws.cell(row=r_up, column=AN, value=d["外省"]).alignment = cell_align
if d["港"] > 0:
ws.cell(row=r_up, column=AO, value=d["港"]).alignment = cell_align
if d["澳"] > 0:
ws.cell(row=r_up, column=AP, value=d["澳"]).alignment = cell_align
if d["台"] > 0:
ws.cell(row=r_up, column=AQ, value=d["台"]).alignment = cell_align
if d["外籍"] > 0:
ws.cell(row=r_up, column=AR, value=d["外籍"]).alignment = cell_align
if d["其他"] > 0:
ws.cell(row=r_up, column=AS, value=d["其他"]).alignment = cell_align
# 非户籍五类明细,移除所有填0代码,仅数值>0写入
# type1
if nl["type1"]["大班"] > 0:
ws.cell(row=r_det, column=D, value=nl["type1"]["大班"]).alignment = cell_align
if nl["type1"]["中班"] > 0:
ws.cell(row=r_det, column=E, value=nl["type1"]["中班"]).alignment = cell_align
if nl["type1"]["小班"] > 0:
ws.cell(row=r_det, column=F, value=nl["type1"]["小班"]).alignment = cell_align
# type2
if nl["type2"]["大班"] > 0:
ws.cell(row=r_det, column=J, value=nl["type2"]["大班"]).alignment = cell_align
if nl["type2"]["中班"] > 0:
ws.cell(row=r_det, column=K, value=nl["type2"]["中班"]).alignment = cell_align
if nl["type2"]["小班"] > 0:
ws.cell(row=r_det, column=L, value=nl["type2"]["小班"]).alignment = cell_align
# type3
if nl["type3"]["大班"] > 0:
ws.cell(row=r_det, column=P, value=nl["type3"]["大班"]).alignment = cell_align
if nl["type3"]["中班"] > 0:
ws.cell(row=r_det, column=Q, value=nl["type3"]["中班"]).alignment = cell_align
if nl["type3"]["小班"] > 0:
ws.cell(row=r_det, column=R, value=nl["type3"]["小班"]).alignment = cell_align
# type4
if nl["type4"]["大班"] > 0:
ws.cell(row=r_det, column=V, value=nl["type4"]["大班"]).alignment = cell_align
if nl["type4"]["中班"] > 0:
ws.cell(row=r_det, column=W, value=nl["type4"]["中班"]).alignment = cell_align
if nl["type4"]["小班"] > 0:
ws.cell(row=r_det, column=X, value=nl["type4"]["小班"]).alignment = cell_align
# type5
if nl["type5"]["大班"] > 0:
ws.cell(row=r_det, column=AB, value=nl["type5"]["大班"]).alignment = cell_align
if nl["type5"]["中班"] > 0:
ws.cell(row=r_det, column=AC, value=nl["type5"]["中班"]).alignment = cell_align
if nl["type5"]["小班"] > 0:
ws.cell(row=r_det, column=AD, value=nl["type5"]["小班"]).alignment = cell_align
print(f" ✅ {park} 明细数据写入完成(0值不填充,保留模板公式)")
# ===================== 优抚子女明细写入:0值跳过,不填0、不碰小计列 =====================
print("\n===== 写入军人武警优抚子女明细(0值不填充) =====")
for park_name, write_r in park_write_row.items():
data = army_warrior_total[park_name]
# 军人现役
cols = col_rule["军人现役_符合"]
if data["军人现役"]["托班"] > 0:
ws.cell(write_r, cols[1], value=data["军人现役"]["托班"]).alignment = cell_align
if data["军人现役"]["小班"] > 0:
ws.cell(write_r, cols[2], value=data["军人现役"]["小班"]).alignment = cell_align
if data["军人现役"]["中班"] > 0:
ws.cell(write_r, cols[3], value=data["军人现役"]["中班"]).alignment = cell_align
if data["军人现役"]["大班"] > 0:
ws.cell(write_r, cols[4], value=data["军人现役"]["大班"]).alignment = cell_align
# 军人退役
cols = col_rule["军人退役_符合"]
if data["军人退役"]["托班"] > 0:
ws.cell(write_r, cols[1], value=data["军人退役"]["托班"]).alignment = cell_align
if data["军人退役"]["小班"] > 0:
ws.cell(write_r, cols[2], value=data["军人退役"]["小班"]).alignment = cell_align
if data["军人退役"]["中班"] > 0:
ws.cell(write_r, cols[3], value=data["军人退役"]["中班"]).alignment = cell_align
if data["军人退役"]["大班"] > 0:
ws.cell(write_r, cols[4], value=data["军人退役"]["大班"]).alignment = cell_align
# 武警现役
cols = col_rule["武警现役_符合"]
if data["武警现役"]["托班"] > 0:
ws.cell(write_r, cols[1], value=data["武警现役"]["托班"]).alignment = cell_align
if data["武警现役"]["小班"] > 0:
ws.cell(write_r, cols[2], value=data["武警现役"]["小班"]).alignment = cell_align
if data["武警现役"]["中班"] > 0:
ws.cell(write_r, cols[3], value=data["武警现役"]["中班"]).alignment = cell_align
if data["武警现役"]["大班"] > 0:
ws.cell(write_r, cols[4], value=data["武警现役"]["大班"]).alignment = cell_align
# 武警退役
cols = col_rule["武警退役_符合"]
if data["武警退役"]["托班"] > 0:
ws.cell(write_r, cols[1], value=data["武警退役"]["托班"]).alignment = cell_align
if data["武警退役"]["小班"] > 0:
ws.cell(write_r, cols[2], value=data["武警退役"]["小班"]).alignment = cell_align
if data["武警退役"]["中班"] > 0:
ws.cell(write_r, cols[3], value=data["武警退役"]["中班"]).alignment = cell_align
if data["武警退役"]["大班"] > 0:
ws.cell(write_r, cols[4], value=data["武警退役"]["大班"]).alignment = cell_align
print("✅ 优抚明细写入完成,无数据单元格保持空白,所有小计/合计公式完整保留")
# 保存输出
wb.save(out_excel)
wb.close()
wb_data.close()
print(f"\n🎉 全部程序执行完毕!输出文件路径:\n{out_excel}")




对比图

无0效果图更干净

明天问问领导,一分园和二分园的排序方式,
如果总园02默认第一个,那么分园按序排列,都是一分园(一 01)在前,二分园(二 03)在后。
需要要完全按照编号,就是一分园01、总园02、二分园03,参数写入位置又要重新调整了。
特别说明:
必须把班级改成统一样式,否则,程序会生成很多"未知园区"

不仅有填错年级(中1班升班为大1班,家长还不熟新的年级,默认写中1),还有填错班级数字的(中2班),

所以一定要让班主任用"预设名单",确保每个人都填写。

又来了一个班,继续三次批量

python
'''
第3步
把分析出来的数量写入指定的模版里(保留原模版的公式,小计、总计,都不要填入数字)
不要补0
豆包 阿夏
20260812
'''
from openpyxl import load_workbook
from openpyxl.styles import Alignment
# ===================== 路径配置 =====================
folder = r'C:\Users\mhjg2\Desktop\20260812幼儿园户籍信息统计'
data_excel = f"{folder}\\分析.xlsx"
template_excel = f"{folder}\\1 2026学年闵行区幼儿园概况表(总分园填在一张表上)(1).xlsx"
out_excel = f"{folder}\\2026学年闵行区幼儿园概况表(XXXX总分园).xlsx"
# ===================== 园区班级映射规则 =====================
park_class_rule = {
"总园": ["中1", "中2", "中3", "中4", "中5", "中6", "大1", "大2", "大3", "大4", "大5"],
"一分园": ["托1", "托2", "小4", "小5"],
"二分园": ["托3", "小1", "小2", "小3"]
}
class_to_park = {}
for park, cls_list in park_class_rule.items():
for cls in cls_list:
class_to_park[cls] = park
# 班级转年级工具函数
def class_to_grade(class_name: str) -> str:
c = class_name.strip()
if "托" in c:
return "托班"
elif "小" in c:
return "小班"
elif "中" in c:
return "中班"
elif "大" in c:
return "大班"
return None
# ===================== 优抚表配置(固定写入40/41/42行) =====================
park_write_row = {
"总园": 40,
"一分园": 41,
"二分园": 42
}
# 列组规则:(小计列, 托班列, 小班列, 中班列, 大班列)
col_rule = {
"军人现役_符合": (3, 4, 5, 6, 7), # C小计 D托 E小 F中 G大
"军人退役_符合": (13, 14, 15, 16, 17), # M小计 N托 O小 P中 Q大
"武警现役_符合": (24, 25, 26, 27, 28), # X小计 Y托 Z小 AA中 AB大
"武警退役_符合": (34, 35, 36, 37, 38) # AH小计 AI托 AJ小 AK中 AL大
}
# 优抚数据存储容器
army_warrior_total = {
"总园": {
"军人现役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0},
"军人退役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0},
"武警现役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0},
"武警退役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0}
},
"一分园": {
"军人现役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0},
"军人退役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0},
"武警现役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0},
"武警退役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0}
},
"二分园": {
"军人现役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0},
"军人退役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0},
"武警现役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0},
"武警退役": {"托班": 0, "小班": 0, "中班": 0, "大班": 0}
}
}
# ===================== 读取数据源【分析.xlsx】提取优抚数据 =====================
wb_data = load_workbook(data_excel)
ws_data = wb_data["园区班级分层统计"]
rows_data = list(ws_data.iter_rows(values_only=True))
header = rows_data[0]
data_list = rows_data[1:]
print("===== 所有列名 =====")
for i, h in enumerate(header):
print(f"列{i}: {h}")
# 拆分三类数据
df_hukou = []
df_nonlocal = []
df_army_warrior = []
for row in data_list:
row_dict = dict(zip(header, row))
col_name = row_dict.get("列名称")
if col_name == "户籍所在地":
df_hukou.append(row_dict)
elif col_name == "非户籍幼儿五类明细选择":
df_nonlocal.append(row_dict)
elif col_name in ("军人子女类型", "武警消防子女类型"):
df_army_warrior.append(row_dict)
print(f"\n读取户籍记录总数:{len(df_hukou)}")
print(f"读取非户籍五类记录总数:{len(df_nonlocal)}")
print(f"读取军人/武警优抚记录总数:{len(df_army_warrior)}")
# ===================== 统计优抚子女数据(从分析表汇总) =====================
print("\n===== 统计军人武警优抚子女数据 =====")
for row_dict in df_army_warrior:
park = str(row_dict["园区"]).strip()
cls_name = str(row_dict["班级"]).strip()
col_type = row_dict["列名称"]
content = str(row_dict["内容文本"]).strip()
cnt = int(row_dict["本班出现次数"])
grade = class_to_grade(cls_name)
if park not in army_warrior_total or grade is None or cnt <= 0:
continue
target_key = None
if col_type == "军人子女类型":
if "现役" in content:
target_key = "军人现役"
elif "退役" in content:
target_key = "军人退役"
elif col_type == "武警消防子女类型":
if "现役" in content:
target_key = "武警现役"
elif "退役" in content:
target_key = "武警退役"
if target_key:
army_warrior_total[park][target_key][grade] += cnt
# 控制台打印核对数据
for park in ["总园", "一分园", "二分园"]:
print(f"\n【{park}】优抚汇总:")
for k, v in army_warrior_total[park].items():
total = sum(v.values())
print(f" {k} 合计{total} → 托{v['托班']} 小{v['小班']} 中{v['中班']} 大{v['大班']}")
# ===================== 1、主表托小中大户籍容器 =====================
parks = ["总园", "一分园", "二分园"]
park_student_data = {
"总园": {
"托班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0},
"小班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0},
"中班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0},
"大班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0}
},
"一分园": {
"托班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0},
"小班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0},
"中班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0},
"大班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0}
},
"二分园": {
"托班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0},
"小班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0},
"中班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0},
"大班": {"本区": 0, "外区": 0, "外省": 0, "港": 0, "澳": 0, "台": 0, "外籍": 0, "其他": 0}
}
}
# ===================== 2、开班数量统计 =====================
all_class_raw = set()
for r in data_list:
cls = dict(zip(header, r)).get("班级")
if cls:
all_class_raw.add(str(cls))
short_class_set = set()
for c in all_class_raw:
short_c = str(c).replace("班", "").strip()
short_class_set.add(short_c)
class_count = {
"总园": {"托班": 0, "小班": 0, "中班": 0, "大班": 0, "混龄班": 0, "特教班": 0},
"一分园": {"托班": 0, "小班": 0, "中班": 0, "大班": 0, "混龄班": 0, "特教班": 0},
"二分园": {"托班": 0, "小班": 0, "中班": 0, "大班": 0, "混龄班": 0, "特教班": 0}
}
for sc in short_class_set:
if sc not in class_to_park:
continue
p = class_to_park[sc]
if "托" in sc:
class_count[p]["托班"] += 1
elif "小" in sc:
class_count[p]["小班"] += 1
elif "中" in sc:
class_count[p]["中班"] += 1
elif "大" in sc:
class_count[p]["大班"] += 1
elif "混" in sc:
class_count[p]["混龄班"] += 1
elif "特" in sc:
class_count[p]["特教班"] += 1
print("\n===== 班级数量 =====")
for park in parks:
print(f" {park}: {class_count[park]}")
# ===================== 3、统计户籍数据 =====================
print("\n===== 统计户籍数据 =====")
for row_dict in df_hukou:
park = str(row_dict["园区"]).strip()
class_name = str(row_dict["班级"]).strip()
content = str(row_dict["内容文本"]).strip()
num = int(row_dict["本班出现次数"])
grade_main = None
if "托" in class_name:
grade_main = "托班"
elif "小" in class_name:
grade_main = "小班"
elif "中" in class_name:
grade_main = "中班"
elif "大" in class_name:
grade_main = "大班"
elif "混" in class_name:
grade_main = "混龄班"
elif "特" in class_name:
grade_main = "特教班"
if grade_main is None or park not in park_student_data:
continue
if "本市本区" in content:
park_student_data[park][grade_main]["本区"] += num
elif "本市外区" in content:
park_student_data[park][grade_main]["外区"] += num
elif "外省" in content:
park_student_data[park][grade_main]["外省"] += num
elif "港" in content or "香港" in content:
park_student_data[park][grade_main]["港"] += num
elif "澳" in content or "澳门" in content:
park_student_data[park][grade_main]["澳"] += num
elif "台" in content or "台湾" in content:
park_student_data[park][grade_main]["台"] += num
elif "外籍" in content:
park_student_data[park][grade_main]["外籍"] += num
else:
park_student_data[park][grade_main]["其他"] += num
print("✅ 户籍数据统计完成")
# ===================== 4、统计非本市户籍五类数据 =====================
print("\n===== 统计非户籍五类数据 =====")
class_grade_map = {}
for row in data_list:
row_dict = dict(zip(header, row))
if row_dict.get("列名称") == "班级":
park = str(row_dict.get("园区") or "").strip()
class_name = str(row_dict.get("班级") or "").strip()
if park and class_name:
grade = None
if "托" in class_name:
grade = "托班"
elif "小" in class_name:
grade = "小班"
elif "中" in class_name:
grade = "中班"
elif "大" in class_name:
grade = "大班"
if grade:
class_grade_map[(park, class_name)] = grade
non_local_data = {}
for park in parks:
non_local_data[park] = {
"type1": {"大班": 0, "中班": 0, "小班": 0},
"type2": {"大班": 0, "中班": 0, "小班": 0},
"type3": {"大班": 0, "中班": 0, "小班": 0},
"type4": {"大班": 0, "中班": 0, "小班": 0},
"type5": {"大班": 0, "中班": 0, "小班": 0}
}
for row_dict in df_nonlocal:
park = str(row_dict["园区"]).strip()
class_name = str(row_dict["班级"]).strip()
content = str(row_dict["内容文本"]).strip()
num = int(row_dict["本班出现次数"])
if not content or num == 0:
continue
if park not in parks:
continue
grade = class_grade_map.get((park, class_name))
if not grade:
continue
if grade not in ["大班", "中班", "小班"]:
continue
match_type = None
if "120" in content:
match_type = "type1"
elif "房产" in content and "积分不满" in content:
match_type = "type2"
elif "满6个月" in content and "不满" not in content:
match_type = "type3"
elif "不满6个月" in content:
match_type = "type4"
elif "无居住证" in content:
match_type = "type5"
if match_type:
non_local_data[park][match_type][grade] += num
type_names = {"type1": "积分120", "type2": "仅有房产", "type3": "社保满6", "type4": "社保不满6", "type5": "无居住证"}
for park in parks:
print(f"\n【{park}】")
has_data = False
for k, v in non_local_data[park].items():
total = sum(v.values())
if total > 0:
has_data = True
print(f" {type_names.get(k)}: 合计{total}, 大班={v['大班']}, 中班={v['中班']}, 小班={v['小班']}")
if not has_data:
print(" 无数据")
# ===================== 写入Excel基础数据(0值不写入,保留模板空白,不碰小计公式) =====================
wb = load_workbook(template_excel)
ws = wb.active
cell_align = Alignment(horizontal="center", vertical="center", text_rotation=0)
row_upper = {"总园": 7, "一分园": 8, "二分园": 9}
row_detail = {"总园": 15, "一分园": 16, "二分园": 17}
# 列常量
B, C, D, E, F, G, H = 2, 3, 4, 5, 6, 7, 8
I, J, K, L, M, N = 9, 10, 11, 12, 13, 14
O, P, Q, R, S, T = 15, 16, 17, 18, 19, 20
U, V, W, X, Y, Z = 21, 22, 23, 24, 25, 26
AA, AB, AC, AD, AE, AF = 27, 28, 29, 30, 31, 32
AG, AH, AI, AJ, AK, AL, AM, AN, AO, AP, AQ, AR, AS, AT, AU = 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47
print("\n===== 开始写入Excel明细数据(0值不填充,保留原有公式) =====")
for park in parks:
r_up = row_upper[park]
r_det = row_detail[park]
cnt = class_count[park]
stu = park_student_data[park]
nl = non_local_data[park]
# 开班明细:数值>0才写入
if cnt["托班"] > 0:
ws.cell(row=r_up, column=C, value=cnt["托班"]).alignment = cell_align
if cnt["小班"] > 0:
ws.cell(row=r_up, column=D, value=cnt["小班"]).alignment = cell_align
if cnt["中班"] > 0:
ws.cell(row=r_up, column=E, value=cnt["中班"]).alignment = cell_align
if cnt["大班"] > 0:
ws.cell(row=r_up, column=F, value=cnt["大班"]).alignment = cell_align
if cnt["混龄班"] > 0:
ws.cell(row=r_up, column=G, value=cnt["混龄班"]).alignment = cell_align
ws.cell(row=r_up, column=AT, value=cnt["混龄班"]).alignment = cell_align
if cnt["特教班"] > 0:
ws.cell(row=r_up, column=H, value=cnt["特教班"]).alignment = cell_align
ws.cell(row=r_up, column=AU, value=cnt["特教班"]).alignment = cell_align
# 托班户籍明细
t = stu["托班"]
if t["本区"] > 0:
ws.cell(row=r_up, column=K, value=t["本区"]).alignment = cell_align
if t["外区"] > 0:
ws.cell(row=r_up, column=L, value=t["外区"]).alignment = cell_align
if t["外省"] > 0:
ws.cell(row=r_up, column=M, value=t["外省"]).alignment = cell_align
if t["港"] > 0:
ws.cell(row=r_up, column=N, value=t["港"]).alignment = cell_align
if t["澳"] > 0:
ws.cell(row=r_up, column=O, value=t["澳"]).alignment = cell_align
if t["台"] > 0:
ws.cell(row=r_up, column=P, value=t["台"]).alignment = cell_align
if t["外籍"] > 0:
ws.cell(row=r_up, column=Q, value=t["外籍"]).alignment = cell_align
if t["其他"] > 0:
ws.cell(row=r_up, column=R, value=t["其他"]).alignment = cell_align
# 小班户籍明细
x = stu["小班"]
if x["本区"] > 0:
ws.cell(row=r_up, column=T, value=x["本区"]).alignment = cell_align
if x["外区"] > 0:
ws.cell(row=r_up, column=U, value=x["外区"]).alignment = cell_align
if x["外省"] > 0:
ws.cell(row=r_up, column=V, value=x["外省"]).alignment = cell_align
if x["港"] > 0:
ws.cell(row=r_up, column=W, value=x["港"]).alignment = cell_align
if x["澳"] > 0:
ws.cell(row=r_up, column=X, value=x["澳"]).alignment = cell_align
if x["台"] > 0:
ws.cell(row=r_up, column=Y, value=x["台"]).alignment = cell_align
if x["外籍"] > 0:
ws.cell(row=r_up, column=Z, value=x["外籍"]).alignment = cell_align
if x["其他"] > 0:
ws.cell(row=r_up, column=AA, value=x["其他"]).alignment = cell_align
# 中班户籍明细
z = stu["中班"]
if z["本区"] > 0:
ws.cell(row=r_up, column=AC, value=z["本区"]).alignment = cell_align
if z["外区"] > 0:
ws.cell(row=r_up, column=AD, value=z["外区"]).alignment = cell_align
if z["外省"] > 0:
ws.cell(row=r_up, column=AE, value=z["外省"]).alignment = cell_align
if z["港"] > 0:
ws.cell(row=r_up, column=AF, value=z["港"]).alignment = cell_align
if z["澳"] > 0:
ws.cell(row=r_up, column=AG, value=z["澳"]).alignment = cell_align
if z["台"] > 0:
ws.cell(row=r_up, column=AH, value=z["台"]).alignment = cell_align
if z["外籍"] > 0:
ws.cell(row=r_up, column=AI, value=z["外籍"]).alignment = cell_align
if z["其他"] > 0:
ws.cell(row=r_up, column=AJ, value=z["其他"]).alignment = cell_align
# 大班户籍明细
d = stu["大班"]
if d["本区"] > 0:
ws.cell(row=r_up, column=AL, value=d["本区"]).alignment = cell_align
if d["外区"] > 0:
ws.cell(row=r_up, column=AM, value=d["外区"]).alignment = cell_align
if d["外省"] > 0:
ws.cell(row=r_up, column=AN, value=d["外省"]).alignment = cell_align
if d["港"] > 0:
ws.cell(row=r_up, column=AO, value=d["港"]).alignment = cell_align
if d["澳"] > 0:
ws.cell(row=r_up, column=AP, value=d["澳"]).alignment = cell_align
if d["台"] > 0:
ws.cell(row=r_up, column=AQ, value=d["台"]).alignment = cell_align
if d["外籍"] > 0:
ws.cell(row=r_up, column=AR, value=d["外籍"]).alignment = cell_align
if d["其他"] > 0:
ws.cell(row=r_up, column=AS, value=d["其他"]).alignment = cell_align
# 非户籍五类明细,移除所有填0代码,仅数值>0写入
# type1
if nl["type1"]["大班"] > 0:
ws.cell(row=r_det, column=D, value=nl["type1"]["大班"]).alignment = cell_align
if nl["type1"]["中班"] > 0:
ws.cell(row=r_det, column=E, value=nl["type1"]["中班"]).alignment = cell_align
if nl["type1"]["小班"] > 0:
ws.cell(row=r_det, column=F, value=nl["type1"]["小班"]).alignment = cell_align
# type2
if nl["type2"]["大班"] > 0:
ws.cell(row=r_det, column=J, value=nl["type2"]["大班"]).alignment = cell_align
if nl["type2"]["中班"] > 0:
ws.cell(row=r_det, column=K, value=nl["type2"]["中班"]).alignment = cell_align
if nl["type2"]["小班"] > 0:
ws.cell(row=r_det, column=L, value=nl["type2"]["小班"]).alignment = cell_align
# type3
if nl["type3"]["大班"] > 0:
ws.cell(row=r_det, column=P, value=nl["type3"]["大班"]).alignment = cell_align
if nl["type3"]["中班"] > 0:
ws.cell(row=r_det, column=Q, value=nl["type3"]["中班"]).alignment = cell_align
if nl["type3"]["小班"] > 0:
ws.cell(row=r_det, column=R, value=nl["type3"]["小班"]).alignment = cell_align
# type4
if nl["type4"]["大班"] > 0:
ws.cell(row=r_det, column=V, value=nl["type4"]["大班"]).alignment = cell_align
if nl["type4"]["中班"] > 0:
ws.cell(row=r_det, column=W, value=nl["type4"]["中班"]).alignment = cell_align
if nl["type4"]["小班"] > 0:
ws.cell(row=r_det, column=X, value=nl["type4"]["小班"]).alignment = cell_align
# type5
if nl["type5"]["大班"] > 0:
ws.cell(row=r_det, column=AB, value=nl["type5"]["大班"]).alignment = cell_align
if nl["type5"]["中班"] > 0:
ws.cell(row=r_det, column=AC, value=nl["type5"]["中班"]).alignment = cell_align
if nl["type5"]["小班"] > 0:
ws.cell(row=r_det, column=AD, value=nl["type5"]["小班"]).alignment = cell_align
print(f" ✅ {park} 明细数据写入完成(0值不填充,保留模板公式)")
# ===================== 优抚子女明细写入:0值跳过,不填0、不碰小计列 =====================
print("\n===== 写入军人武警优抚子女明细(0值不填充) =====")
for park_name, write_r in park_write_row.items():
data = army_warrior_total[park_name]
# 军人现役
cols = col_rule["军人现役_符合"]
if data["军人现役"]["托班"] > 0:
ws.cell(write_r, cols[1], value=data["军人现役"]["托班"]).alignment = cell_align
if data["军人现役"]["小班"] > 0:
ws.cell(write_r, cols[2], value=data["军人现役"]["小班"]).alignment = cell_align
if data["军人现役"]["中班"] > 0:
ws.cell(write_r, cols[3], value=data["军人现役"]["中班"]).alignment = cell_align
if data["军人现役"]["大班"] > 0:
ws.cell(write_r, cols[4], value=data["军人现役"]["大班"]).alignment = cell_align
# 军人退役
cols = col_rule["军人退役_符合"]
if data["军人退役"]["托班"] > 0:
ws.cell(write_r, cols[1], value=data["军人退役"]["托班"]).alignment = cell_align
if data["军人退役"]["小班"] > 0:
ws.cell(write_r, cols[2], value=data["军人退役"]["小班"]).alignment = cell_align
if data["军人退役"]["中班"] > 0:
ws.cell(write_r, cols[3], value=data["军人退役"]["中班"]).alignment = cell_align
if data["军人退役"]["大班"] > 0:
ws.cell(write_r, cols[4], value=data["军人退役"]["大班"]).alignment = cell_align
# 武警现役
cols = col_rule["武警现役_符合"]
if data["武警现役"]["托班"] > 0:
ws.cell(write_r, cols[1], value=data["武警现役"]["托班"]).alignment = cell_align
if data["武警现役"]["小班"] > 0:
ws.cell(write_r, cols[2], value=data["武警现役"]["小班"]).alignment = cell_align
if data["武警现役"]["中班"] > 0:
ws.cell(write_r, cols[3], value=data["武警现役"]["中班"]).alignment = cell_align
if data["武警现役"]["大班"] > 0:
ws.cell(write_r, cols[4], value=data["武警现役"]["大班"]).alignment = cell_align
# 武警退役
cols = col_rule["武警退役_符合"]
if data["武警退役"]["托班"] > 0:
ws.cell(write_r, cols[1], value=data["武警退役"]["托班"]).alignment = cell_align
if data["武警退役"]["小班"] > 0:
ws.cell(write_r, cols[2], value=data["武警退役"]["小班"]).alignment = cell_align
if data["武警退役"]["中班"] > 0:
ws.cell(write_r, cols[3], value=data["武警退役"]["中班"]).alignment = cell_align
if data["武警退役"]["大班"] > 0:
ws.cell(write_r, cols[4], value=data["武警退役"]["大班"]).alignment = cell_align
print("✅ 优抚明细写入完成,无数据单元格保持空白,所有小计/合计公式完整保留")
# 保存输出
wb.save(out_excel)
wb.close()
wb_data.close()
print(f"\n🎉 全部程序执行完毕!输出文件路径:\n{out_excel}")
换了最终提交表的名字
:
刚才大班是62人,现在94人,

