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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 11:42:26