【办公类-18-09】20250520(Python)全园幼儿“验血单信息”批量生成打印(学校、班级、姓名、性别)
·

背景需求
昨天做了全园所有班级的“涂氟单”PDF
【办公类-18-08】20251217(Python)全园幼儿“口腔检查涂氟信息”批量生成打印
https://mp.csdn.net/mp_blog/creation/editor/156028065
今天再同理做一份“验血单”
一、数据情况


二、下载园园通名单

三、合并exlce
'''
20251220验血单制作
1、下载园园通新生名册.xls,把两个新生名册合并在一起
2、部分插班生信息手动添加
deepseek,阿夏
20251124
'''
import pandas as pd
import os
import re
def format_long_number(value):
"""处理长数字,避免科学计数法和精度丢失"""
if pd.isna(value) or value == '':
return value
str_value = str(value).strip()
# 处理科学计数法
if 'e+' in str_value.lower() or 'e-' in str_value.lower():
try:
# 将科学计数法转换为完整数字
num_value = float(str_value)
return str(int(num_value)) if num_value.is_integer() else str(num_value)
except:
return str_value
# 处理浮点数.0的情况
if '.' in str_value and str_value.endswith('.0'):
return str_value[:-2]
return str_value
def format_class_name(class_name):
"""格式化班级名称"""
if pd.isna(class_name) or class_name == '':
return class_name
class_str = str(class_name)
# 定义班级类型和对应的前缀
class_types = {
'托班': '托', '托': '托',
'小班': '小', '小': '小',
'中班': '中', '中': '中',
'大班': '大', '大': '大'
}
# 中文数字到阿拉伯数字的映射
chinese_to_arabic = {
'一': '1', '二': '2', '三': '3', '四': '4', '五': '5',
'六': '6', '七': '7', '八': '8', '九': '9', '十': '10',
'1': '1', '2': '2', '3': '3', '4': '4', '5': '5',
'6': '6', '7': '7', '8': '8', '9': '9', '10': '10'
}
# 尝试匹配各种班级格式
patterns = [
r'([托小中大])班(\S+?)班', # 如:大班一班
r'([托小中大])(\S+?)班', # 如:大一班
r'(\S+?)([托小中大])班', # 如:一班大班
r'([托小中大])班', # 如:大班(没有具体班号)
]
for pattern in patterns:
match = re.search(pattern, class_str)
if match:
if len(match.groups()) >= 0:
# 有班级类型和班号
class_type = match.group(1)
class_num = match.group(2)
# 获取班级前缀
prefix = class_types.get(class_type, class_type)
# 转换班号
if class_num in chinese_to_arabic:
num = chinese_to_arabic[class_num]
return f"{prefix}{num}班"
else:
return f"{prefix}{class_num}班"
else:
# 只有班级类型,没有班号
class_type = match.group(1)
prefix = class_types.get(class_type, class_type)
return f"{prefix}班"
# 如果没有匹配到任何模式,返回原值
return class_str
def merge_and_format_excel():
# 定义文件路径
path = r'C:\Users\jg2yXRZ\OneDrive\桌面\20251220验血单全园'
folder_path = path + r"\01园园通下载"
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)
# 首先读取第一行来检测列的数据类型
temp_df = pd.read_excel(file_path, nrows=1)
# 创建dtype字典,将所有列都设置为字符串类型
dtype_dict = {col: str for col in temp_df.columns}
# 用字符串类型重新读取整个文件
df = pd.read_excel(file_path, dtype=dtype_dict, keep_default_na=False)
# 特别处理身份证号、学号等可能的长数字列
for col in df.columns:
if any(keyword in col for keyword in ['身份证', '证件号', '学号', '幼儿编号', 'ID']):
# 去除可能的空格和特殊字符
df[col] = df[col].astype(str).str.strip()
# 如果是以科学计数法形式出现的数字,进行转换
df[col] = df[col].apply(lambda x: format_long_number(x))
dfs.append(df)
print(f"已读取文件: {file}")
# 合并数据
merged_df = pd.concat(dfs, ignore_index=True)
# 查找包含班级信息的列
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("未检测到班级列,跳过格式转换")
# 再次处理所有列,确保数字格式正确
for col in merged_df.columns:
merged_df[col] = merged_df[col].apply(format_long_number)
# 保存合并后的文件
# 使用openpyxl引擎,避免xlsxwriter对长数字的处理问题
with pd.ExcelWriter(output_path, engine='openpyxl') as writer:
merged_df.to_excel(writer, index=False)
print(f"文件已保存至: {output_path}")
print(f"合并完成,共{len(merged_df)}条记录")
# 显示一些样本数据以供验证
print("\n前5条数据的班级信息:")
if class_columns:
for class_col in class_columns:
print(f"{class_col}列的前5个值:")
print(merged_df[class_col].head().tolist())
# 特别显示可能的长数字列
long_num_cols = [col for col in merged_df.columns if any(keyword in col for keyword in ['身份证', '证件号', '学号', '幼儿编号', 'ID'])]
if long_num_cols:
print("\n长数字列样本数据:")
for col in long_num_cols:
print(f"{col}列的前3个值:")
print(merged_df[col].head(3).tolist())
# 执行函数
if __name__ == "__main__":
merge_and_format_excel()

四、匹配学号,重新排列
'''
20251220验血单制作
1、用合并xls与班级信息表的学号匹配,按学号排队,保存03匹配学号.xlsx
deepseek,阿夏
20251217
'''
import pandas as pd
import os
def format_long_number(value):
"""处理长数字,避免科学计数法和精度丢失"""
if pd.isna(value) or value == '':
return value
str_value = str(value).strip()
# 处理科学计数法
if 'e+' in str_value.lower() or 'e-' in str_value.lower():
try:
# 将科学计数法转换为完整数字
num_value = float(str_value)
return str(int(num_value)) if num_value.is_integer() else str(num_value)
except:
return str_value
# 处理浮点数.0的情况
if '.' in str_value and str_value.endswith('.0'):
return str_value[:-2]
# 处理浮点数显示为整数的情况
if '.' in str_value:
try:
# 检查是否可以转换为整数
float_val = float(str_value)
if float_val.is_integer():
return str(int(float_val))
except:
pass
return str_value
# 设置路径
path =r'C:\Users\jg2yXRZ\OneDrive\桌面\20251220验血单全园'
# 1. 读取园园通信息表 - 所有列都作为字符串读取
df_main = pd.read_excel(path + r'\02园园通全部班级信息合并.xlsx', dtype=str, keep_default_na=False)
# 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, keep_default_na=False)
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. 处理所有数字列,避免精度丢失
for col in df_merged.columns:
df_merged[col] = df_merged[col].apply(format_long_number)
# 7. 对完整匹配结果进行排序并保存
# 确保学号列是数值类型用于排序,但保存时保持字符串格式
df_merged['学号_排序'] = pd.to_numeric(df_merged['学号'], errors='coerce')
# 创建班级排序的映射关系
class_order = {
'托1班': 1, '托2班': 2, '托3班': 3, '托4班': 4,
'小1班': 5, '小2班': 6, '小3班': 7, '小4班': 8,
'中1班': 9, '中2班': 10, '中3班': 11, '中4班': 12,
'大1班': 13, '大2班': 14, '大3班': 15, '大4班': 16
}
# 添加临时排序列
df_merged['班级排序'] = df_merged['所在班级'].map(class_order)
# 先按班级排序,再按学号排序
df_merged_sorted = df_merged.sort_values(by=['班级排序', '学号_排序'])
# 删除临时排序列
df_merged_sorted = df_merged_sorted.drop(['班级排序', '学号_排序'], axis=1)
# 保存排序后的完整表格,使用openpyxl引擎避免数字格式问题
with pd.ExcelWriter(path + r'\03匹配学号.xlsx', engine='openpyxl') as writer:
df_merged_sorted.to_excel(writer, index=False)

五、制作需要信息的EXCLE,分割成一个个班级,并把一个个班级作为一个工作簿的多个工作表
'''
20251220验血单制作
1、将03匹配学号.xlsx里面的学号、班级、姓名、身份证号,幼儿编号等数据写入到医保模版指定的列里
2、先生成每个班级的独立Excel文件,再合并所有文件到一个工作簿(每个班级一个工作表)
3、合并完成后删除存放单个文件的文件夹
deepseek,阿夏
20251216
'''
import pandas as pd
import numpy as np
from openpyxl import load_workbook, Workbook
from openpyxl.styles import Alignment
import os
import glob
import shutil # 用于删除文件夹(含子文件)
# 全局定义上海行政区列表(避免作用域问题)
OUTER_DISTRICT_LIST = [
'黄浦区', '徐汇区', '长宁区', '静安区', '普陀区', '虹口区', '杨浦区',
'浦东新区', '宝山区', '嘉定区', '金山区', '松江区', '青浦区', '奉贤区', '崇明区'
]
SHANGHAI_DISTRICTS = ['闵行区'] + OUTER_DISTRICT_LIST
# ===================== 核心修改:统一配置路径 =====================
# 请根据你的实际文件位置修改这个路径!!!
BASE_PATH = r'C:\Users\jg2yXRZ\OneDrive\桌面\20251220验血单全园'
def batch_process_all_classes():
"""批量处理所有班级的医保表格数据(生成单个班级文件)"""
main_data_file = os.path.join(BASE_PATH, '03匹配学号.xlsx')
# 增加文件存在性检查
if not os.path.exists(main_data_file):
print(f"❌ 主数据文件不存在:{main_data_file}")
print("请检查:1. 文件路径是否正确 2. 文件名是否为'03匹配学号.xlsx'")
return
df_main = pd.read_excel(main_data_file, sheet_name=0)
valid_classes = [cls for cls in df_main['所在班级'].unique() if pd.notna(cls)]
print(f"✅ 成功识别 {len(valid_classes)} 个班级:{valid_classes}")
for class_name in valid_classes:
process_single_class(df_main, class_name, BASE_PATH)
print(f"\n🎉 所有班级独立文件生成完成!累计处理 {len(valid_classes)} 个班级")
# 生成完成后自动执行合并操作
merge_class_files_to_one_workbook(BASE_PATH)
# 合并完成后删除单个文件的文件夹
output_dir = os.path.join(BASE_PATH, '2025全校学生验血单')
delete_folder(output_dir)
def process_single_class(main_df, class_name, base_path):
"""处理单个班级:加载模板、设置格式、填充数据、保存文件"""
class_students = main_df[main_df['所在班级'] == class_name].copy()
student_count_total = len(class_students)
print(f"\n📌 开始处理班级:{class_name}(共{student_count_total}名学生)")
template_file = os.path.join(base_path, '00模版验血单表格.xlsx')
# 增加模板文件检查
if not os.path.exists(template_file):
print(f"❌ 模板文件缺失:{template_file}")
print("请检查:1. 模板文件是否在指定路径 2. 文件名是否为'00模版验血单表格.xlsx'")
return
try:
workbook = load_workbook(template_file)
worksheet = workbook.active
except Exception as e:
print(f"❌ 加载模板文件失败:{str(e)}")
return
# 全局统一文本格式(E/F列)
for col_letter in ['E', 'F']:
for cell in worksheet[col_letter]:
cell.number_format = '@'
cell.alignment = Alignment(horizontal='left')
start_row = 2
max_student_limit = 35
filled_count = 0
for row_idx, (_, student_info) in enumerate(class_students.iterrows(), start=start_row):
if filled_count >= max_student_limit:
print(f"⚠️ 班级 {class_name} 学生数超过{max_student_limit}人,仅保留前{max_student_limit}条数据")
break
filled_count += 1
print(f" 🔄 处理第{filled_count}名学生:{student_info['姓名']}")
fill_student_details(worksheet, row_idx, student_info, class_name)
# 创建输出目录并保存文件
output_dir = os.path.join(base_path, '2025全校学生验血单')
os.makedirs(output_dir, exist_ok=True)
output_filename = f'{class_name}_2025园园通学生验血单.xlsx'
output_path = os.path.join(output_dir, output_filename)
try:
workbook.save(output_path)
print(f"✅ 班级 {class_name} 处理完成,文件保存至:{output_path}")
except PermissionError:
print(f"❌ 保存失败:{output_path} 已被打开,请关闭后重试")
except Exception as e:
print(f"❌ 保存文件失败:{str(e)}")
def fill_student_details(worksheet, row_num, student_data, class_name):
"""填充单个学生的详细信息到表格指定位置"""
# A列:学号
if '学号' in student_data and pd.notna(student_data['学号']):
worksheet[f'A{row_num}'] = str(student_data['学号'])
# B列:姓名
if '姓名' in student_data and pd.notna(student_data['姓名']):
worksheet[f'B{row_num}'] = student_data['姓名']
# C列:班级
if '所在班级' in student_data and pd.notna(student_data['所在班级']):
worksheet[f'C{row_num}'] = student_data['所在班级']
# D列:性别
if '性别' in student_data and pd.notna(student_data['性别']):
worksheet[f'D{row_num}'] = str(student_data['性别'])
# 以下为注释掉的字段,如需启用可取消注释
# # I列:证件号码(身份证号)
# if '证件号码' in student_data and pd.notna(student_data['证件号码']):
# worksheet[f'I{row_num}'] = str(student_data['证件号码'])
# worksheet[f'I{row_num}'].number_format = '@'
# # F/G/H列:出生日期(拆分为年/月/日,补零至2位)
# if '出生日期' in student_data and pd.notna(student_data['出生日期']):
# try:
# birth_dt = pd.to_datetime(student_data['出生日期'])
# worksheet[f'F{row_num}'] = birth_dt.year # 年
# worksheet[f'G{row_num}'] = f"{birth_dt.month:02d}" # 月(补零)
# worksheet[f'H{row_num}'] = f"{birth_dt.day:02d}" # 日(补零)
# worksheet[f'G{row_num}'].number_format = '@'
# worksheet[f'H{row_num}'].number_format = '@'
# except Exception as e:
# worksheet[f'F{row_num}'] = str(student_data['出生日期'])
# print(f" ⚠️ {student_data['姓名']} 出生日期格式异常:{student_data['出生日期']},错误:{str(e)}")
# # J/K列:户口所在地(上海→J列勾,非上海→K列勾)
# if '户口所在地区' in student_data and pd.notna(student_data['户口所在地区']):
# hukou_district = str(student_data['户口所在地区']).strip()
# if hukou_district in SHANGHAI_DISTRICTS:
# worksheet[f'J{row_num}'] = '√'
# else:
# worksheet[f'K{row_num}'] = '√'
def merge_class_files_to_one_workbook(base_path):
"""将2025全校学生验血单文件夹中的所有班级文件合并到一个工作簿(仅复制值,避免格式报错)"""
# 1. 定义文件夹路径和文件匹配规则
output_dir = os.path.join(base_path, '2025全校学生验血单')
if not os.path.exists(output_dir):
print(f"\n⚠️ 待合并的文件夹不存在:{output_dir}")
return
file_pattern = os.path.join(output_dir, '*_2025园园通学生验血单.xlsx')
class_files = glob.glob(file_pattern)
if not class_files:
print(f"\n⚠️ 未找到待合并的班级文件,检查路径:{output_dir}")
return
print(f"\n📁 找到 {len(class_files)} 个待合并的班级文件:")
for f in class_files:
print(f" - {os.path.basename(f)}")
# 2. 创建新的整合工作簿
merged_wb = Workbook()
# 删除默认的Sheet工作表
if 'Sheet' in merged_wb.sheetnames:
merged_wb.remove(merged_wb['Sheet'])
# 3. 逐个读取班级文件,仅复制值到整合工作簿
for file_path in class_files:
try:
# 读取单个班级文件(仅读值,不加载格式,提升效率)
class_wb = load_workbook(file_path, data_only=True)
class_ws = class_wb.active
# 提取班级名(从文件名中截取)
file_name = os.path.basename(file_path)
class_name = file_name.replace('_2025园园通学生验血单.xlsx', '')
# 在整合工作簿中新建工作表,命名为班级名
new_ws = merged_wb.create_sheet(title=class_name)
# 仅复制单元格的值
for row_idx, row in enumerate(class_ws.iter_rows(values_only=True), start=1):
for col_idx, cell_value in enumerate(row, start=1):
new_ws.cell(row=row_idx, column=col_idx, value=cell_value)
# 对关键列设置文本格式
key_cols = ['A', 'E', 'F', 'G', 'H', 'I'] # 学号、班级、出生日期、身份证号列
for col_letter in key_cols:
for row in new_ws.iter_rows(min_row=1, max_row=100):
cell = row[ord(col_letter)-ord('A')]
cell.number_format = '@'
cell.alignment = Alignment(horizontal='left')
print(f"✅ 已合并班级:{class_name}")
except Exception as e:
print(f"❌ 合并文件 {file_path} 失败:{str(e)}")
# 4. 保存整合后的工作簿
merged_file_path = os.path.join(base_path, '04园园通学生验血单_班级合并版.xlsx')
try:
merged_wb.save(merged_file_path)
print(f"\n🎉 所有班级文件合并完成!")
print(f"📑 合并文件保存至:{merged_file_path}")
print(f"📊 工作簿包含工作表:{merged_wb.sheetnames}")
except PermissionError:
print(f"\n❌ 合并文件保存失败:{merged_file_path} 已被打开,请关闭后重试")
except Exception as e:
print(f"\n❌ 保存合并文件失败:{str(e)}")
def delete_folder(folder_path):
"""删除指定文件夹(含所有子文件/子文件夹),处理权限问题"""
if not os.path.exists(folder_path):
print(f"\n📂 文件夹 {folder_path} 不存在,无需删除")
return
try:
# rmtree 递归删除文件夹及所有内容
shutil.rmtree(folder_path)
print(f"\n🗑️ 已成功删除文件夹:{folder_path}")
except PermissionError:
print(f"\n❌ 删除文件夹失败:{folder_path} 或其中的文件被占用,请关闭相关Excel文件后手动删除")
except Exception as e:
print(f"\n❌ 删除文件夹 {folder_path} 失败:{str(e)}")
# 主程序入口
if __name__ == "__main__":
print("="*60)
print("📋 程序开始执行 - 验血单批量生成工具")
print(f" 基础路径:{BASE_PATH}")
print("="*60)
try:
main_data_path = os.path.join(BASE_PATH, '03匹配学号.xlsx')
if not os.path.exists(main_data_path):
raise FileNotFoundError(f"主数据文件不存在:{main_data_path}")
df_check = pd.read_excel(main_data_path)
# 调整必要列清单,适配实际业务
required_columns = [
'所在班级', '学号', '姓名', '性别'
]
missing_cols = [col for col in required_columns if col not in df_check.columns]
if missing_cols:
raise ValueError(f"主数据文件缺少必要列:{', '.join(missing_cols)}")
print("📋 主数据文件信息:")
print(f" 列名:{df_check.columns.tolist()}")
print(f" 总行数:{len(df_check)}")
print(f" 涉及班级:{[cls for cls in df_check['所在班级'].unique() if pd.notna(cls)]}")
print("="*60)
batch_process_all_classes()
print("\n✅ 程序执行完毕!")
except Exception as main_err:
print(f"\n❌ 程序执行失败:{str(main_err)}")
print("请优先检查:")
print(" 1. BASE_PATH 变量是否指向正确的文件夹")
print(" 2. 文件夹内是否有 '03匹配学号.xlsx' 和 '00模版验血单表格.xlsx' 文件")
print(" 3. 所有Excel文件都已关闭(避免权限问题)")


六、每个班级内容都做成PDF
# -*- coding:utf-8 -*-
'''
目的:验血单(一个班级单独打印)
作者:deepseek,阿夏
日期:20251220
功能:遍历Excel多工作表,每个班级生成独立的合并PDF(统一存放至“合并PDF”文件夹)
'''
# 一、导入相关模块,设定路径
from docxtpl import DocxTemplate
import pandas as pd
import os
import time
from docx2pdf import convert
from PyPDF2 import PdfFileMerger
import shutil
# 配置参数
l = 2 # 1=有背景图,2=无背景图
zpath = r'C:\Users\jg2yXRZ\OneDrive\桌面\20251220验血单全园\\'
temp_word_path = zpath + r'零时Word' # 临时Word/PDF文件夹
pdf_output_dir = os.path.join(zpath, "02合并PDF") # 最终PDF统一存放文件夹
# 二、核心函数:处理单个班级(工作表)的数据
def process_class_sheet(sheet_name, sheet_data):
"""
处理单个班级的Excel数据
:param sheet_name: 工作表名(班级名)
:param sheet_data: 该班级的DataFrame数据
"""
# 1. 创建临时文件夹(每个班级单独的临时目录,避免冲突)
class_temp_path = os.path.join(temp_word_path, sheet_name)
try:
os.makedirs(class_temp_path)
except FileExistsError:
pass
# 2. 获取班级数据
total_people = sheet_data.shape[0]
print(f"\n===== 开始处理【{sheet_name}】班,共 {total_people} 人 =====")
# 提取列数据(做空值处理,避免报错)
sheet_data = sheet_data.fillna("") # 空值替换为空字符串
num = sheet_data["num"]
name = sheet_data["name"]
# school = sheet_data["school"]
sex = sheet_data["sex"]
classroom = sheet_data["classroom"].astype(str).str.replace('\n', '') # 去掉换行符
# y = sheet_data["y"]
# m = sheet_data["m"]
# d = sheet_data["d"]
# ID = sheet_data["ID"]
# SH = sheet_data["SH"]
# FSH = sheet_data["FSH"]
# M = sheet_data["M"]
# F = sheet_data["F"]
# dis = sheet_data["dis"]
# nation = sheet_data["nation"]
# 3. 遍历生成单个Word和PDF
pdf_files = [] # 存储该班级的所有PDF路径
for i in range(total_people):
try:
# 构造渲染数据
context = {
"num": str(num.iloc[i]),
"sex": sex.iloc[i],
# "dis": dis.iloc[i],
"name": name.iloc[i],
# "school": school.iloc[i],
"classroom": classroom.iloc[i],
# "y": y.iloc[i],
# "m": m.iloc[i],
# "d": d.iloc[i],
# "ID": ID.iloc[i],
# "SH": SH.iloc[i],
# "FSH": FSH.iloc[i],
# "M": M.iloc[i],
# "F": F.iloc[i],
# "nation": nation.iloc[i],
}
# 加载模板
if l == 1:
tpl = DocxTemplate(zpath + '打印单字(有背景).docx')
else:
tpl = DocxTemplate(zpath + '打印单字(无背景).docx')
# 生成Word
word_file = os.path.join(class_temp_path, f'{num.iloc[i]:02}.docx')
tpl.render(context)
tpl.save(word_file)
# 转换为PDF
pdf_file = os.path.join(class_temp_path, f'{num.iloc[i]:02}.pdf')
convert(word_file, pdf_file)
pdf_files.append(pdf_file)
print(f" 已生成:{sheet_name}班 - {num.iloc[i]:02}.pdf")
time.sleep(1) # 避免转换过快报错
except Exception as e:
print(f" ❌ 处理第{i+1}条数据失败:{str(e)}")
continue
# 4. 合并该班级的所有PDF(保存到“合并PDF”文件夹)
if pdf_files:
# 创建“合并PDF”文件夹(确保存在)
os.makedirs(pdf_output_dir, exist_ok=True)
pdf_files.sort() # 按序号排序
merger = PdfFileMerger()
for pdf in pdf_files:
try:
merger.append(pdf)
except:
pass
# 定义最终PDF文件名(保存到“合并PDF”文件夹)
bg_flag = "有背景图" if l == 1 else "无背景图"
final_pdf_name = f"{sheet_name}班验血单({total_people}人)({bg_flag}).pdf"
final_pdf_path = os.path.join(pdf_output_dir, final_pdf_name)
# 保存合并后的PDF
merger.write(final_pdf_path)
merger.close()
print(f"\n✅ 【{sheet_name}】班合并PDF完成:{final_pdf_path}")
else:
print(f"\n⚠️ 【{sheet_name}】班无有效PDF文件,跳过合并")
# 5. 删除该班级的临时文件夹
try:
shutil.rmtree(class_temp_path)
print(f"🗑️ 已删除【{sheet_name}】班临时文件")
except:
print(f"⚠️ 【{sheet_name}】班临时文件删除失败,请手动清理:{class_temp_path}")
# 三、主流程:遍历Excel所有工作表
if __name__ == "__main__":
# 1. 检查Excel文件是否存在
excel_path = zpath + '04园园通学生验血单_班级合并版.xlsx'
if not os.path.exists(excel_path):
print(f"❌ 未找到Excel文件:{excel_path}")
exit()
# 2. 提前创建“合并PDF”文件夹(确保目录存在)
os.makedirs(pdf_output_dir, exist_ok=True)
print(f"📂 最终PDF将保存至:{pdf_output_dir}")
# 3. 获取所有工作表名称
excel_file = pd.ExcelFile(excel_path)
sheet_names = excel_file.sheet_names
print(f"📋 找到Excel工作表(班级):{sheet_names}")
# 4. 遍历每个工作表(班级)处理
for sheet in sheet_names:
# 读取该工作表的数据
df = pd.read_excel(excel_path, sheet_name=sheet)
# 处理该班级
process_class_sheet(sheet, df)
# 5. 删除总临时文件夹
try:
shutil.rmtree(temp_word_path)
print(f"\n🗑️ 已删除总临时文件夹:{temp_word_path}")
except:
print(f"\n⚠️ 总临时文件夹删除失败,请手动清理:{temp_word_path}")
print(f"\n🎉 所有班级PDF生成完成!所有PDF文件已保存至:{pdf_output_dir}")


因为20个班级,每个班级20-35人之间,所以生成时间很长。



更多推荐



所有评论(0)