【办公类-112-04】20260415街道学生名单基本信息模版(运用deepseek的Python编程,实现excle数据匹配提取)
·

背景需求

我没看到,很快保健老师让班主任自己填写了,私发给她

我看到以后,觉得还是用编程带入快速方便,打开表格看一下,查了查原来的py ,好像这个项目没有做过。

4月分刚插班了2位孩子,4月10日正好做了最新的园园通数据
【办公类-142-04】20260330插班生word转长表EXCLE(4)新表重制
https://mp.csdn.net/mp_blog/creation/editor/159734547【办公类-112-06】20260228园园通信息合并配学号拆班(园园通市级编号在excel中的位置调整,调整最适合列宽)
https://mp.csdn.net/mp_blog/creation/editor/159155166
把这份匹配过学号的4月园园通全园幼儿数据复制一份

两份EXCLE

附件1是有幼儿信息的,不能做为附件上传豆包,附件2里面没有真实数据,可以附件上传豆包。
我把附件1、附件2的列标题整行复制



'''
保健学生名单基本信息模板,内容提取
deepseek,阿夏
202060414
'''
import pandas as pd
import os
# 设置文件夹路径
folder_path = r"D:\test\20桌面素材\20260413保健学生名单基本信息模板"
# 附件2文件路径(假设是Excel格式)
attachment2_path = os.path.join(folder_path, "02匹配学号(分园新生).xlsx") # 请根据实际文件名修改
# 输出文件路径
output_path = os.path.join(folder_path, "学生名单基本信息模板(AAAA学校).xlsx")
# 附件1需要的字段映射(附件2字段名 -> 输出字段名)
field_mapping = {
"证件类型": "证件类型",
"证件号码": "证件号码",
"出生日期": "出生日期",
"姓名": "姓名",
"民族": "民族",
"籍贯-省份": "籍贯", # 附件1中的籍贯,可用省份或完整籍贯
"性别": "性别",
"年级": "年级", # 托大班、小班、中班、大班
"班级名称": "班级", # 如大1班
"学号": "学号",
"监护人手机": "家长手机号"
}
try:
# 读取附件2
print("正在读取附件2...")
df_attachment2 = pd.read_excel(attachment2_path)
print(f"附件2读取成功,共{len(df_attachment2)}行")
# 提取需要的字段
extracted_data = {}
for source_field, target_field in field_mapping.items():
if source_field in df_attachment2.columns:
extracted_data[target_field] = df_attachment2[source_field]
else:
print(f"警告:附件2中未找到字段 '{source_field}'")
extracted_data[target_field] = [""] * len(df_attachment2)
# 创建结果DataFrame
df_result = pd.DataFrame(extracted_data)
# 添加固定字段
df_result.insert(0, "序号", range(1, len(df_result) + 1))
df_result.insert(df_result.columns.get_loc("年级") + 1, "学习阶段(统一写幼儿园)", "幼儿园")
# 重新排列列的顺序,与附件1范例一致
column_order = [
"序号",
"证件类型",
"证件号码",
"出生日期",
"姓名",
"民族",
"籍贯",
"性别",
"学习阶段(统一写幼儿园)",
"年级",
"班级",
"学号",
"家长手机号"
]
# 确保所有列都存在
for col in column_order:
if col not in df_result.columns:
df_result[col] = ""
df_result = df_result[column_order]
# 保存结果
df_result.to_excel(output_path, index=False)
print(f"数据提取完成!已保存到: {output_path}")
print(f"共提取{len(df_result)}条记录")
except FileNotFoundError:
print(f"错误:找不到文件 {attachment2_path}")
print("请确保文件名正确(如:附件2.xlsx 或 附件2.csv)")
except Exception as e:
print(f"发生错误:{e}")

最后所有的托小中大班孩子的相关信息都正确提取了

但是我发现小1-小4、中1-中4、大1-大4都是整班排序,但后面的小5-小6、中5-中6、大5-大6是乱序排列的

我仔细研究半天,查看了“园园通整理”的代码
原来“班级排序”的范围只有各年级的1-4班,所以5-6班就乱序排列
复制并修改班级


'''
20250825_2025_学年出入所(园)儿童基本情况登记 表一空 01
1、用合并xls与班级信息表的学号匹配,按学号排队
2、按班级拆分成一个个班级,最适合列宽一行(非自动换行)
3、按指定的列名顺序重新排列列的位置
20260317
'''
import pandas as pd
import os
from openpyxl.utils import get_column_letter
from openpyxl.styles import Alignment
from openpyxl.styles import numbers
# 设置路径
path = r'D:\test\20桌面素材\20260228_2025园园通幼儿信息提取配学号拆班发班主任'
date='20260410'
# 定义目标列名顺序
target_columns = [
'学号', '班级', '姓名', '市登记编号', '性别','出生地', '证件类型', '证件号码',
'姓名拼音', '曾用名/英文名', '出生日期', '年级', '班级名称', '入园日期',
'就读方式', '国籍/地区', '健康状况', '血型', '户口性质', '非农业户口类型',
'港澳台侨外', '民族', '出生地-省份', '籍贯-省份', '是否人户一致',
'户口所在地-省份', '户口所在地-城市', '户口所在地-区县', '户口所在地-街道',
'户口所在地-居委', '户口所在地-详细地址', '现居地-省份', '现居地-城市',
'现居地-区县', '现居地-街道', '现居地-居委', '现居地邮政编码', '现居地-详细地址',
'监护人姓名', '监护人证件类型', '监护人证件号', '监护人手机', '与幼儿关系',
'是否监护人', '是否是第一监护人', '是否是军烈子女', '是否是优抚子女',
'是否是进城务工人员随迁子女', '是否是部队子女', '是否是孤儿', '是否是残疾幼儿',
'残疾幼儿类别', '更新时间', '机构所在地区', '机构ID', '机构名称', '办园点ID',
'办园点编码', '办园点名称', '班级昵称', '出生地-区县', '机构编码', '籍贯-区县',
'籍贯-城市', '幼儿ID', '创建时间', '班级ID', '版本号', '幼儿特长',
'户口所在地-居委-其他', '现居地-街道-其他', '户口所在地-街道-其他',
'现居地-居委-其他', '特异体质', '出生地-城市', '原幼儿编号', '班级排序'
]
def calculate_display_width(text):
"""
计算字符串在Excel中的显示宽度
中文字符占2个单位,英文字符和数字占1个单位
"""
if text is None or pd.isna(text):
return 0
text = str(text)
width = 0
for char in text:
# 判断是否为中文字符(包括中文标点)
if '\u4e00' <= char <= '\u9fff' or char in ',。;:“”‘’!?【】()《》':
width += 2
else:
width += 1
return width
def reorder_columns(df, target_columns):
"""
按照目标列名顺序重新排列DataFrame的列
"""
# 获取DataFrame中实际存在的列
existing_columns = []
missing_columns = []
for col in target_columns:
if col in df.columns:
existing_columns.append(col)
else:
missing_columns.append(col)
# 获取目标列中不存在的其他列(放在最后)
other_columns = [col for col in df.columns if col not in existing_columns]
if missing_columns:
print(f"警告:以下目标列在数据中不存在,将被忽略:{missing_columns}")
if other_columns:
print(f"注意:以下额外列将放在最后:{other_columns}")
# 重新排列列顺序
return df[existing_columns + other_columns]
# 1. 读取园园通信息表,将所有列作为字符串读取,保持原始格式
df_main = pd.read_excel(path + r'\02园园通全部班级班信息合并.xlsx', dtype=str)
# 2. 读取班级信息表的所有工作表,将所有列作为字符串读取
xls = pd.ExcelFile(path + r'\00班级信息表.xlsx')
sheet_names = xls.sheet_names
# 3. 合并所有班级信息表
df_list = []
for sheet in sheet_names:
df_sheet = pd.read_excel(xls, sheet_name=sheet, dtype=str) # 所有列作为字符串读取
df_sheet['班级'] = sheet # 添加班级列
df_list.append(df_sheet)
df_info = pd.concat(df_list, ignore_index=True)
# 4. 匹配学号
df_merged = pd.merge(df_main,
df_info[['班级', '姓名', '学号']],
left_on=['班级名称', '姓名'],
right_on=['班级', '姓名'],
how='left')
# 5. 移动学号列到最前面(这一步现在会被后面的重新排序列覆盖,但保留以确保学号存在)
cols = df_merged.columns.tolist()
cols = ['学号'] + [col for col in cols if col != '学号']
df_merged = df_merged[cols]
# 6. 对完整匹配结果进行排序并保存
# 学号列转换为数值类型用于排序,但保存时保持原始文本格式
df_merged['学号_排序'] = pd.to_numeric(df_merged['学号'], errors='coerce')
# 先按班级排序(托1班、托2班、小1班、小2班...)
# 创建班级排序的映射关系
class_order = {
'托1班': 1, '托2班': 2, '小1班': 3, '小2班': 4,
'小3班': 5, '小4班': 6, '小5班': 7, '小6班': 8,
'中1班': 9, '中2班': 10, '中3班': 11, '中4班': 12,
'中5班': 13, '中6班': 14, '大1班': 15, '大2班': 16,
'大3班': 17, '大4班': 18,'大5班': 19, '大6班': 20,
}
# 添加临时排序列
df_merged['班级排序'] = df_merged['班级名称'].map(class_order)
# 先按班级排序,再按学号排序
df_merged_sorted = df_merged.sort_values(by=['班级排序', '学号_排序'])
# 删除临时排序列(班级排序保留,因为它在目标列中)
df_merged_sorted = df_merged_sorted.drop(['学号_排序'], axis=1)
# 按照目标列顺序重新排列
df_merged_sorted = reorder_columns(df_merged_sorted, target_columns)
# 保存排序后的完整表格,并调整列宽
with pd.ExcelWriter(path + r'\02匹配学号(分园新生).xlsx', engine='openpyxl') as writer:
df_merged_sorted.to_excel(writer, sheet_name='匹配结果', index=False)
# 获取工作表并调整列宽
worksheet = writer.sheets['匹配结果']
# 计算每列的最大显示宽度
for column in worksheet.columns:
max_width = 0
column_letter = get_column_letter(column[0].column)
# 获取列标题和所有单元格的最大显示宽度
for cell in column:
try:
# 计算单元格内容的显示宽度
cell_width = calculate_display_width(cell.value)
if cell_width > max_width:
max_width = cell_width
except:
pass
# 设置列宽(添加一点额外空间)
# Excel列宽单位是标准字符宽度,中文字符需要额外空间
adjusted_width = max_width + 2 # 添加2个字符的边距
# 限制最小宽度为8,最大宽度为100
worksheet.column_dimensions[column_letter].width = min(max(adjusted_width, 8), 100)
# 将所有单元格设置为文本格式
for row in worksheet.iter_rows():
for cell in row:
cell.number_format = '@' # 设置文本格式
# 7. 按班级拆分并保存为单独工作簿
# 创建输出文件夹
output_folder = path + r'\04拆分班级'
if not os.path.exists(output_folder):
os.makedirs(output_folder)
# 按班级拆分
for class_name in df_merged['班级名称'].unique():
# 筛选当前班级的数据
class_df = df_merged[df_merged['班级名称'] == class_name]
# 创建临时排序列用于排序
class_df = class_df.copy() # 避免警告
class_df['学号_排序'] = pd.to_numeric(class_df['学号'], errors='coerce')
# 对每个班级内的数据按学号排序
class_df_sorted = class_df.sort_values(by='学号_排序')
# 删除临时排序列
class_df_sorted = class_df_sorted.drop('学号_排序', axis=1)
# 按照目标列顺序重新排列
class_df_sorted = reorder_columns(class_df_sorted, target_columns)
# 创建文件名(去除可能存在的非法字符)
safe_class_name = "".join([c for c in class_name if c not in r'\/:*?"<>|'])
output_path = os.path.join(output_folder, f'05_{date}_园园通幼儿全部信息_{safe_class_name}.xlsx')
# 保存为单独的工作簿,并调整列宽
with pd.ExcelWriter(output_path, engine='openpyxl') as writer:
sheet_name = f'{class_name}园园通幼儿数据'
# 工作表名称不能超过31个字符
if len(sheet_name) > 31:
sheet_name = sheet_name[:31]
class_df_sorted.to_excel(writer, sheet_name=sheet_name, index=False)
# 获取工作表并调整列宽
worksheet = writer.sheets[sheet_name]
# 计算每列的最大显示宽度
for column in worksheet.columns:
max_width = 0
column_letter = get_column_letter(column[0].column)
# 获取列标题和所有单元格的最大显示宽度
for cell in column:
try:
# 计算单元格内容的显示宽度
cell_width = calculate_display_width(cell.value)
if cell_width > max_width:
max_width = cell_width
except:
pass
# 设置列宽(根据最长字符的实际显示宽度)
adjusted_width = max_width + 2 # 添加2个字符的边距
# 限制最小宽度为8,最大宽度为100
worksheet.column_dimensions[column_letter].width = min(max(adjusted_width, 8), 100)
# 设置所有单元格为文本格式
for row in worksheet.iter_rows():
for cell in row:
cell.number_format = '@' # 设置所有单元格为文本格式
print("处理完成!")
print(f"1. 已生成完整匹配表: 02匹配学号(分园新生).xlsx(已按班级和学号排序,按指定列名顺序排列,所有单元格保持文本格式,根据实际显示宽度计算最适合列宽)")
print(f"2. 已按班级拆分保存到 {output_folder} 文件夹,每个班级内按学号排序,按指定列名顺序排列,所有单元格保持文本格式,根据实际显示宽度计算最适合列宽")
所有都按照班级排列了



但是保健老师只要2分园的,所以我还要“拆分园区”


'''
保健学生名单基本信息模板,内容提取,拆分三园区
deepseek,阿夏
202060414
'''
import pandas as pd
import os
# 设置文件夹路径
folder_path = r"D:\test\20桌面素材\20260413保健学生名单基本信息模板"
# 附件2文件路径(假设是Excel格式)
attachment2_path = os.path.join(folder_path, "02匹配学号(分园新生).xlsx") # 请根据实际文件名修改
# 输出文件路径
output_path = os.path.join(folder_path, "学生名单基本信息模板(BBBB学校).xlsx")
# 附件1需要的字段映射(附件2字段名 -> 输出字段名)
field_mapping = {
"证件类型": "证件类型",
"证件号码": "证件号码",
"出生日期": "出生日期",
"姓名": "姓名",
"民族": "民族",
"籍贯-省份": "籍贯", # 附件1中的籍贯,可用省份或完整籍贯
"性别": "性别",
"年级": "年级", # 托大班、小班、中班、大班
"班级名称": "班级", # 如大1班
"学号": "学号",
"监护人手机": "家长手机号"
}
def process_data(df):
"""处理数据,提取需要的字段并添加固定列"""
# 提取需要的字段
extracted_data = {}
for source_field, target_field in field_mapping.items():
if source_field in df.columns:
extracted_data[target_field] = df[source_field]
else:
print(f"警告:附件2中未找到字段 '{source_field}'")
extracted_data[target_field] = [""] * len(df)
# 创建结果DataFrame
df_result = pd.DataFrame(extracted_data)
# 添加固定字段
df_result.insert(0, "序号", range(1, len(df_result) + 1))
df_result.insert(df_result.columns.get_loc("年级") + 1, "学习阶段(统一写幼儿园)", "幼儿园")
# 重新排列列的顺序,与附件1范例一致
column_order = [
"序号",
"证件类型",
"证件号码",
"出生日期",
"姓名",
"民族",
"籍贯",
"性别",
"学习阶段(统一写幼儿园)",
"年级",
"班级",
"学号",
"家长手机号"
]
# 确保所有列都存在
for col in column_order:
if col not in df_result.columns:
df_result[col] = ""
df_result = df_result[column_order]
return df_result
try:
# 读取附件2
print("正在读取附件2...")
df_attachment2 = pd.read_excel(attachment2_path)
print(f"附件2读取成功,共{len(df_attachment2)}行")
# 检查班级名称字段是否存在
if "班级名称" not in df_attachment2.columns:
print("错误:附件2中没有找到'班级名称'字段")
exit()
# 根据班级名称分类
# 一分园:托1、托2、小1、小2
# 二分园:小3-小6
# 总园:其他班级
# 定义分类条件
condition_yifen = df_attachment2["班级名称"].isin(["托1班", "托2班", "小1班", "小2班"])
condition_erfen = df_attachment2["班级名称"].isin(["小3班", "小4班", "小5班", "小6班"])
condition_zong = ~(condition_yifen | condition_erfen) # 其他班级
# 分别提取数据
df_yifen = df_attachment2[condition_yifen].copy()
df_erfen = df_attachment2[condition_erfen].copy()
df_zong = df_attachment2[condition_zong].copy()
print(f"一分园数据:{len(df_yifen)}条")
print(f"二分园数据:{len(df_erfen)}条")
print(f"总园数据:{len(df_zong)}条")
# 处理每个数据集
df_yifen_processed = process_data(df_yifen) if len(df_yifen) > 0 else pd.DataFrame()
df_erfen_processed = process_data(df_erfen) if len(df_erfen) > 0 else pd.DataFrame()
df_zong_processed = process_data(df_zong) if len(df_zong) > 0 else pd.DataFrame()
# 使用ExcelWriter写入多个工作表
with pd.ExcelWriter(output_path, engine='openpyxl') as writer:
if len(df_yifen_processed) > 0:
df_yifen_processed.to_excel(writer, sheet_name="一分园", index=False)
print(f"已写入工作表'一分园',共{len(df_yifen_processed)}条记录")
else:
print("警告:一分园无数据")
if len(df_erfen_processed) > 0:
df_erfen_processed.to_excel(writer, sheet_name="二分园", index=False)
print(f"已写入工作表'二分园',共{len(df_erfen_processed)}条记录")
else:
print("警告:二分园无数据")
if len(df_zong_processed) > 0:
df_zong_processed.to_excel(writer, sheet_name="总园", index=False)
print(f"已写入工作表'总园',共{len(df_zong_processed)}条记录")
else:
print("警告:总园无数据")
print(f"\n数据提取完成!已保存到: {output_path}")
print(f"共处理{len(df_attachment2)}条记录,已按班级分配到不同工作表")
except FileNotFoundError:
print(f"错误:找不到文件 {attachment2_path}")
print("请确保文件名正确")
except Exception as e:
print(f"发生错误:{e}")
import traceback
traceback.print_exc()


三个园区人数不同



按照学号排列

虽然最后保健老师没有用上,但是我觉得很值得:因为我纠正了“园园通数据匹配学号后的排序问题(小中大5-小中大6班没有排序)”

第1稿:学号用了“市登记编号10位”

第2稿:学号用了“数字学号1-30”

更多推荐



所有评论(0)