ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

【办公类-112-08】20261009园园通信息合并配学号拆班(数据更新,用年月日期区分版本)

【办公类-112-08】20261009园园通信息合并配学号拆班(数据更新,用年月日期区分版本)

一、背景需求

10月的插班生信息进入园园通了,我需要更新班级点名册,把这些插班生班级的EXCEL发给班主任

每月都有孩子转入转出,原来写的园园通信息合并配学号拆班的代码每个月都要生成一次(发给插班生的班级),但是都是同一个文件名(20260806)所以每次刷新会替换掉excle内部的数据,转出孩子的信息就不见了。

【办公类-112-07】20260828园园通信息合并配学号拆班(园园通市级编号在excel中的位置调整,调整最适合列宽)https://mp.csdn.net/mp_blog/creation/editor/164063926

因为更新后,转走的孩子的信息就没有了,所以这次我想保留每个月的更新数据。

二、下载相关数据

1.园园通数据(所有孩子的所有信息),excle文件名并添加日期

2.班级信息表(匹配序号)

把更新后的班级点名册下载,文件名增加日期

三、代码补充日期

1.更改班级的汉字为数字

''' 2025082520250825_2025_学年出入所(园)儿童基本情况登记 表一空 01 1、下载园园通新生名册.xls,把两个新生名册合并在一起 2、部分插班生信息手动添加 deepseek,阿夏 20261009 ''' import pandas as pd import os import re date='20261009' def merge_and_format_excel(): # 定义文件路径 path = r'D:\Python最终内容\20260902 2026园园通幼儿信息提取配学号拆班发班主任' # 设置路径 folder_path = path + r"\00 园园通下载" output_path = path + fr'\02 {date}园园通全部班级班信息合并.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()

生成文件名有日期(内部知识班级变成了数字)

2、拆分班级(日期)文件夹

''' 20250825_2025_学年出入所(园)儿童基本情况登记 表一空 01 1、用合并xls与班级信息表的学号匹配,按学号排队 2、按班级拆分成一个个班级,最适合列宽一行(非自动换行) 3、按指定的列名顺序重新排列列的位置 20261009 ''' 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:\Python最终内容\20260902 2026园园通幼儿信息提取配学号拆班发班主任' date='20261009' # 定义目标列名顺序 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 + fr'\02 {date}园园通全部班级班信息合并.xlsx', dtype=str) # 2. 读取班级信息表的所有工作表,将所有列作为字符串读取 xls = pd.ExcelFile(path + fr'\01 {date}班级信息表.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, '托3班': 3, '托4班': 4, '小1班': 11, '小2班': 12, '小3班': 13, '小4班': 14, '小5班': 15, '中1班': 21, '中2班': 22, '中3班': 23, '中4班': 24,'中5班': 25,'中6班': 26, '大1班': 31, '大2班': 32, '大3班': 33, '大4班': 34,'大5班': 35, } # 添加临时排序列 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'\03 匹配学号.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 + fr'\04 拆分班级\{date}' 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} 文件夹,每个班级内按学号排序,按指定列名顺序排列,所有单元格保持文本格式,根据实际显示宽度计算最适合列宽")

三、私发有插班生的班主任

标注日期后,就可以避免数据被替换,保留每个月的幼儿信息。

-------------------------

20261105,11月插班一人(小5班)

这位同学插在21号位置上

下载“共享文档“班级信息表”

下载RAR

源文件转移

00园园通下载文件夹里面放上最新版本的额园园通全部幼儿数据

运行两个代码

因为Python最终内容,这个代码经常用,但我容易找不到,所以在路径最前面添加000,确保在最前面能找到它

代码里面的路径也变了

两个代码都要改日期

''' 2025082520250825_2025_学年出入所(园)儿童基本情况登记 表一空 01 1、下载园园通新生名册.xls,把两个新生名册合并在一起 2、部分插班生信息手动添加 deepseek,阿夏 20261009 ''' import pandas as pd import os import re date='20261105' def merge_and_format_excel(): # 定义文件路径 path = r'D:\000Python最终内容\20260902 2026园园通幼儿信息提取配学号拆班发班主任' # 设置路径 folder_path = path + r"\00 园园通下载" output_path = path + fr'\02 {date}园园通全部班级班信息合并.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()
''' 20250825_2025_学年出入所(园)儿童基本情况登记 表一空 01 1、用合并xls与班级信息表的学号匹配,按学号排队 2、按班级拆分成一个个班级,最适合列宽一行(非自动换行) 3、按指定的列名顺序重新排列列的位置 20261009 ''' 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:\000Python最终内容\20260902 2026园园通幼儿信息提取配学号拆班发班主任' date='20261105' # 定义目标列名顺序 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 + fr'\02 {date}园园通全部班级班信息合并.xlsx', dtype=str) # 2. 读取班级信息表的所有工作表,将所有列作为字符串读取 xls = pd.ExcelFile(path + fr'\01 {date}班级信息表.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, '托3班': 3, '托4班': 4, '小1班': 11, '小2班': 12, '小3班': 13, '小4班': 14, '小5班': 15, '中1班': 21, '中2班': 22, '中3班': 23, '中4班': 24,'中5班': 25,'中6班': 26, '大1班': 31, '大2班': 32, '大3班': 33, '大4班': 34,'大5班': 35, } # 添加临时排序列 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'\03 匹配学号.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 + fr'\04 拆分班级\{date}' 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} 文件夹,每个班级内按学号排序,按指定列名顺序排列,所有单元格保持文本格式,根据实际显示宽度计算最适合列宽")

打开看了一下,小5班21号是新孩子的姓名。

转发班主任

返回列表