如何在Python中配置打印机装订属性打印PDF(发票自动化场景)
解决Outlook发票PDF自动打印的双面与装订配置问题
问题原因
你当前用的win32api.ShellExecute打印命令不支持/staple:1这类高级打印机属性——该命令仅能传递基础的打印机指定参数,无法直接控制双面打印、装订这类需要修改打印机设备模式(DEVMODE)的高级设置。
解决方案
方法1:借助Adobe Acrobat Reader命令行(需提前安装)
Adobe Acrobat Reader支持通过命令行传递打印参数,可结合打印机预设实现双面+装订。替换原代码中win32api.ShellExecute的打印部分:
import subprocess # Adobe Reader路径,根据实际安装路径调整 acrobat_path = r"C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe" # /nosplash 避免启动弹窗,/t 指定打印任务 subprocess.run([ acrobat_path, "/nosplash", "/t", temp_file_path, printer_name ], check=True, shell=False)
提前在打印机打印首选项中创建并设置默认预设为「双面打印+自动装订」,Acrobat会继承该预设的配置。
方法2:通过win32print API直接配置DEVMODE(无需第三方软件)
这种方法直接修改打印机设备模式,强制启用双面和装订,无需依赖外部阅读器。以下是封装好的打印函数,替换原打印逻辑:
def print_pdf_with_settings(file_path, printer_name): hprinter = win32print.OpenPrinter(printer_name) try: # 获取打印机默认DEVMODE配置 devmode = win32print.GetPrinter(hprinter, 2)["pDevMode"] # 设置纵向双面打印(可换DMDUP_HORIZONTAL为横向双面) devmode.Duplex = win32con.DMDUP_VERTICAL # 设置顶部左侧装订(不同打印机常量可能不同,无效则需查询打印机支持的属性值) devmode.Staple = win32con.DMPAPER_STAPLE_TOP_LEFT # 更新打印机临时配置 win32print.SetPrinter(hprinter, 2, {"pDevMode": devmode}, 0) # 创建并执行打印作业 job_info = win32print.StartDocPrinter(hprinter, 1, ("Invoice Print Job", None, "RAW")) try: win32print.StartPagePrinter(hprinter) with open(file_path, "rb") as f: win32print.WritePrinter(hprinter, f.read()) win32print.EndPagePrinter(hprinter) win32print.EndDocPrinter(hprinter) finally: # 恢复打印机默认配置(避免影响其他打印任务) devmode.Duplex = win32con.DMDUP_SIMPLEX devmode.Staple = 0 win32print.SetPrinter(hprinter, 2, {"pDevMode": devmode}, 0) finally: win32print.ClosePrinter(hprinter)
在原代码中调用该函数:
# 替换原来的win32api.ShellExecute行 print_pdf_with_settings(temp_file_path, printer_name)
修改后的完整代码(以方法1为例)
from pathlib import Path import win32com.client import time from os.path import isfile, join from winotify import Notification, audio import win32print import os import subprocess # 替换为你的邮箱和文件夹路径 email = "your_email@domain.com" outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI") inbox = outlook.Folders[email].Folders["folder"].Folders["folder"] archiv = outlook.Folders[email].Folders["folder"].Folders["folder"] printer_name = win32print.GetDefaultPrinter() acrobat_path = r"C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe" target_folder = r"C:\your\target\path" for Item in inbox.Items: subject = Item.Subject attachments = Item.Attachments try: for attachment in attachments: if attachment.FileName.lower().endswith(".pdf"): print("Printing document:", attachment.FileName) temp_file_path = os.path.join(target_folder, attachment.FileName) attachment.SaveAsFile(temp_file_path) # 调用Adobe Reader打印 subprocess.run([ acrobat_path, "/nosplash", "/t", temp_file_path, printer_name ], check=True, shell=False) Item.Move(archiv) toast = Notification(app_id="Invoice Automation", title="Log Notification", msg=f"处理成功: {Item.Subject}", duration="short") toast.show() except Exception as e: toast = Notification(app_id="Invoice Automation", title="Log Notification", msg=f"错误信息: {str(e)}", duration="short") toast.show()
内容的提问来源于stack exchange,提问作者Nico Xenox
相关产品推荐
相关产品推荐

