Python自动化办公:打印机控制全攻略

Python自动化办公:打印机控制全攻略 1. Python控制打印机的基础原理打印机控制看似简单实则涉及操作系统底层交互。Python通过不同模块封装了这些底层接口让我们能用统一的方式操作各类打印机。我刚开始接触这个领域时发现不同品牌的打印机驱动差异很大但Python的抽象层帮我们屏蔽了这些复杂性。打印机通信主要分为两种模式命令模式和文件模式。命令模式直接发送打印机指令如ESC/POS指令集常见于热敏打印机文件模式则是发送完整文档如PDF、DOCX由打印机驱动解析。Python的妙处在于它能同时支持这两种模式。以Windows系统为例打印流程实际上是这样的应用程序 → GDI图形接口 → 打印假脱机 → 打印机驱动 → 物理打印机。Python的win32print模块就是与这个打印子系统交互的桥梁。而在Linux/macOS上CUPS(通用Unix打印系统)承担了类似的角色。2. Windows系统打印方案详解2.1 win32print模块深度使用PyWin32库中的win32print模块是Windows打印的瑞士军刀。安装很简单pip install pywin32获取打印机信息是最基础的操作import win32print # 获取默认打印机 default_printer win32print.GetDefaultPrinter() print(f当前默认打印机{default_printer}) # 枚举网络打印机需要加上这个标志位 all_printers win32print.EnumPrinters( win32print.PRINTER_ENUM_LOCAL | win32print.PRINTER_ENUM_CONNECTIONS )实际打印文件时我推荐使用ShellExecute方式它最接近右键点击打印的效果import win32api file_path 销售报表.xlsx win32api.ShellExecute( 0, # 无父窗口 print, # 执行打印操作 file_path, # 文件路径 None, # 使用默认打印机 ., # 当前目录 0 # 不显示窗口 )2.2 高级打印控制技巧工作中经常需要批量打印时这几个技巧特别实用设置打印份数from win32printing import Printer with Printer(margin100) as p: # 边距100像素 p.text(年度报告) p.set(copies3) # 打印3份打印状态监控def check_printer_status(printer_name): hprinter win32print.OpenPrinter(printer_name) status win32print.GetPrinter(hprinter, 2)[Status] if status win32print.PRINTER_STATUS_PAUSED: return 已暂停 elif status win32print.PRINTER_STATUS_ERROR: return 错误状态 else: return 就绪3. Linux/macOS打印解决方案3.1 CUPS系统集成在Unix-like系统上打印是通过CUPS(Common UNIX Printing System)实现的。Python通过pycups库与之交互import cups conn cups.Connection() printers conn.getPrinters() # 打印PDF文档 job_id conn.printFile( HP_LaserJet, # 打印机名称 invoice.pdf, # 文件路径 客户发票, # 作业名称 {copies: 2} # 打印2份 )3.2 命令行打印工具封装对于简单的打印任务直接调用系统命令更快捷import subprocess # 打印文本文件 subprocess.run([lp, -d, Brother_HL-2140, report.txt]) # 查看打印队列 result subprocess.run([lpstat, -o], capture_outputTrue) print(result.stdout.decode())4. 跨平台打印方案4.1 操作系统检测与适配实现跨平台打印的关键是先检测操作系统类型import platform import subprocess def print_file(filename): system platform.system() if system Windows: # 注意处理文件路径中的空格 subprocess.run([notepad, /p, filename]) elif system Linux: subprocess.run([lp, filename]) elif system Darwin: # macOS subprocess.run([lpr, filename]) else: raise OSError(不支持的操作系统)4.2 通用打印服务方案对于企业级应用可以考虑这些方案打印服务器方案所有设备通过网络打印到中央打印服务器云打印服务使用Google Cloud Print等云服务需注意服务可用性虚拟PDF打印机先统一生成PDF再调用系统打印# 虚拟打印示例 def virtual_print(content, output_formatPDF): if output_format PDF: from reportlab.pdfgen import canvas c canvas.Canvas(temp.pdf) c.drawString(100, 800, content) c.save() return temp.pdf # 其他格式处理...5. 特殊打印机控制5.1 热敏小票打印机超市小票、POS机常用ESC/POS指令控制from escpos.printer import Usb # 需要先通过lsusb(linux)或设备管理器(Windows)查找厂商ID p Usb(0x0416, 0x5011) # 爱普生TM-T88IV p.text(销售小票\n) p.text(商品1 ¥15.00\n) p.text(商品2 ¥28.50\n) p.text(- * 32 \n) p.barcode(123456789, EAN13) p.cut() # 切纸5.2 标签打印机斑马等工业标签打印机通常使用ZPL指令def print_zpl_label(): zpl_code ^XA ^FO50,50^A0N,50,50^FD产品标签^FS ^FO50,120^BQN,2,10^FDMM,A123-456^FS ^XZ with open(r\\printserver\Zebra_Label, wb) as f: f.write(zpl_code.encode())6. 实战案例自动化打印系统6.1 批量打印Excel报表结合pandas和win32print实现自动化报表打印import pandas as pd from win32printing import Printer def print_excel_sheets(filename): excel pd.ExcelFile(filename) with Printer(linegap2) as p: for sheet_name in excel.sheet_names: df excel.parse(sheet_name) p.text(f {sheet_name} \n\n) # 打印表格内容 for _, row in df.iterrows(): p.text( .join(str(x) for x in row) \n) p.page_break() # 分页6.2 定时打印任务调度结合Windows任务计划或Linux cron实现定时打印import schedule import time def daily_report(): print_file(daily_report.pdf) # 每天9:00执行 schedule.every().day.at(09:00).do(daily_report) while True: schedule.run_pending() time.sleep(60)7. 常见问题排查指南打印乱码问题检查打印机驱动是否安装正确确认发送的数据编码中文建议使用GB18030热敏打印机检查是否发送了正确的初始化指令打印任务卡住# Windows清除所有打印任务 import win32print hprinter win32print.OpenPrinter(default_printer) win32print.SetPrinter(hprinter, 0, None, win32print.PRINTER_CONTROL_PURGE)权限问题处理Windows以管理员身份运行Python脚本Linux将用户加入lpadmin组sudo usermod -aG lpadmin username