办公类-115-0120250920职称资料上传01多个jpg转同名PDF如荣誉证书并自动生成单一文件夹
目录
【办公类-115-01】20250920职称资料上传01——多个jpg转同名PDF(如:荣誉证书)并自动生成单一文件夹
背景需求:
20250920上海市中高职称评审开始,我在2023年申请课题鉴定C,可以有两次参评机会,2023年12月参加过一次考评。2025是第二次。
和2年前一样,在9月有一个职称上报平台的程序。
需要上传很多很多的资料
一、教师账户上传(成绩荣誉证书、个人信息文字、课程表文字)
二、管理园账户(人事档案图片扫描盖章资料上传)
两年前做这个系统上传,里面最大的工作量就是把各种类型的资料转成PDF。足足搞了两周,天天晚上做到9点。
当时我用的是ADOBE AcTOBAT 做的“单张图片转PDF”、“多张图片合并PDF”“多个PDF转PDF”、
用word做的docx转PDF
当图片太大,PDF超过5MB或1.5MB,还要用格式工厂压缩图片。在把小图放到ADOBE AcTOBAT 继续合并PDF
特别“结题报告”,要分别把docx转PDF,把图片合并PDF,再把多个合并成一个PDF。ADOBE AcTOBAT 要操作很多次合并。
加上总之非常繁琐、繁杂、烦躁。
操作流程
今年再次做这个系统,我就想能不能用AI写Python代码,直接实现
1、单张图片转PDF(单张荣誉证书jpg转PDF)
2、多个图片合并PDF(五张教师考评表jpg合并一个PDF)
3、多个PDF合并(十三五证书下载就是PDF)
4、其他综合类文件拼PDF(PDF+图片=PDF、word+图片+PDF=PDF)
最开始整理资料,我能做的就是将各类证书、
以”奖励”为例,准备10张证书(扫描件)
根据重要性级别手动‘’编号
'''
职称01,10张证书jpg转PDF,合并同名文件夹
deepseek,阿夏
20250920
'''
import os
import img2pdf
from PIL import Image
from pathlib import Path
import io
def convert_each_image_to_pdf(folder_path):
"""
将文件夹中的每张图片分别转换为同名的PDF文件
Args:
folder_path (str): 图片文件夹路径
"""
# 支持的图片格式
supported_formats = ('.png', '.jpg', '.jpeg', '.bmp', '.tiff', '.tif', '.webp')
# 获取所有图片文件
image_files = []
for file in Path(folder_path).iterdir():
if file.suffix.lower() in supported_formats and file.is_file():
image_files.append(file)
if not image_files:
print("未找到图片文件!")
return
print(f"找到 {len(image_files)} 张图片")
# 处理每张图片
success_count = 0
for img_path in image_files:
try:
# 生成输出PDF文件名(保持原名,只改扩展名)
output_pdf_name = img_path.with_suffix('.pdf')
# 检查是否已存在同名PDF文件
if output_pdf_name.exists():
print(f"跳过 {img_path.name},PDF文件已存在: {output_pdf_name.name}")
continue
# 处理图片方向
with Image.open(img_path) as img:
# 转换为RGB模式(避免透明度问题)
if img.mode != 'RGB':
img = img.convert('RGB')
# 获取图片尺寸
width, height = img.size
# 判断横竖版:宽度大于高度则为横版
if width > height:
# 横版图片,旋转90度使其在PDF中正确显示
rotated_img = img.rotate(90, expand=True)
# 保存为临时文件
temp_path = f"temp_{img_path.stem}.jpg"
rotated_img.save(temp_path, "JPEG", quality=95)
# 转换为PDF
with open(output_pdf_name, "wb") as f:
f.write(img2pdf.convert(temp_path))
# 删除临时文件
os.remove(temp_path)
else:
# 竖版图片,直接转换
with open(output_pdf_name, "wb") as f:
f.write(img2pdf.convert(str(img_path)))
success_count += 1
print(f"已转换: {img_path.name} -> {output_pdf_name.name}")
except Exception as e:
print(f"转换图片 {img_path.name} 时出错: {e}")
print(f"转换完成!成功转换 {success_count} 张图片")
def convert_each_image_to_pdf_simple(folder_path):
"""
简化版本:直接将每张图片转换为PDF,不处理横竖版
"""
# 支持的图片格式
supported_formats = ('.png', '.jpg', '.jpeg', '.bmp', '.tiff', '.tif', '.webp')
# 获取所有图片文件
image_files = []
for file in Path(folder_path).iterdir():
if file.suffix.lower() in supported_formats and file.is_file():
image_files.append(file)
if not image_files:
print("未找到图片文件!")
return
print(f"找到 {len(image_files)} 张图片")
# 处理每张图片
success_count = 0
for img_path in image_files:
try:
# 生成输出PDF文件名
output_pdf_name = img_path.with_suffix('.pdf')
# 检查是否已存在同名PDF文件
if output_pdf_name.exists():
print(f"跳过 {img_path.name},PDF文件已存在: {output_pdf_name.name}")
continue
# 直接转换为PDF
with open(output_pdf_name, "wb") as f:
f.write(img2pdf.convert(str(img_path)))
success_count += 1
print(f"已转换: {img_path.name} -> {output_pdf_name.name}")
except Exception as e:
print(f"转换图片 {img_path.name} 时出错: {e}")
print(f"转换完成!成功转换 {success_count} 张图片")
if __name__ == "__main__":
# 使用示例
path = r'C:\Users\Administrator\Desktop\09奖励'
folder_path = path
print("开始转换每张图片为单独的PDF...")
# 先尝试简化版本(不处理横竖版)
print("尝试简化版本...")
convert_each_image_to_pdf_simple(folder_path)
# 检查是否还有图片未转换(可能因为横版问题转换失败)
# 获取所有图片文件
supported_formats = ('.png', '.jpg', '.jpeg', '.bmp', '.tiff', '.tif', '.webp')
remaining_images = []
for file in Path(folder_path).iterdir():
if file.suffix.lower() in supported_formats and file.is_file():
pdf_file = file.with_suffix('.pdf')
if not pdf_file.exists(): # 如果对应的PDF文件不存在
remaining_images.append(file)
if remaining_images:
print(f"还有 {len(remaining_images)} 张图片未转换,尝试完整版本...")
# 对未转换的图片使用完整版本
for img_path in remaining_images:
try:
output_pdf_name = img_path.with_suffix('.pdf')
with Image.open(img_path) as img:
if img.mode != 'RGB':
img = img.convert('RGB')
width, height = img.size
if width > height:
rotated_img = img.rotate(90, expand=True)
temp_path = f"temp_{img_path.stem}.jpg"
rotated_img.save(temp_path, "JPEG", quality=95)
with open(output_pdf_name, "wb") as f:
f.write(img2pdf.convert(temp_path))
os.remove(temp_path)
else:
with open(output_pdf_name, "wb") as f:
f.write(img2pdf.convert(str(img_path)))
print(f"已转换: {img_path.name} -> {output_pdf_name.name}")
except Exception as e:
print(f"转换图片 {img_path.name} 时出错: {e}")
一个代码将每张图片转成一个同名的pdf
一开始就这样,但是上传的时候,我发现所有10个PDF和10个jpg在一起,我很容易选错PDF,要很仔细看编号。
所以我还是参考2023年的方法,把证书放到每个文件夹里,这样看编号更清晰
所以我再写一个代码同名的jpg和PDF,放到一个同名文件夹里
'''
职称01,10张证书jpg和PDF,转入同名文件夹
deepseek,阿夏
20250920
'''
import os
import shutil
from pathlib import Path
def organize_files_by_name(source_folder):
"""
将同名文件(不同后缀)整理到同名文件夹中
Args:
source_folder: 源文件夹路径
"""
source_path = Path(source_folder)
# 检查源文件夹是否存在
if not source_path.exists():
print(f"错误:文件夹 '{source_folder}' 不存在")
return
# 用于存储文件名和对应文件路径的字典
file_groups = {}
# 遍历源文件夹中的所有文件
for file_path in source_path.iterdir():
if file_path.is_file():
# 获取文件名(不含后缀)
file_stem = file_path.stem
# 获取文件后缀
file_suffix = file_path.suffix
# 将文件按文件名分组
if file_stem not in file_groups:
file_groups[file_stem] = []
file_groups[file_stem].append(file_path)
# 创建文件夹并移动文件
moved_count = 0
for file_stem, file_list in file_groups.items():
# 如果同名文件数量大于1,或者用户希望单个文件也整理
if len(file_list) > 0:
# 创建目标文件夹
target_folder = source_path / file_stem
target_folder.mkdir(exist_ok=True)
# 移动文件到目标文件夹
for file_path in file_list:
target_path = target_folder / file_path.name
shutil.move(str(file_path), str(target_path))
print(f"移动: {file_path.name} -> {file_stem}/")
moved_count += 1
print(f"\n整理完成!共移动了 {moved_count} 个文件")
def organize_files_with_preview(source_folder):
"""
带预览功能的文件整理(先显示将要进行的操作,确认后执行)
Args:
source_folder: 源文件夹路径
"""
source_path = Path(source_folder)
if not source_path.exists():
print(f"错误:文件夹 '{source_folder}' 不存在")
return
file_groups = {}
# 收集文件信息
for file_path in source_path.iterdir():
if file_path.is_file():
file_stem = file_path.stem
if file_stem not in file_groups:
file_groups[file_stem] = []
file_groups[file_stem].append(file_path)
# 显示预览信息
print("预览将要进行的操作:")
print("=" * 50)
operations = []
for file_stem, file_list in file_groups.items():
if len(file_list) > 0:
target_folder = source_path / file_stem
operations.append({
'folder': target_folder,
'files': file_list
})
print(f"创建文件夹: {file_stem}")
for file_path in file_list:
print(f" └─ 移动: {file_path.name}")
print()
if not operations:
print("没有找到需要整理的文件")
return
# 确认是否执行
confirm = input("确认执行以上操作?(y/n): ").lower()
if confirm == 'y':
# 执行移动操作
moved_count = 0
for op in operations:
op['folder'].mkdir(exist_ok=True)
for file_path in op['files']:
target_path = op['folder'] / file_path.name
shutil.move(str(file_path), str(target_path))
moved_count += 1
print(f"\n整理完成!共移动了 {moved_count} 个文件")
else:
print("操作已取消")
def main():
# 设置源文件夹路径(这里是你的123文件夹)
source_folder = r'C:\Users\Administrator\Desktop\09奖励'
print("文件整理工具")
print("1. 直接执行")
print("2. 预览后执行")
# choice = input("请选择模式 (1/2): ")
choice = "1"
if choice == "1":
organize_files_by_name(source_folder)
elif choice == "2":
organize_files_with_preview(source_folder)
else:
print("无效选择")
if __name__ == "__main__":
main()