背景需求

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

我看到以后,觉得还是用编程带入快速方便,打开表格看一下,查了查原来的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”

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐