【办公类-18-07】20250527屈光检查PDF文件拆分成多个pdf(两页一份,用幼儿班级姓名命名文件)

article/2025/7/4 8:07:01

背景需求:

今天春游,上海海昌公园。路上保健老师收到前几天幼儿的屈光视力检查单PDF。

她说:所有孩子的通知都做在一个PDF里,我没法单独发给班主任。你有什么办法拆开来?

我说:“没问题,问deep seek,它会写拆分代码。

过了一会儿保健老师与保健所联系,决定保健所打印这些胆子。

“那你就不用做了!”

讨论时,保健老师感叹:有145个孩子,这么多屈光有问题!信息化时代下,幼儿的远端视力越来越差了。

但是我没有作过PDF拆分,还是试了一下

设计过程:

PDF拆分成2页一个PDF

代码展示

'''
屈光PDF按照2张一份,拆分成多个编号
deepseek 阿夏
20250527
'''
from PyPDF2 import PdfReader, PdfWriter
import osdef split_pdf_every_2_pages(input_pdf_path, output_folder):# 创建输出文件夹(如果不存在)if not os.path.exists(output_folder):os.makedirs(output_folder)# 读取PDF文件reader = PdfReader(input_pdf_path)total_pages = len(reader.pages)print(f"总页数: {total_pages}")# 计算需要分割的文件数量num_files = (total_pages + 1) // 2for i in range(num_files):writer = PdfWriter()# 计算当前文件的起始和结束页码start_page = i * 2end_page = min(start_page + 2, total_pages)# 添加页面到新PDFfor page_num in range(start_page, end_page):writer.add_page(reader.pages[page_num])# 生成输出文件名output_filename = os.path.join(output_folder, f"{i+1:003}_P{start_page+1}-P{end_page}.pdf")# 写入新PDF文件with open(output_filename, "wb") as out:writer.write(out)print(f"已创建: {output_filename}")# 使用示例
path=r'C:\Users\jg2yXRZ\OneDrive\桌面\20250527视力复诊屈光拆分'
input_pdf =path + r"\复诊通知XXXx.pdf"  # 替换为你的PDF文件路径
output_dir = path + r"\拆分文件"  # 输出文件夹
os.makedirs(output_dir,exist_ok=True)split_pdf_every_2_pages(input_pdf, output_dir)

顺利实现两页一份PDF

但是我还希望提取姓名、年级、班级号,作为文件名。

经过反复测试后,我发现姓名固定在第6行,年级固定在第7行,但是班级号的位置是不确定,可能在68,69和某些不确定的行上。

deepseek晚上总是容易断网,所以改用了星火讯飞写

代码展示:

'''
屈光PDF按照2张一份,拆分成多个。提取单数页上的姓名(6)年级(7),班级(68、69或不确定的位置)
将大班七班改成大7班。做成文件名
deepseek 阿夏
20250527
'''import fitz  # PyMuPDF
import os
import re
import pandas as pd  # 确保已安装pandas库
from PyPDF2 import PdfReader, PdfWriterdef chinese_to_digit(chinese_num):"""将中文数字转换为阿拉伯数字。支持一到十的转换。"""chinese_dict = {'一': 1, '二': 2, '三': 3, '四': 4,'五': 5, '六': 6, '七': 7, '八': 8, '九': 9, '十': 10}return chinese_dict.get(chinese_num, chinese_num)def extract_student_info(input_pdf_path, target_pages):"""动态提取学生姓名、年级和班级信息。:param input_pdf_path: PDF文件路径:param target_pages: 需要处理的页面列表(例如,单数页):return: 包含学生信息的字典列表"""doc = fitz.open(input_pdf_path)results = []# 定义匹配“X班”的正则表达式,X为阿拉伯数字或中文数字,可能带括号class_pattern = re.compile(r'[((]?(\d+|[一二三四五六七八九十]+)班[))]?')  # 根据实际格式调整括号和数字类型for page_num in target_pages:page = doc.load_page(page_num - 1)  # fitz的页码从0开始text = page.get_text("text")lines = [line.strip() for line in text.split('\n') if line.strip()]# 初始化变量name = Nonegrade = Noneclasses = []# 从第6行和第7行提取姓名和年级if len(lines) >= 6:name = lines[5].strip()  # 第6行(索引5)if len(lines) >= 7:grade = lines[6].strip()  # 第7行(索引6)# 遍历所有行查找班级信息for line in lines:matches = class_pattern.findall(line)for match in matches:# 将中文数字转换为阿拉伯数字converted_match = ''.join([str(chinese_to_digit(char)) if char in '一二三四五六七八九十' else char for char in match])class_name = converted_match  # match 已经是字符串,无需调用 group()if class_name not in classes:classes.append(class_name)# 将提取的信息添加到结果中if name and grade:result = {"page_num": page_num,"name": name,"grade": grade[0],"class": classes}results.append(result)else:print(f"第{page_num}页缺少必要的信息。")return resultsdef convert_students_info(students):"""将学生信息转换为 "大7班_陈宇阳" 格式的字符串列表。:param students: 包含学生信息的字典列表:return: 格式化后的字符串列表"""formatted_list = []for student in students:grade = student.get('grade', '')class_list = student.get('class', [])name = student.get('name', '')class_str = ''.join(class_list)formatted_str = f"{grade}{class_str}班_{name}"formatted_list.append(formatted_str)return formatted_listdef split_pdf_every_2_pages(input_pdf_path, output_folder, formatted_names):"""将PDF每两页分割成一个新的PDF文件,并使用formatted_names列表中的名称命名文件。:param input_pdf_path: 输入PDF文件路径:param output_folder: 输出文件夹路径:param formatted_names: 用于命名的文件名列表:return: None"""# 创建输出文件夹(如果不存在)if not os.path.exists(output_folder):os.makedirs(output_folder)# 读取PDF文件reader = PdfReader(input_pdf_path)total_pages = len(reader.pages)print(f"总页数: {total_pages}")# 计算需要分割的文件数量num_files = (total_pages + 1) // 2print(f"需要创建的文件数量: {num_files}")# 确保formatted_names的长度足够if len(formatted_names) < num_files:print("警告: formatted_names列表长度小于需要创建的文件数量。多余的文件将使用默认命名。")for i in range(num_files):writer = PdfWriter()# 计算当前文件的起始和结束页码start_page = i * 2end_page = min(start_page + 2, total_pages)# 添加页面到新PDFfor page_num in range(start_page, end_page):writer.add_page(reader.pages[page_num])# 获取对应的文件名,如果不足则使用默认命名if i < len(formatted_names):filename = f"{formatted_names[i]}.pdf"else:filename = f"{i+1:003}_P{start_page+1}-P{end_page}.pdf"# 生成输出文件路径output_filename = os.path.join(output_folder, filename)# 写入新PDF文件with open(output_filename, "wb") as out:writer.write(out)print(f"已创建: {output_filename}")def main():# 设置PDF文件路径path = r'C:\Users\jg2yXRZ\OneDrive\桌面\20250527视力复诊屈光拆分'input_pdf = os.path.join(path, "复诊通知XXXX.pdf")output_dir = os.path.join(path, "拆分文件")  # 输出文件夹os.makedirs(output_dir, exist_ok=True)# 获取所有单数页(假设页码从1开始)doc = fitz.open(input_pdf)all_pages = list(range(1, len(doc) + 1))odd_pages = [p for p in all_pages if p % 2 != 0]print(f"处理的单数页: {odd_pages}")# 提取内容students_info = extract_student_info(input_pdf, odd_pages)print(f"提取到的学生信息数量: {len(students_info)}")# 转换并打印格式化后的列表formatted_list = convert_students_info(students_info)print("格式化后的学生列表:")for item in formatted_list:print(item)# 分割PDF并使用formatted_list命名文件split_pdf_every_2_pages(input_pdf, output_dir, formatted_list)print("PDF分割完成。")if __name__ == "__main__":main()

结果展示

感觉必须添加序号(数据编码)

'''
屈光PDF按照2张一份,拆分成多个。提取单数页上的姓名(6)年级(7),班级(68、69或不确定的位置)
将大班七班改成大7班。做成文件名、有编号(先中班、再大班)
deepseek 阿夏
20250527
'''# 导入必要的依赖项
import os
from fpdf import FPDF
import re
import pandas as pd  # 确保已安装pandas库
from PyPDF2 import PdfReader, PdfWriter
import fitz  # PyMuPDFdef chinese_to_digit(chinese_num):"""将中文数字转换为阿拉伯数字。支持一到十的转换。"""chinese_dict = {'一': 1, '二': 2, '三': 3, '四': 4,'五': 5, '六': 6, '七': 7, '八': 8, '九': 9, '十': 10}return chinese_dict.get(chinese_num, chinese_num)def extract_student_info(input_pdf_path, target_pages):"""动态提取学生姓名、年级和班级信息。:param input_pdf_path: PDF文件路径:param target_pages: 需要处理的页面列表(例如,单数页):return: 包含学生信息的字典列表"""doc = fitz.open(input_pdf_path)results = []# 定义匹配“X班”的正则表达式,X为阿拉伯数字或中文数字,可能带括号class_pattern = re.compile(r'[((]?(\d+|[一二三四五六七八九十]+)班[))]?')  # 根据实际格式调整括号和数字类型for page_num in target_pages:page = doc.load_page(page_num - 1)  # fitz的页码从0开始text = page.get_text("text")lines = [line.strip() for line in text.split('\n') if line.strip()]# 初始化变量name = Nonegrade = Noneclasses = []# 从第6行和第7行提取姓名和年级if len(lines) >= 6:name = lines[5].strip()  # 第6行(索引5)if len(lines) >= 7:grade = lines[6].strip()  # 第7行(索引6)# 遍历所有行查找班级信息for line in lines:matches = class_pattern.findall(line)for match in matches:# 将中文数字转换为阿拉伯数字converted_match = ''.join([str(chinese_to_digit(char)) if char in '一二三四五六七八九十' else char for char in match])class_name = converted_match  # match 已经是字符串,无需调用 group()if class_name not in classes:classes.append(class_name)# 将提取的信息添加到结果中if name and grade:result = {"page_num": page_num,"name": name,"grade": grade[0],"class": classes}results.append(result)else:print(f"第{page_num}页缺少必要的信息。")return resultsdef convert_students_info(students):"""将学生信息转换为 "大7班_陈宇阳" 格式的字符串列表。:param students: 包含学生信息的字典列表:return: 格式化后的字符串列表"""formatted_list = []for student in students:grade = student.get('grade', '')class_list = student.get('class', [])name = student.get('name', '')class_str = ''.join(class_list)formatted_str = f"{grade}{class_str}班_{name}"formatted_list.append(formatted_str)return formatted_listdef split_pdf_every_2_pages(input_pdf_path, output_folder, formatted_names):"""将PDF每两页分割成一个新的PDF文件,并使用formatted_names列表中的名称命名文件。同时在文件名前添加三位数的序号前缀。:param input_pdf_path: 输入PDF文件路径:param output_folder: 输出文件夹路径:param formatted_names: 用于命名的文件名列表:return: None"""# 创建输出文件夹(如果不存在)if not os.path.exists(output_folder):os.makedirs(output_folder)# 读取PDF文件reader = PdfReader(input_pdf_path)total_pages = len(reader.pages)print(f"总页数: {total_pages}")# 计算需要分割的文件数量num_files = (total_pages + 1) // 2print(f"需要创建的文件数量: {num_files}")# 确保formatted_names的长度足够if len(formatted_names) < num_files:print("警告: formatted_names列表长度小于需要创建的文件数量。多余的文件将使用默认命名。")for i in range(num_files):writer = PdfWriter()# 计算当前文件的起始和结束页码start_page = i * 2end_page = min(start_page + 2, total_pages)# 添加页面到新PDFfor page_num in range(start_page, end_page):writer.add_page(reader.pages[page_num])# 获取对应的文件名,如果不足则使用默认命名if i < len(formatted_names):base_filename = formatted_names[i]else:base_filename = f"P{start_page+1}-P{end_page}"# 添加三位数的序号前缀numbered_filename = f"{i+1:03}_{base_filename}_202505屈光复查通知.pdf"# 生成输出文件路径output_filename = os.path.join(output_folder, numbered_filename)# 写入新PDF文件with open(output_filename, "wb") as out:writer.write(out)print(f"已创建: {output_filename}")def main():# 设置PDF文件路径path = r'C:\Users\jg2yXRZ\OneDrive\桌面\20250527视力复诊屈光拆分'input_pdf = os.path.join(path, "复诊通知XXXX.pdf")output_dir = os.path.join(path, "拆分文件")  # 输出文件夹os.makedirs(output_dir, exist_ok=True)# 获取所有单数页(假设页码从1开始)doc = fitz.open(input_pdf)all_pages = list(range(1, len(doc) + 1))odd_pages = [p for p in all_pages if p % 2 != 0]print(f"处理的单数页: {odd_pages}")# 提取内容students_info = extract_student_info(input_pdf, odd_pages)print(f"提取到的学生信息数量: {len(students_info)}")# 转换并打印格式化后的列表formatted_list = convert_students_info(students_info)print("格式化后的学生列表:")for item in formatted_list:print(item)# 分割PDF并使用formatted_list命名文件,同时在文件名前添加序号前缀split_pdf_every_2_pages(input_pdf, output_dir, formatted_list)print("PDF分割完成。")if __name__ == "__main__":main()

按照先中班、后大班的顺序

为了明确文件内容,再添加了一个说明

最后是把所有PDF按班级合并文件夹,打包

'''
屈光PDF按照2张一份,拆分成多个。提取单数页上的姓名(6)年级(7),班级(68、69或不确定的位置)
将大班七班改成大7班。做成文件名、有编号(先中班、再大班)、
按班级分别保存,并打包,便于发送
deepseek 阿夏
20250527
'''
、import os
import re
import shutil
import zipfile
from PyPDF2 import PdfReader, PdfWriter
import fitz  # PyMuPDFdef chinese_to_digit(chinese_num):"""将中文数字转换为阿拉伯数字。支持一到十的转换。"""chinese_dict = {'一': 1, '二': 2, '三': 3, '四': 4,'五': 5, '六': 6, '七': 7, '八': 8, '九': 9, '十': 10}return chinese_dict.get(chinese_num, chinese_num)def extract_student_info(input_pdf_path, target_pages):"""从PDF中提取学生信息(姓名、年级、班级)"""doc = fitz.open(input_pdf_path)results = []class_pattern = re.compile(r'[((]?(\d+|[一二三四五六七八九十]+)班[))]?')for page_num in target_pages:page = doc.load_page(page_num - 1)text = page.get_text("text")lines = [line.strip() for line in text.split('\n') if line.strip()]name = lines[5].strip() if len(lines) >= 6 else Nonegrade = lines[6].strip() if len(lines) >= 7 else Noneclasses = []for line in lines:matches = class_pattern.findall(line)for match in matches:converted_match = ''.join([str(chinese_to_digit(char)) if char in '一二三四五六七八九十' else char for char in match])if converted_match not in classes:classes.append(converted_match)if name and grade:results.append({"page_num": page_num,"name": name,"grade": grade[0],"class": classes})else:print(f"第{page_num}页缺少必要的信息。")return resultsdef convert_students_info(students):"""格式化学生信息为'大7班_陈宇阳'格式"""return [f"{s['grade']}{''.join(s['class'])}班_{s['name']}" for s in students]def split_pdf_every_2_pages(input_pdf_path, output_folder, formatted_names):"""将PDF每两页分割成单独文件"""if not os.path.exists(output_folder):os.makedirs(output_folder)reader = PdfReader(input_pdf_path)total_pages = len(reader.pages)num_files = (total_pages + 1) // 2for i in range(num_files):writer = PdfWriter()start_page = i * 2end_page = min(start_page + 2, total_pages)for page_num in range(start_page, end_page):writer.add_page(reader.pages[page_num])base_filename = formatted_names[i] if i < len(formatted_names) else f"P{start_page+1}-P{end_page}"output_filename = os.path.join(output_folder, f"{i+1:03}_{base_filename}_屈光复查202505.pdf")with open(output_filename, "wb") as out:writer.write(out)print(f"已创建: {output_filename}")def classify_pdfs_by_class(source_folder):"""将PDF文件按班级分类到不同文件夹"""pdf_files = [f for f in os.listdir(source_folder) if f.lower().endswith('.pdf')]if not pdf_files:print(f"在文件夹 {source_folder} 中没有找到PDF文件")returnclass_stats = {}for pdf_file in pdf_files:match = re.search(r'(中\d+班|大\d+班)', pdf_file)if match:class_name = match.group(1)class_folder = os.path.join(source_folder, class_name)os.makedirs(class_folder, exist_ok=True)src_path = os.path.join(source_folder, pdf_file)dest_path = os.path.join(class_folder, pdf_file)shutil.move(src_path, dest_path)print(f"移动文件: {pdf_file} -> {class_folder}")class_stats[class_name] = class_stats.get(class_name, 0) + 1else:print(f"无法从文件名 {pdf_file} 中提取班级信息")print("\n分类完成,统计结果:")for class_name, count in class_stats.items():print(f"{class_name}: {count}个文件")return class_stats.keys()def zip_class_folders(source_folder, class_folders):"""将班级文件夹打包为ZIP压缩包"""print("\n=== 开始打包班级文件夹 ===")for folder_name in class_folders:folder_path = os.path.join(source_folder, folder_name)zip_path = os.path.join(source_folder, f"{folder_name}.zip")with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:for root, dirs, files in os.walk(folder_path):for file in files:file_path = os.path.join(root, file)arcname = os.path.relpath(file_path, folder_path)zipf.write(file_path, arcname)print(f"已创建压缩包: {zip_path}")def main():# 设置路径base_path = r'C:\Users\jg2yXRZ\OneDrive\桌面\20250527视力复诊屈光拆分'input_pdf = os.path.join(base_path, "复诊通知XXXX.pdf")output_dir = os.path.join(base_path, "拆分文件")# 第一步:拆分PDFprint("=== 开始拆分PDF ===")os.makedirs(output_dir, exist_ok=True)doc = fitz.open(input_pdf)odd_pages = [p for p in range(1, len(doc) + 1) if p % 2 != 0]students_info = extract_student_info(input_pdf, odd_pages)formatted_list = convert_students_info(students_info)split_pdf_every_2_pages(input_pdf, output_dir, formatted_list)print("PDF拆分完成!\n")# 第二步:分类PDFprint("=== 开始分类PDF ===")class_folders = classify_pdfs_by_class(output_dir)print("PDF分类完成!")# 第三步:打包文件夹zip_class_folders(output_dir, class_folders)if __name__ == "__main__":main()

我看到终端显示了每个班级有几份,我还想标明文件内容是“屈光复查”

最终代码

'''
屈光PDF按照2张一份,拆分成多个。提取单数页上的姓名(6)年级(7),班级(68、69或不确定的位置)
将大班七班改成大7班。做成文件名、有编号(先中班、再大班)
按照班级转移PDF,班级文件名包括人数、屈光
deepseek 阿夏
20250527
'''import os
import re
import shutil
import zipfile
from PyPDF2 import PdfReader, PdfWriter
import fitz  # PyMuPDFdef chinese_to_digit(chinese_num):"""将中文数字转换为阿拉伯数字。支持一到十的转换。"""chinese_dict = {'一': 1, '二': 2, '三': 3, '四': 4,'五': 5, '六': 6, '七': 7, '八': 8, '九': 9, '十': 10}return chinese_dict.get(chinese_num, chinese_num)def extract_student_info(input_pdf_path, target_pages):"""从PDF中提取学生信息(姓名、年级、班级)"""doc = fitz.open(input_pdf_path)results = []class_pattern = re.compile(r'[((]?(\d+|[一二三四五六七八九十]+)班[))]?')for page_num in target_pages:page = doc.load_page(page_num - 1)text = page.get_text("text")lines = [line.strip() for line in text.split('\n') if line.strip()]name = lines[5].strip() if len(lines) >= 6 else Nonegrade = lines[6].strip() if len(lines) >= 7 else Noneclasses = []for line in lines:matches = class_pattern.findall(line)for match in matches:converted_match = ''.join([str(chinese_to_digit(char)) if char in '一二三四五六七八九十' else char for char in match])if converted_match not in classes:classes.append(converted_match)if name and grade:results.append({"page_num": page_num,"name": name,"grade": grade[0],"class": classes})else:print(f"第{page_num}页缺少必要的信息。")return resultsdef convert_students_info(students):"""格式化学生信息为'大7班_陈宇阳'格式"""return [f"{s['grade']}{''.join(s['class'])}班_{s['name']}" for s in students]def split_pdf_every_2_pages(input_pdf_path, output_folder, formatted_names):"""将PDF每两页分割成单独文件"""if not os.path.exists(output_folder):os.makedirs(output_folder)reader = PdfReader(input_pdf_path)total_pages = len(reader.pages)num_files = (total_pages + 1) // 2for i in range(num_files):writer = PdfWriter()start_page = i * 2end_page = min(start_page + 2, total_pages)for page_num in range(start_page, end_page):writer.add_page(reader.pages[page_num])base_filename = formatted_names[i] if i < len(formatted_names) else f"P{start_page+1}-P{end_page}"output_filename = os.path.join(output_folder, f"{i+1:03}_{base_filename}_屈光复查202505.pdf")with open(output_filename, "wb") as out:writer.write(out)print(f"已创建: {output_filename}")def classify_pdfs_by_class(source_folder):"""将PDF文件按班级分类到不同文件夹,并在文件夹名中加入人数统计"""pdf_files = [f for f in os.listdir(source_folder) if f.lower().endswith('.pdf')]if not pdf_files:print(f"在文件夹 {source_folder} 中没有找到PDF文件")returnclass_stats = {}# 第一次遍历:统计每个班级的人数for pdf_file in pdf_files:match = re.search(r'(中\d+班|大\d+班)', pdf_file)if match:class_name = match.group(1)class_stats[class_name] = class_stats.get(class_name, 0) + 1# 第二次遍历:移动文件到带人数的文件夹for pdf_file in pdf_files:match = re.search(r'(中\d+班|大\d+班)', pdf_file)if match:class_name = match.group(1)count = class_stats[class_name]new_folder_name = f"{class_name}_{count}人_屈光复查202505"class_folder = os.path.join(source_folder, new_folder_name)os.makedirs(class_folder, exist_ok=True)src_path = os.path.join(source_folder, pdf_file)dest_path = os.path.join(class_folder, pdf_file)shutil.move(src_path, dest_path)print(f"移动文件: {pdf_file} -> {new_folder_name}")print("\n分类完成,统计结果:")for class_name, count in class_stats.items():print(f"{class_name}: {count}个文件")# 返回带人数的文件夹名列表return [f"{k}({v}人)" for k, v in class_stats.items()]def zip_class_folders(source_folder, class_folders):"""将班级文件夹打包为ZIP压缩包"""print("\n=== 开始打包班级文件夹 ===")for folder_name in class_folders:folder_path = os.path.join(source_folder, folder_name)zip_path = os.path.join(source_folder, f"{folder_name}_屈光复查202505.zip")with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:for root, dirs, files in os.walk(folder_path):for file in files:file_path = os.path.join(root, file)arcname = os.path.relpath(file_path, folder_path)zipf.write(file_path, arcname)print(f"已创建压缩包: {zip_path}")def main():# 设置路径base_path = r'C:\Users\jg2yXRZ\OneDrive\桌面\20250527视力复诊屈光拆分'input_pdf = os.path.join(base_path, "复诊通知XXXX.pdf")output_dir = os.path.join(base_path, "拆分文件")# 第一步:拆分PDFprint("=== 开始拆分PDF ===")os.makedirs(output_dir, exist_ok=True)doc = fitz.open(input_pdf)odd_pages = [p for p in range(1, len(doc) + 1) if p % 2 != 0]students_info = extract_student_info(input_pdf, odd_pages)formatted_list = convert_students_info(students_info)split_pdf_every_2_pages(input_pdf, output_dir, formatted_list)print("PDF拆分完成!\n")# 第二步:分类PDFprint("=== 开始分类PDF ===")class_folders = classify_pdfs_by_class(output_dir)print("PDF分类完成!")# 第三步:打包文件夹zip_class_folders(output_dir, class_folders)if __name__ == "__main__":main()

转发给保健老师:

20250529

本来说是社区保健所打印通知,但是今天保健老师还是群发了各班PDF名单

很开心你,代码还是用上了。

但是转发时,我发现还要解压缩好麻烦啊,就准备上电脑再操作。

不一会儿,保健老师又发了单独的PDF

但是我发现发送编号不是按顺序的,而是跳着的,而且少了010、009,还以为是保健老师判定这两个孩子不同复查。

午餐时,保健老师打电话,说

1、班主任发现:原来的rar文件是空包。

我一看打包zip真的是空的

2、我只能发送单独PDF,结果一次只能9份,你们班缺了2个人是谁?

微信一次发送文件最多9个。以那一份先发全为准,所以不是按编号展示出来的。如果数量多,倒数第一个发(先显示),前8个发,所以就是倒数第2、3个不显示(1-11,就是9和10不显示)

问deep seek为什么是空白。

更新代码

'''
屈光PDF按照2张一份,拆分成多个。提取单数页上的姓名(6)年级(7),班级(68、69或不确定的位置)
将大班七班改成大7班。做成文件名、有编号(先中班、再大班)
按照班级转移PDF,班级文件名包括人数、屈光
deepseek 阿夏
20250527
'''import os
import re
import shutil
import zipfile
from PyPDF2 import PdfReader, PdfWriter
import fitz  # PyMuPDFdef chinese_to_digit(chinese_num):"""将中文数字转换为阿拉伯数字。支持一到十的转换。"""chinese_dict = {'一': 1, '二': 2, '三': 3, '四': 4,'五': 5, '六': 6, '七': 7, '八': 8, '九': 9, '十': 10}return chinese_dict.get(chinese_num, chinese_num)def extract_student_info(input_pdf_path, target_pages):"""从PDF中提取学生信息(姓名、年级、班级)"""doc = fitz.open(input_pdf_path)results = []class_pattern = re.compile(r'[((]?(\d+|[一二三四五六七八九十]+)班[))]?')for page_num in target_pages:page = doc.load_page(page_num - 1)text = page.get_text("text")lines = [line.strip() for line in text.split('\n') if line.strip()]name = lines[5].strip() if len(lines) >= 6 else Nonegrade = lines[6].strip() if len(lines) >= 7 else Noneclasses = []for line in lines:matches = class_pattern.findall(line)for match in matches:converted_match = ''.join([str(chinese_to_digit(char)) if char in '一二三四五六七八九十' else char for char in match])if converted_match not in classes:classes.append(converted_match)if name and grade:results.append({"page_num": page_num,"name": name,"grade": grade[0],"class": classes})else:print(f"第{page_num}页缺少必要的信息。")return resultsdef convert_students_info(students):"""格式化学生信息为'大7班_陈宇阳'格式"""return [f"{s['grade']}{''.join(s['class'])}班_{s['name']}" for s in students]def split_pdf_every_2_pages(input_pdf_path, output_folder, formatted_names):"""将PDF每两页分割成单独文件"""if not os.path.exists(output_folder):os.makedirs(output_folder)reader = PdfReader(input_pdf_path)total_pages = len(reader.pages)num_files = (total_pages + 1) // 2for i in range(num_files):writer = PdfWriter()start_page = i * 2end_page = min(start_page + 2, total_pages)for page_num in range(start_page, end_page):writer.add_page(reader.pages[page_num])base_filename = formatted_names[i] if i < len(formatted_names) else f"P{start_page+1}-P{end_page}"output_filename = os.path.join(output_folder, f"{i+1:03}_{base_filename}_屈光复查202505.pdf")with open(output_filename, "wb") as out:writer.write(out)print(f"已创建: {output_filename}")def classify_pdfs_by_class(source_folder):"""将PDF文件按班级分类到不同文件夹,并在文件夹名中加入人数统计"""pdf_files = [f for f in os.listdir(source_folder) if f.lower().endswith('.pdf')]if not pdf_files:print(f"在文件夹 {source_folder} 中没有找到PDF文件")return []class_stats = {}# 第一次遍历:统计每个班级的人数for pdf_file in pdf_files:match = re.search(r'(中\d+班|大\d+班)', pdf_file)if match:class_name = match.group(1)class_stats[class_name] = class_stats.get(class_name, 0) + 1# 第二次遍历:移动文件到带人数的文件夹created_folders = []for pdf_file in pdf_files:match = re.search(r'(中\d+班|大\d+班)', pdf_file)if match:class_name = match.group(1)count = class_stats[class_name]new_folder_name = f"{class_name}_{count:02}人_屈光复查202505"class_folder = os.path.join(source_folder, new_folder_name)if new_folder_name not in created_folders:os.makedirs(class_folder, exist_ok=True)created_folders.append(new_folder_name)src_path = os.path.join(source_folder, pdf_file)dest_path = os.path.join(class_folder, pdf_file)shutil.move(src_path, dest_path)print(f"移动文件: {pdf_file} -> {new_folder_name}")print("\n分类完成,统计结果:")for class_name, count in class_stats.items():print(f"{class_name}: {count}个文件")# 返回实际创建的文件夹路径列表return [os.path.join(source_folder, f"{k}_{v:02}人_屈光复查202505") for k, v in class_stats.items()]def zip_class_folders(source_folder, class_folders):"""将班级文件夹打包为ZIP压缩包"""print("\n=== 开始打包班级文件夹 ===")for folder_path in class_folders:folder_name = os.path.basename(folder_path)zip_path = os.path.join(source_folder, f"{folder_name}.zip")with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:for root, dirs, files in os.walk(folder_path):for file in files:file_path = os.path.join(root, file)arcname = os.path.relpath(file_path, folder_path)zipf.write(file_path, arcname)print(f"已创建压缩包: {zip_path}")def main():# 设置路径base_path = r'C:\Users\jg2yXRZ\OneDrive\桌面\20250527视力复诊屈光拆分'input_pdf = os.path.join(base_path, "复诊通知景谷二幼.pdf")output_dir = os.path.join(base_path, "03打包发给班主任")# 第一步:拆分PDFprint("=== 开始拆分PDF ===")os.makedirs(output_dir, exist_ok=True)doc = fitz.open(input_pdf)odd_pages = [p for p in range(1, len(doc) + 1) if p % 2 != 0]students_info = extract_student_info(input_pdf, odd_pages)formatted_list = convert_students_info(students_info)split_pdf_every_2_pages(input_pdf, output_dir, formatted_list)print("PDF拆分完成!\n")# 第二步:分类PDFprint("=== 开始分类PDF ===")class_folders = classify_pdfs_by_class(output_dir)print("PDF分类完成!")# 第三步:打包文件夹zip_class_folders(output_dir, class_folders)if __name__ == "__main__":main()

结果:打包文件有大小了

虽然打包发送每条PDF都有,更方便更完整

但是老师可能更喜欢单独PDF,便于转发。

可是保健老师转发又涉及一次只能9条。真是头疼。


http://www.hkcw.cn/article/fbUBgEigwJ.shtml

相关文章

yolov8添加注意力机制

在 YOLOv8 中添加注意力机制可以显著提升模型对关键特征的关注能力&#xff0c;从而提高检测精度。以下是几种主流注意力机制的实现方法和集成策略&#xff1a; 1. 注意力机制选择 根据计算效率和效果&#xff0c;推荐以下几种注意力模块&#xff1a; CBAM&#xff1a;同时关…

SpringBatch+Mysql+hanlp简版智能搜索

资源条件有限&#xff0c;需要支持智搜的数据量也不大&#xff0c;上es搜索有点大材小用了&#xff0c;只好写个简版mysql的智搜&#xff0c;处理全文搜素&#xff0c;支持拼音搜索&#xff0c;中文分词&#xff0c;自定义分词断词&#xff0c;地图范围搜索&#xff0c;周边搜索…

林峯堂妹回应破产传闻 豪门生活背后的真相

谁能想到,前几天还拎着爱马仕、坐着商务舱看演唱会的TVB视后林夏薇,突然就被申请破产了?这剧情反转得比港剧还刺激。根据法院文件,一家公司向香港高院申请她破产,案子8月才开庭。最让人震惊的是,她家住山顶15亿豪宅,老公还是金融才俊,怎么突然就沦落到这步?就在破产消…

摩根大通CEO:美最大威胁是内部敌人 警惕自我挑战

摩根大通首席执行官杰米戴蒙在加州的一场经济论坛上表示,美国真正应该担心的不是中国,而是自己。他认为美国应警惕“内部的敌人”。尽管他承认中国是一个潜在对手,但指出中国在许多方面做得很好。他质疑美国能否在行动、价值观、能力和管理方面齐心协力。戴蒙还警告称中美间…

加征关税后 美国政府又输一局 法院裁定不合法

美国政府在今年4月2日以“美国利益优先”为由,对全球超过180个国家和地区加征的所谓“解放日”关税,最近被美国国际贸易法院裁决为不合法。此外,该法院还裁定美国政府以芬太尼等问题危害国家安全为由对中国、加拿大和墨西哥加征的关税也不合法。从公布的裁决书来看,美国政府…

温广南获评“百千万工程”突出个人 乡村振兴领路人

5月29日,2025年省委农村工作会议暨深入实施“百县千镇万村高质量发展工程”推进会召开。会上通报了在推进“百千万工程”工作中表现突出的集体和个人名单,200个单位、200人获通报表扬。南沙区港湾街道芦湾村党总支书记、村委会主任温广南榜上有名。芦湾村入选第二批典型村培育…

山东郓城落水事故情况通报 5死2危重

5月30日12时30分许,郓城县一家废品回收企业的员工在废旧塑料清洗池边作业时不慎跌入池中。六名工友见状先后施救,但相继跌入池中。事故发生后,当地消防部门和急救人员迅速赶到现场,将七人紧急送往医院抢救。截至目前,事故已造成五人死亡,两人情况危重。菏泽市和郓城县对此…

王楚钦:奥运会后很难熬 想过放弃 奥运挫折后的蜕变之路

5月30日,央视发布了《面对面王楚钦蜕变之路》的节目预告。在预告中,王楚钦谈到了巴黎奥运会后的坎坷心路。他提到,奥运会之后的三个月非常难熬,曾有过无数放弃的念头。他对奥运会上的表现感到不满,认为自己在32强时输掉了外战,一直在追问为什么奥林匹克历史上没有发生的事…

王楚钦自曝上厕所都有固定坑位 球拍风波后的心理蜕变

在央视即将播出的专访节目《面对面:王楚钦的蜕变之路》预告片中,国乒主力王楚钦首次公开谈及多哈世乒赛球拍受损事件,并以幽默方式回应两次球拍风波背后的心理挑战。他表示:“我连上厕所都要选固定坑位。”这种习惯一度让王楚钦难以接受突发变化,但巴黎奥运会上的“球拍被…

随机选择法找出重复N次的元素

思路与算法 我们可以每次随机选择两个不同的下标&#xff0c;判断它们对应的元素是否相等即可。如果相等&#xff0c;那么返回任意一个作为答案。 代码 C Java 复杂度分析 时间复杂度&#xff1a;期望 O(1) 。选择两个相同元素的概率为 n/2n*(n-1)/2n≈1/4 &#xff0c;因此…

改进自己的图片 app

1. 起因&#xff0c; 目的: 前面我写过一个图片 app &#xff0c; 最新做了些改动。 把原来的一列&#xff0c;改为3列&#xff0c; 继续使用瀑布流手机上使用&#xff0c;更流程&#xff0c;而且横屏可以显示2列。 2. 先看效果 3. 过程: 过程太细碎了&#xff0c;这里只是…

MODIS火点数据下载

可能有的链接需要科学上网如果用了VPN还是打不开就直接按照文字来进行搜索 MODIS常用火点数据主要分成Active Fire和Burned Area两大类。 MODIS简介&#xff1a;MODIS | NASA Earthdata 一、大类区分 首先&#xff0c;需要简单了解一下两者的区别&#xff0c;从而做出第一步…

无缝转换!冶金级DEVICENET转EtherCAT网关,稳定可靠扛得住!

在冶金行业智能化转型过程中&#xff0c;设备通信协议的升级与兼容成为关键挑战。由于历史原因&#xff0c;大量冶金工厂仍在使用传统的DEVICENET总线设备&#xff08;如传感器、电机驱动器、I/O模块等&#xff09;&#xff0c;而新兴的工业机器人和高精度控制设备普遍采用ETHE…

Linux多线程(六)之线程控制4【线程ID及进程地址空间布局】

文章目录 线程ID及进程地址空间布局线程局部存储 线程ID及进程地址空间布局 pthread_ create函数会产生一个线程ID&#xff0c;存放在第一个参数指向的地址中。 该线程ID和前面说的线程ID不是一回事。 前面讲的线程ID属于进程调度的范畴。 ​ 因为线程是轻量级进程&#xff…

美政府终止一项艾滋病疫苗研发项目 抗击艾滋病努力受挫

特朗普政府终止了一项2.58亿美元的项目,对艾滋病疫苗研发工作造成了沉重打击。一位不愿透露姓名且未经授权发言的高级官员表示,美国国立卫生研究院计划将关注点转向利用现有方法消除艾滋病,并暂停了莫德纳公司研发的一项艾滋病疫苗临床试验。公共卫生专家指出,这些削减措施…

俄称击落千余架乌军无人机 俄军攻势持续

5月30日,俄罗斯国防部发布战报称,在过去一周里,俄军对乌克兰境内的国防工业设施、军用机场基础设施、武器弹药储存设施等目标实施了打击。在苏梅、哈尔科夫、顿涅茨克等地,俄军打退了乌军多次进攻并发动攻势。俄防空部队击落了1439架固定翼无人机,并控制了苏梅、哈尔科夫、…

于正称大师算出横店爆剧为《藏海传》 热度断层登顶破纪录

于正曾透露,他找大师算出的横店爆剧是《藏海传》。他在文中提到,大师通过塔罗牌预测,爆剧会与5、7、9这三个数字有关。而肖战恰好是5号出生,姓氏“肖”有7画,名字“战”有9画,这似乎正好对应了《藏海传》。《藏海传》自上线以来,热度迅速攀升,仅38小时就打破了站内热度…

上交解锁遥感图像中的空间理解能力!AirSpatialBot:面向细粒度车辆属性识别与检索的空间感知空中智能体

作者&#xff1a;Yue Zhou 1 ^{1} 1, Ran Ding 1 ^{1} 1, Xue Yang 2 ^{2} 2, Xue Jiang 1 ^{1} 1, Xingzhao Liu 1 ^{1} 1单位&#xff1a; 1 ^{1} 1上海交通大学电子工程系&#xff0c; 2 ^{2} 2上海交通大学自动化系论文标题&#xff1a;AirSpatialBot: A Spatially-Aware A…

dvwa3——CSRF

LOW&#xff1a; 先尝试change一组密码&#xff1a;123456 修改成功&#xff0c;我们观察上面的url代码 http://localhost/DVWA/vulnerabilities/csrf/?password_new123456&password_conf123456&ChangeChange# 将password_new部分与password_conf部分改成我们想要的…

论坛系统(4)

用户详情 获取用户信息 实现逻辑 ⽤⼾提交请求&#xff0c;服务器根据是否传⼊Id参数决定返回哪个⽤⼾的详情 1. 不传⽤⼾Id&#xff0c;返回当前登录⽤⼾的详情(从session获取) 2. 传⼊⽤⼾Id&#xff0c;返回指定Id的⽤⼾详情(根据用户id去查) 俩种方式获得用户信息 参…