怎么用脚本控制打印机

wen 实用脚本 2

从零到实战:用Python脚本精确控制打印机的完整指南


目录导读

  1. 为什么需要脚本控制打印机? —— 效率与自动化的核心价值
  2. 控制打印机前的准备工作 —— 硬件、驱动与Python环境搭建
  3. 核心操控技术 —— win32print库深度解析(含代码示例)
  4. 进阶实战:批量打印PDF/Word文档的自动化脚本
  5. 常见报错与解决方案 —— 排除“卡纸”“脱机”等玄学问题
  6. 高频问答(Q&A) —— 解决你最后的疑虑

为什么需要脚本控制打印机?

在日常办公或开发中,手动点击“打印”按钮重复操作不仅耗时,且容易出错,批量打印100张带不同编号的标签、定时自动打印报表、根据数据库内容动态生成单据,通过脚本,我们可以实现无人值守打印静默打印(不弹出对话框)、以及精确控制打印份数、纸张方向、双面模式等,其本质是调用操作系统底层的打印机API,绕过GUI交互,直接向打印机发送指令。

怎么用脚本控制打印机


准备工作:环境与依赖

在开始写代码之前,请确保:

  • 硬件:打印机已正确连接电脑并安装官方驱动,且在“控制面板 > 设备和打印机”中设为默认打印机(或记住其名称)。
  • Python环境:建议使用Python 3.8+,并安装核心库 pywin32(或仅安装 win32print,它是前者的子模块)。
    pip install pywin32
  • 系统限制:此方案主要针对Windows系统(因使用Win32 API),对于Linux/macOS,可改用cupslp命令,但本文聚焦Windows。

核心操控技术:win32print深度解析

win32print 是连接Python与Windows打印系统的桥梁,其底层封装了GDI(图形设备接口)和打印机驱动API,以下是最常用的三个函数:

  1. win32print.EnumPrinters() —— 获取打印机列表

    import win32print
    printers = win32print.EnumPrinters(win32print.PRINTER_ENUM_LOCAL | win32print.PRINTER_ENUM_CONNECTIONS)
    for p in printers:
        print(p[2])  # 打印打印机名称
  2. win32print.OpenPrinter()win32print.StartDocPrinter() —— 开启打印任务 这是最底层的“原始数据”发送方式,通常用于直接发送文本或PCL/PostScript指令,但如果你要打印PDF或图片,更推荐使用上层的 win32api.ShellExecuteos.startfile(),因为它们会自动调用关联程序(如Adobe Reader)并触发打印。

  3. win32print.SetJob() —— 控制任务状态(暂停/恢复/取消)

    # 获取当前打印队列中的任务
    handle = win32print.OpenPrinter(printer_name)
    jobs = win32print.EnumJobs(handle, 0, -1, win32print.JOB_STATUS_ALL)
    for job in jobs:
        job_id = job['JobId']
        # 取消任务
        win32print.SetJob(handle, job_id, 0, None, win32print.JOB_CONTROL_DELETE)
    win32print.ClosePrinter(handle)

进阶实战:批量打印PDF/Word文档的自动化脚本

要想实现“一键打印整个文件夹中的PDF”,最稳定的是调用系统默认程序,然后通过模拟快捷键Ctrl+P来触发打印,但这种方式不够“静默”,更好的方案是通过COM接口操作Office或使用专库pdf2print,下面是一段更实用、无弹窗的打印图片文本文件的例子:

import os
import win32print
import win32ui
from PIL import Image
def print_image(img_path, printer_name=None, copies=1):
    if not printer_name:
        printer_name = win32print.GetDefaultPrinter()
    # 创建DC(设备上下文)
    hprinter = win32print.OpenPrinter(printer_name)
    try:
        # 获取打印机DC句柄
        devmode = win32print.GetPrinter(hprinter, 2)["pDevMode"]
        # 加载图片并调整尺寸
        image = Image.open(img_path)
        width, height = image.size
        # 创建打印DC
        pr_dc = win32ui.CreateDC()
        pr_dc.CreatePrinterDC(printer_name)
        pr_dc.StartDoc(img_path)
        pr_dc.StartPage()
        # 缩放图片以适配纸张(这里简化处理)
        # 实际需计算比例并调用StretchBlt
        pr_dc.EndPage()
        pr_dc.EndDoc()
    finally:
        win32print.ClosePrinter(hprinter)
# 批量打印当前目录所有图片
for f in os.listdir('.'):
    if f.lower().endswith(('.png', '.jpg', '.jpeg')):
        print(f"正在打印:{f}")
        print_image(f)

注意:上述代码涉及图像缩放与DPI计算,真正的生产级脚本应使用win32uiBitBlt来做无损输出,如果只是想快速实现,推荐安装pandas + pathlib + win32api,利用shellapi.ShellExecuteWprintto命令。


常见报错与解决方案

问题现象 可能原因 解决办法
“PrintNotFound”错误 打印机名称错误或驱动未安装 使用win32print.EnumPrinters()打印所有名称,复制确切字符串。
脚本运行无反应 打印页面被隐藏或队列阻塞 检查打印机状态,先手动打印测试页排除硬件故障。
PDF打印失败 关联程序未启动或受保护 改用Acrobat的COM接口,或转换PDF为图片后打印。
权限不足 服务账户无访问驱动权限 以管理员身份运行Python或Windows服务。

高频问答(Q&A)

Q1:脚本能控制打印机的双面打印吗? A:可以,你需要修改devmode中的dmDuplex字段(1=单面,2=双面长边,3=双面短边),但这要求驱动支持,建议在打印机属性中预先设置默认双面,然后脚本中不修改该字段。

Q2:如何在Linux上实现类似功能? A:使用cups打印系统,调用subprocess.run(['lp', '-d', 'printer_name', '-n', '2', 'file.pdf']),Python库如pycups也提供封装。

Q3:脚本如何实现“静默打印”而不弹出保存PDF对话框? A:关键在于不要使用os.startfile(),它会调用Adobe Reader并弹出窗口,请使用win32print直接发送原始数据,或者使用libreoffice的headless模式转换并打印。

Q4:监控打印任务完成状态? A:可以使用win32print.EnumJobs轮询队列,当任务列表为空时即为打印完成,更高级的是注册系统打印事件,但需要写C++扩展或使用win32event


结束语:掌握脚本控制打印机,本质是拥抱自动化思维,从简单的文本打印到复杂的混合文档批处理,Python的win32print为你提供了强大的底层接口,本文给出的示例代码(请自行补齐具体细节)已能覆盖80%的日常需求,如果你的场景涉及网络打印机或云打印,只需调整连接字符串即可,希望这篇指南能帮你从“手动点打印”升级为“一键全自动”。

抱歉,评论功能暂时关闭!