使用Img2Pdf时因os.scandir排序问题导致PDF图片顺序错误
修复子文件夹自然排序问题
问题根源
os.scandir()返回的目录条目是无序的,默认按系统底层存储顺序返回,而非自然数字排序,导致数字命名的子文件夹(如1、10、100)出现顺序错乱。
修改后的代码
import os import img2pdf import re from typing import List, Tuple def convert_images_to_pdf(image_paths: List[str], pdf_path: str) -> None: """ 将图片列表转换为单个PDF文件 参数: image_paths: 待转换图片的路径列表 pdf_path: 输出PDF的路径 返回: None,生成成功或报错时打印信息 """ try: with open(pdf_path, 'wb') as pdf_file: pdf_file.write(img2pdf.convert(image_paths)) print(f"PDF已成功生成: {pdf_path}") except (ValueError, FileNotFoundError) as error: print(f"生成PDF时出错: {error}") def natural_sort_key(s): """生成自然排序的键,处理带数字的字符串""" return [int(text) if text.isdigit() else text.lower() for text in re.split('([0-9]+)', s)] def create_folder_pdf(folder_path: str) -> None: """ 将指定文件夹下所有子文件夹的JPEG图片转换为对应PDF 参数: folder_path: 包含图片的根文件夹路径 返回: None,无图片或出错时打印信息 """ try: # 读取子文件夹并按自然顺序排序 with os.scandir(folder_path) as folder_iterator: subfolders = sorted([item for item in folder_iterator if item.is_dir()], key=lambda x: natural_sort_key(x.name)) for item in subfolders: subfolder_name = item.name subfolder_path = os.path.join(folder_path, subfolder_name) image_paths = [] # 读取子文件夹内的图片并按自然顺序排序 with os.scandir(subfolder_path) as file_iterator: image_files = sorted([file for file in file_iterator if file.name.lower().endswith(('.jpeg', '.jpg'))], key=lambda x: natural_sort_key(x.name)) image_paths = [file.path for file in image_files] if image_paths: pdf_path = os.path.join(subfolder_path, f'{subfolder_name}.pdf') convert_images_to_pdf(image_paths, pdf_path) else: print(f"{subfolder_name}中未找到JPEG文件!") except OSError as error: print(f"打开文件夹出错: {folder_path}, 错误信息: {error}") return if __name__ == "__main__": folder_path = input("请输入包含JPEG图片的文件夹路径: ") if not os.path.exists(folder_path): print(f"路径不存在: {folder_path}") else: create_folder_pdf(folder_path)
关键修改说明
- 新增
natural_sort_key函数:通过正则拆分字符串中的数字与非数字部分,将数字转为整数后参与排序,实现自然排序逻辑(比如1<2<10<100) - 子文件夹排序:从根目录读取子文件夹后,用
natural_sort_key作为排序键,确保章节顺序符合预期 - 图片排序优化:子文件夹内的图片也使用自然排序,避免类似
001-10排在001-2前面的问题
补充说明
你提到的PNG转JPEG操作是合理的,截断的PNG在JPEG格式下容错性更强,不会影响后续PDF生成流程。
内容的提问来源于stack exchange,提问作者Matt Bone
相关产品推荐
相关产品推荐

