如何用Python实现Windows下批量打印PDF并监听打印完成触发后续操作
Windows下Python批量打印PDF并监听任务完成的实现方案
核心问题解决思路
- 避免弹窗:放弃调用Adobe Acrobat Reader,改用
SumatraPDF便携版实现静默打印,它无需安装、无多余弹窗,支持命令行直接发送打印任务到指定打印机 - 监听打印完成状态:通过
win32print获取当前打印机的任务队列,轮询待确认的打印任务状态,直到任务从队列中消失即判定为物理打印完成
完整实现代码
import win32print import win32api import time import os from view_controller import play_sound # 配置项,根据实际情况修改 SUMATRA_PATH = r"./SumatraPDF.exe" # 你存放SumatraPDF便携版的路径 DEFAULT_PRINTER = win32print.GetDefaultPrinter() # 也可以手动指定网络打印机名称 WAIT_INTERVAL = 1 # 打印队列轮询间隔,单位秒 def wait_for_print_job_done(job_name: str, timeout: int = 300) -> bool: """ 等待指定打印任务完成 :param job_name: 打印任务名称(一般为PDF文件名) :param timeout: 超时时间,默认5分钟 :return: 任务完成返回True,超时返回False """ start_time = time.time() while time.time() - start_time < timeout: # 打开当前打印机获取任务列表 printer_handle = win32print.OpenPrinter(DEFAULT_PRINTER) jobs = win32print.EnumJobs(printer_handle, 0, -1, 1) win32print.ClosePrinter(printer_handle) # 检查目标任务是否还在队列中 job_exists = any(job['pDocument'] == job_name for job in jobs) if not job_exists: return True time.sleep(WAIT_INTERVAL) return False def print_PDFs(files, wait_seconds: int = 20): if not isinstance(files, list): files = [files] for file_path in files: if not os.path.exists(file_path): print(f"文件不存在:{file_path},跳过") continue file_name = os.path.basename(file_path) # 调用SumatraPDF静默打印,无弹窗 print(f"开始打印:{file_name}") win32api.ShellExecute( 0, "print", SUMATRA_PATH, f'/print-to "{DEFAULT_PRINTER}" "{file_path}"', ".", 0 # 0表示隐藏窗口,完全后台运行 ) # 等待打印任务完成 if wait_for_print_job_done(file_name): play_sound('complete') print(f"打印完成:{file_name},{wait_seconds}秒后开始下一个任务") time.sleep(wait_seconds) else: print(f"打印超时:{file_name},请检查打印机状态")
使用说明
- SumatraPDF便携版无需安装,也不会修改系统默认PDF打开方式,直接放到对应路径即可使用
- 如果是网络打印机,直接把
DEFAULT_PRINTER变量的值改成你公司网络打印机的完整名称即可 - 轮询间隔和超时时间可以根据你打印机的实际打印速度调整,避免误判
内容的提问来源于stack exchange,提问作者Francesco Anastasio
相关产品推荐
相关产品推荐

