欢迎光临
我们一直在努力

【办公类-114-02】20260905江川托育学生名单基本信息模版(运用豆包的Python编程,实现excle数据匹配提取)】

一、背景需求

保健老师求助批量制作“街道需要的幼儿名单”

我看了截图,感觉这些列的提取,我以前应该是没有做过。

索要Excel原版

内部有序列

民族没有序列

二、代码设计

(一)思路

之前我做过街道学生数据提取

【办公类-112-04】20260415街道学生名单基本信息模版(运用deepseek的Python编程,实现excle数据匹配提取)https://mp.csdn.net/mp_blog/creation/editor/160192625

把园园通提取的数据按照我需要的重新排列(让登记编号排在前列第4位)

所以我觉得只要把列表里面的提取内容改成excle的列名,就可以了。

(二)园园通下载所有幼儿全部数据

1.把园园通数据拆分发送把班主任代码里面的第一个py复制一份

把下载的Excel放到“文件夹里”

 

把Excel里面的汉字版本班级“大班一班”改成“数字版班级大1班”。

'''
20260905江川托幼信息收集《XX园–2026学年学生名单》

1、下载园园通新生名册.xls。
2、把“大班一班”改成“大1班
deepseek,阿夏
20260917
'''

import pandas as pd
import os
import re

date='20260825'

def merge_and_format_excel():
# 定义文件路径
path = r'D:\\Python最终内容\\20260903托育名单'
# 设置路径
folder_path = path + r"\\00 园园通下载"
output_path = path + r'\\02 园园通全部班级班信息合并.xlsx'

# 获取文件夹中的所有Excel文件
excel_files = [f for f in os.listdir(folder_path) if f.endswith(('.xlsx', '.xls'))]

# if len(excel_files) < 2:
# print("234文件夹中Excel文件数量不足2个")
# return

# 读取所有Excel文件
dfs = []
for file in excel_files[:3]: # 只处理前两个文件
file_path = os.path.join(folder_path, file)
df = pd.read_excel(file_path)
dfs.append(df)
print(f"已读取文件: {file}")

# 合并数据
merged_df = pd.concat(dfs, ignore_index=True)

# 将列名"ID"改为"市登记编号"(如果存在)
if 'ID' in merged_df.columns:
merged_df.rename(columns={'ID': '市登记编号'}, inplace=True)
print("已将列名'ID'改为'市登记编号'")
else:
print("未找到名为'ID'的列,跳过重命名")

# 格式化班级列(统一改为"托1班"、"小1班"、"中1班"、"大1班"格式)
def format_class_name(class_name):
if pd.isna(class_name):
return class_name

class_str = str(class_name)

# 定义班级类型映射
class_type_map = {
'托': '托', '托大': '托',
'小': '小',
'中': '中',
'大': '大'
}

# 中文数字到阿拉伯数字的映射
chinese_to_arabic = {
'一': '1', '二': '2', '三': '3', '四': '4', '五': '5',
'六': '6', '七': '7', '八': '8', '九': '9', '十': '10',
'十一': '11', '十二': '12'
}

# 先提取班级类型
class_type = None
class_num = None

# 匹配各种格式
# 1. 匹配"托大X班"、"小X班"、"中X班"、"大X班"格式
match = re.search(r'(托大|小|中|大)([一二三四五六七八九十\\d]+)班', class_str)
if match:
class_type = match.group(1)
class_num = match.group(2)
else:
# 2. 匹配"大一班"、"托一班"格式
match = re.search(r'(托|小|中|大)([一二三四五六七八九十])班', class_str)
if match:
class_type = match.group(1)
class_num = match.group(2)
else:
# 3. 匹配"大班一班"格式
match = re.search(r'(托大|小|中|大)班([一二三四五六七八九十]+)班', class_str)
if match:
class_type = match.group(1)
class_num = match.group(2)
else:
# 4. 匹配"一班大班"格式
match = re.search(r'([一二三四五六七八九十]+)班(托大|小|中|大)班', class_str)
if match:
class_num = match.group(1)
class_type = match.group(2)
else:
# 5. 匹配只有班级类型没有班号的情况
match = re.search(r'(托大|小|中|大)班', class_str)
if match:
class_type = match.group(1)
class_num = '1' # 默认班号为1
else:
# 6. 匹配只有班级类型没有"班"字的情况
match = re.search(r'(托大|小|中|大)', class_str)
if match:
class_type = match.group(1)
class_num = '1' # 默认班号为1

if class_type:
# 标准化班级类型
if class_type == '托大':
std_type = '托'
else:
std_type = class_type

# 转换班号
if class_num:
if class_num in chinese_to_arabic:
num = chinese_to_arabic[class_num]
else:
num = class_num
return f"{std_type}{num}班"

# 如果没有匹配到任何模式,尝试直接提取数字
# 检查是否已经是"托1班"这样的格式
match = re.match(r'([托小中大])(\\d+)班', class_str)
if match:
return class_str # 已经是正确格式

# 最后尝试:如果字符串中包含"托"、"小"、"中"、"大",且包含数字
for t in ['托', '小', '中', '大']:
if t in class_str:
# 提取所有数字
nums = re.findall(r'\\d+', class_str)
if nums:
return f"{t}{nums[0]}班"

# 如果还是无法处理,返回原值
print(f"警告:无法识别的班级格式 – {class_str}")
return class_str

# 查找包含班级信息的列
class_columns = [col for col in merged_df.columns if any(keyword in col for keyword in ['班', 'class', '班级'])]

if class_columns:
for class_col in class_columns:
print(f"检测到班级列: {class_col}")
merged_df[class_col] = merged_df[class_col].apply(format_class_name)
else:
print("未检测到班级列,跳过格式转换")

# 保存合并后的文件
merged_df.to_excel(output_path, index=False)
print(f"文件已保存至: {output_path}")
print(f"合并完成,共{len(merged_df)}条记录")

# 显示一些样本数据以供验证
print("\\n前10条数据的班级信息:")
if class_columns:
for class_col in class_columns:
print(f"\\n{class_col}列的前10个值:")
sample_values = merged_df[class_col].head(10).tolist()
for i, val in enumerate(sample_values, 1):
print(f" {i}. {val}")
else:
print("未找到班级列")

# 显示所有列名
print("\\n合并后的所有列名:")
print(merged_df.columns.tolist())

# 执行函数
if __name__ == "__main__":
merge_and_format_excel()

所有标题名称没有改变,只是班级名称变成数字

(三)班级点名册(包含学号)

因为园园通下载名单没有学号,姓名排列混乱,所以需要匹配学号,进行排序。

把不断更新(开学前不断有幼儿转入转出)的班级信息表(包含学号排序).xlsx,下载到文件夹里。

四、豆包设计新的提取代码

第1次

结果只做了大1班

第2次

第3次

终于每个孩子都的信息都提取出来了,但是出生日期要变成斜杠分割

第4次

日期用了斜杠分割

第5次

现在所有班级孩子学生类型都是“新入学”

第6次:添加学号列

第7次

没有班级排序、没有按班级排序,学号也没有从小到大

   

排序又问了1次,还是没有排序

第8次:分析排序规律

我手动排序后,把年级升序、

把班级升序后

再按学号升序(所有1排在一起,导致前面的年级、班级又会打乱)

所以,我要求AI设计“年级、班级升序后,不改变年级和班级的情况,把学号升序”

顺利做出了按顺序排列

最终代码

'''
20260905江川托幼信息收集《XX园–2026学年学生名单》

1.匹配学号
2.读取相应列的内容,更改格式。写入一个Excel内
3.提示复制方法(原表有序列,需要写的内容一模一样)
豆包,阿夏
20260917
'''

# -*- coding: utf-8 -*-
import pandas as pd
import os
import re
from openpyxl.utils import get_column_letter
from openpyxl.styles import Alignment

path = r'D:\\Python最终内容\\20260903托育名单'
date = '20260903'

target_columns = [
'序号', '姓名', '性别', '年级', '班级', '证件类型', '证件号码',
'出生日期', '民族', '户籍类别', '籍贯', '住址', '联系电话', '学生类型', '学号'
]

# ————————–
# 1. 年级映射:指定顺序 托班→小班→中班→大班
# ————————–
grade_map = {
"托班": 1,
"小班": 2,
"中班": 3,
"大班": 4
}

def calculate_display_width(text):
if text is None or (isinstance(text, float) and 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 judge_hukou(province, district):
p = str(province) if pd.notna(province) else ''
d = str(district) if pd.notna(district) else ''
if '上海' in p:
return '本区' if '闵行' in d else '本市外区'
else:
return '外省'

def format_date(value):
if value is None or (isinstance(value, float) and pd.isna(value)):
return ''
try:
dt = pd.to_datetime(value)
return f"{dt.year}/{dt.month}/{dt.day}"
except Exception:
return str(value)

def get_student_type(grade):
if grade in ("托班", "小班"):
return "新入学"
elif grade in ("中班", "大班"):
return "其他"
return ""

def auto_width(worksheet):
for column in worksheet.columns:
max_width = 0
col_letter = get_column_letter(column[0].column)
for cell in column:
try:
w = calculate_display_width(cell.value)
max_width = max(max_width,w)
except Exception:
pass
worksheet.column_dimensions[col_letter].width = min(max(max_width+2,8),100)

def set_text_format(worksheet):
for row in worksheet.iter_rows():
for cell in row:
cell.number_format = '@'
cell.alignment = Alignment(vertical='center', wrap_text=False)

def build_output_df(df):
result = pd.DataFrame()
result['姓名'] = df['姓名']
result['性别'] = df['性别']
result['年级'] = df['_grade_text']
result['班级'] = df['_class_no'].astype(str)
result['证件类型'] = df['证件类型']
result['证件号码'] = df['证件号码']
result['出生日期'] = df['出生日期'].apply(format_date)
result['民族'] = df['民族']
result['户籍类别'] = df.apply(lambda r: judge_hukou(r['户口所在地-省份'], r['户口所在地-区县']), axis=1)
result['籍贯'] = df['籍贯-省份']
result['住址'] = df['现居地-详细地址']
result['联系电话'] = df['监护人手机']
result['学生类型'] = result['年级'].apply(get_student_type)
result['学号'] = df['学号']
return result

# ===================== 读取&合并数据 =====================
df_main = pd.read_excel(path + r'\\02 园园通全部班级班信息合并.xlsx', dtype=str)
xls = pd.ExcelFile(path + r'\\01 20260805班级信息表.xlsx')
df_list = []
for sheet in xls.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)

df_merged = pd.merge(df_main,
df_info[['班级', '姓名', '学号']],
left_on=['班级名称','姓名'],
right_on=['班级','姓名'],
how='left')

# ————————–
# 从原始班级名称拆分出年级文字、班号数字
# ————————–
def split_grade_class(raw):
s = str(raw).strip().replace('\\u3000','')
m = re.match(r'([托小中大])(\\d+)班', s)
if m:
g_txt = {"托":"托班","小":"小班","中":"中班","大":"大班"}[m.group(1)]
c_num = int(m.group(2))
return g_txt, c_num
return "", 999

res = df_merged['班级名称'].apply(split_grade_class)
df_merged['_grade_text'] = [x[0] for x in res]
df_merged['_class_no'] = [x[1] for x in res]

# ————————–
# 构建排序字段(核心!)
# 1.年级编码:托班1,小班2,中班3,大班4
# 2.班号数字
# 3.学号数字;空学号填9999放在本班末尾
# ————————–
df_merged['sort_grade'] = df_merged['_grade_text'].map(grade_map).fillna(99)
df_merged['sort_class'] = df_merged['_class_no']
df_merged['sort_stuid'] = pd.to_numeric(df_merged['学号'], errors='coerce').fillna(9999)

# 三层排序:年级编码 → 班号 → 学号
df_sorted = df_merged.sort_values(
by=["sort_grade", "sort_class", "sort_stuid"],
ascending=[True, True, True]
).reset_index(drop=True)

# 生成输出表,再补序号
output_df = build_output_df(df_sorted)
output_df.insert(0, "序号", range(1, len(output_df)+1))
output_df = output_df[target_columns]

# ————————–
# 打印调试前30行,看排序字段
# ————————–
print("====调试【年级编码|年级|班号|学号排序值|原始学号】====")
dbg = df_sorted[["sort_grade","_grade_text","sort_class","sort_stuid","学号"]].head(30)
print(dbg.to_string())

# 输出Excel
out_path = os.path.join(path, f'03_最终排序_年级班级学号升序.xlsx')
sheet_name = f'全园名单'[:31]

with pd.ExcelWriter(out_path, engine='openpyxl') as writer:
output_df.to_excel(writer, sheet_name=sheet_name, index=False)
ws = writer.sheets[sheet_name]
auto_width(ws)
set_text_format(ws)

print(f"\\n✅输出完成:{out_path}")
print("排序规则:托班→小班→中班→大班;同年级班号升序;同班学号数字升序")

三、发送保健老师

因为原表有序列(三角箭头),提示教师黏贴值

微信交流记录

四、感悟:

用都报AI编程,只用了1小时就调整好了490分表格,发给保健老师,她就不需要向班主任收集了

1.实效性:班主任填写的话,收集起来速度慢了。

2.重要性:这个江川表单与“幼儿保险表”相比,不是特别重要,所以可以Python批量制作所有人员名单。

五、存在问题

20260905我把这个项目制作CSDN,最后截图时,发5个小班都没有籍贯,但是托、中、大,都有籍贯

在园园通上看,原来小班导入数据没有“出生地省市区”“籍贯地省市区”,且这些空格都是“非必填”

但是其他三个年级都有“出生地省市区”“籍贯地省市区”

所以我还是要把园园通补全。再次运行这个代码,才能把小班的籍贯补全。

写个程序自动按照小班幼儿名字打开编辑页进行编辑,但是由于没有原始登记表(小班没有登记表,托班有)。所以只能都填写“上海市上海市闵行区”

赞(0)
未经允许不得转载:171主机测评 » 【办公类-114-02】20260905江川托育学生名单基本信息模版(运用豆包的Python编程,实现excle数据匹配提取)】
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址