PyPDF2按文件夹批量合并PDF时仅合并最后一个PDF的问题
问题原因
- 合并逻辑执行顺序错误:代码在每复制1个PDF到分类文件夹时,就新建一个PDF合并实例,仅追加当前单个文件就直接写出合并PDF,后续复制新文件到同个文件夹时,会新建合并实例覆盖之前的输出文件,最终每个分类文件夹下只会保留最后一次复制的单个PDF对应的合并结果。
- 提前构建好的、存储「分类名-对应所有PDF列表」映射的
folder_name字典完全未参与合并流程,没有实现同分类多文件的批量追加逻辑。 PdfFileMerger初始化时传入文件名属于无效用法,正确初始化方式是创建空的合并器实例,再逐个追加需要合并的PDF文件。- 硬编码
\\拼接路径容易触发转义错误,稳定性差。
修正方案
将原有的「边复制文件边合并」逻辑拆分为两个独立阶段:第一阶段仅完成分类文件夹创建、PDF文件按分类复制的操作;第二阶段逐个遍历每个分类文件夹,初始化一次合并器,将文件夹内所有待合并PDF全部追加完成后,再一次性写出合并结果。
修正后的main函数代码如下:
def main(): match = [] for i in list_dir: search_zero = i.split("_")[2] if search_zero != "0": match.append((i.split("_", 3)[-1][:6])) else: match.append((i.split("_", 0)[-1][:6])) new_match = [] for i, x in enumerate(match): if "_" in match[i]: new_match.append(x[:-1]) else: new_match.append(x) # 第一阶段:创建分类文件夹,完成文件分类复制 for i, x in enumerate(list_dir): category = new_match[i] cat_folder = os.path.join(new_path, category) try: os.makedirs(cat_folder) except FileExistsError: pass if "PDFs" not in list_dir[i]: shutil.copy(os.path.join(path, x), os.path.join(cat_folder, x)) else: shutil.copy(os.path.join(path, x), os.path.join(moving_path, "Merge", x)) # 第二阶段:逐分类合并所有PDF # 取出去重后的全部分类名 all_categories = list(set(new_match)) for cat in all_categories: cat_folder = os.path.join(new_path, cat) os.chdir(cat_folder) merger = PdfFileMerger() # 遍历当前分类文件夹下的所有PDF,跳过最终生成的合并文件 for filename in os.listdir(cat_folder): if filename.endswith(".pdf") and filename != f"{cat}.pdf": merger.append(filename) merger.write(f"{cat}.pdf") merger.close() os.chdir(new_path)
注意事项
- 合并文件时需要过滤掉最终输出的
{分类名}.pdf文件,避免把已经生成的合并文件再次追加到合并队列,触发递归读取错误。 - 所有路径拼接统一使用
os.path.join实现,不需要手动写Windows路径分隔符,避免转义符导致的路径找不到问题。 - 除了遍历文件夹读取待合并PDF的方式,也可以直接使用之前构建的
folder_name字典做合并,两种方式效果一致,遍历文件夹的写法容错性更高,不会受前面分类匹配逻辑的bug影响。
内容的提问来源于stack exchange,提问作者Mike Liar
相关产品推荐
相关产品推荐

