You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyPDF2实现监控文件夹PDF合并至文档末尾而非开头的问题

问题:PyPDF2合并新增PDF到目标文件末尾失败,总是添加到开头

我是Python新手,无法找到正确方法让PyPDF2将监控文件夹中新增的PDF文件合并到目标文件(invoices.pdf)的末尾,而非开头。以下是我目前的代码:

import time
import os
import sys
import logging
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
from PyPDF2 import PdfReader, PdfMerger

class Watcher:
    DIRECTORY_TO_WATCH = "C:\\Users\\Grayden\\Desktop\\PDF_Trial"
    FILENAME = "invoices.pdf"

    def __init__(self):
        self.observer = Observer()

    def run(self):
        event_handler = Handler()
        self.observer.schedule(event_handler, self.DIRECTORY_TO_WATCH, recursive=True)
        self.observer.start()
        try:
            while True:
                time.sleep(5)
        except:
            self.observer.stop()
            print("Error")

        self.observer.join()

class Handler(FileSystemEventHandler):
    @staticmethod
    def on_any_event(event):
        if event.is_directory:
            return None

        elif event.event_type == 'created':
            # Take any action here when a file is first created.
            if event.src_path.endswith(".pdf"):
                print("New PDF file added: %s" % event.src_path)
                merge_pdfs(Watcher.DIRECTORY_TO_WATCH, Watcher.FILENAME)

def merge_pdfs(directory, output_filename):
    pdf_list = []
    for foldername, subfolders, filenames in os.walk(directory):
        for filename in filenames:
            if filename.endswith('.pdf'):
                filepath = os.path.join(foldername, filename)
                pdf_list.append(filepath)

    pdf_merger = PdfMerger()
    for pdf_path in pdf_list:
        with open(pdf_path, 'rb') as pdf_file:
            pdf_reader = PdfReader(pdf_file, strict=False)
            pdf_merger.append(pdf_reader)

    with open(os.path.join(directory, output_filename), 'wb') as file:
        pdf_merger.write(file)

if __name__ == '__main__':
    w = Watcher()
    w.run()

解决方案

你的问题核心在于原代码每次都会遍历文件夹中所有PDF重新合并,遍历顺序的不确定性导致新文件可能被加到开头。正确的做法是只将新添加的PDF追加到已有的目标文件末尾,而非重新合并全部文件。修改后的代码如下:

import time
import os
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
from PyPDF2 import PdfReader, PdfMerger

class Watcher:
    DIRECTORY_TO_WATCH = "C:\\Users\\Grayden\\Desktop\\PDF_Trial"
    FILENAME = "invoices.pdf"

    def __init__(self):
        self.observer = Observer()

    def run(self):
        event_handler = Handler()
        self.observer.schedule(event_handler, self.DIRECTORY_TO_WATCH, recursive=True)
        self.observer.start()
        try:
            while True:
                time.sleep(5)
        except KeyboardInterrupt:
            self.observer.stop()
            print("监控已停止")
        self.observer.join()

class Handler(FileSystemEventHandler):
    @staticmethod
    def on_created(event):
        if event.is_directory:
            return None
        if event.src_path.endswith(".pdf"):
            # 等待1秒确保文件完全写入磁盘
            time.sleep(1)
            print("New PDF file added: %s" % event.src_path)
            merge_pdfs(Watcher.DIRECTORY_TO_WATCH, Watcher.FILENAME, event.src_path)

def merge_pdfs(directory, output_filename, new_pdf_path):
    output_path = os.path.join(directory, output_filename)
    # 跳过目标文件本身,避免循环处理
    if os.path.basename(new_pdf_path) == output_filename:
        return

    pdf_merger = PdfMerger()
    # 先加载已存在的目标文件
    if os.path.exists(output_path):
        with open(output_path, 'rb') as output_file:
            pdf_merger.append(PdfReader(output_file, strict=False))
    # 追加新PDF到末尾
    with open(new_pdf_path, 'rb') as new_pdf_file:
        pdf_merger.append(PdfReader(new_pdf_file, strict=False))
    # 写入合并后的文件
    with open(output_path, 'wb') as file:
        pdf_merger.write(file)

if __name__ == '__main__':
    w = Watcher()
    w.run()

关键修改点

  1. 合并逻辑优化:不再遍历所有PDF,仅将新添加的单个文件追加到目标文件末尾
  2. 避免循环处理:判断如果触发事件的是目标文件invoices.pdf,直接跳过
  3. 文件完整性保障:添加1秒延迟,确保新文件完全写入磁盘后再处理
  4. 异常处理完善:明确捕获KeyboardInterrupt,让程序可以优雅停止

内容的提问来源于stack exchange,提问作者Gtwizzy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 10:30:41