Python办公自动化实战Win32print批量打印PDF/Word全攻略办公室里堆积如山的PDF和Word文档需要打印还在手动一个个点击打印按钮今天我们就用Python的Win32print模块配合PyPDF2和python-docx库打造一个全自动的批量打印解决方案。这个脚本不仅能处理本地文件还能自动识别网络打印机甚至支持双面打印和份数设置。1. 环境准备与基础配置在开始编写批量打印脚本前我们需要先搭建好Python环境并安装必要的库。这里推荐使用Python 3.8版本兼容性和稳定性都经过验证。首先安装核心依赖库pip install pywin32 PyPDF2 python-docxPyPDF2用于处理PDF文件python-docx用于操作Word文档而pywin32则提供了Win32print模块来与Windows打印系统交互。检查打印机是否就绪import win32print def list_printers(): printers win32print.EnumPrinters( win32print.PRINTER_ENUM_LOCAL | win32print.PRINTER_ENUM_CONNECTIONS ) for i, printer in enumerate(printers): print(f{i1}. {printer[2]}) return printers available_printers list_printers()这段代码会列出所有可用的本地和网络打印机。在实际办公环境中我们经常会遇到需要选择特定打印机的情况比如彩色打印机 vs 黑白打印机本地打印机 vs 网络共享打印机普通打印机 vs 虚拟PDF打印机提示如果打印机列表为空请检查打印机是否已正确连接并开启共享权限。网络打印机可能需要先手动连接一次。2. 文档处理核心模块批量打印不同格式的文档需要不同的处理方式。我们分别实现PDF和Word文档的打印逻辑。2.1 PDF文档打印优化PDF是最常见的办公文档格式我们使用PyPDF2来确保打印质量import os from PyPDF2 import PdfFileReader def validate_pdf(file_path): try: with open(file_path, rb) as f: reader PdfFileReader(f) if reader.isEncrypted: print(f警告{file_path} 已加密无法直接打印) return False return True except Exception as e: print(fPDF文件验证失败{e}) return FalsePDF打印函数需要处理一些特殊情况def print_pdf(file_path, printer_name, copies1, duplexFalse): if not validate_pdf(file_path): return printer_handle win32print.OpenPrinter(printer_name) try: # 设置打印参数 attributes win32print.GetPrinter(printer_handle)[13] if duplex: attributes[Duplex] win32print.DUPLEX_VERTICAL # 开始打印任务 job_name os.path.basename(file_path) doc_info (job_name, None, RAW) job_id win32print.StartDocPrinter(printer_handle, 1, doc_info) for _ in range(copies): win32print.StartPagePrinter(printer_handle) with open(file_path, rb) as f: win32print.WritePrinter(printer_handle, f.read()) win32print.EndPagePrinter(printer_handle) finally: win32print.ClosePrinter(printer_handle)2.2 Word文档打印方案Word文档打印需要额外处理格式问题from docx import Document import tempfile def print_word(file_path, printer_name, copies1): try: # 验证Word文档 doc Document(file_path) temp_pdf tempfile.mktemp(suffix.pdf) # 转换为PDF打印更可靠 doc.save(temp_pdf) print_pdf(temp_pdf, printer_name, copies) except Exception as e: print(fWord文档打印失败{e}) finally: if os.path.exists(temp_pdf): os.remove(temp_pdf)注意直接打印Word文档有时会出现格式错乱转换为PDF再打印能确保格式准确。这种方法虽然多了一步转换但可靠性大大提高。3. 批量打印系统实现现在我们将各个模块整合成一个完整的批量打印系统。3.1 文件扫描与过滤智能识别目录下的可打印文件def get_printable_files(directory, extensions(.pdf, .doc, .docx)): file_list [] for root, _, files in os.walk(directory): for file in files: if file.lower().endswith(extensions): file_path os.path.join(root, file) file_list.append(file_path) return sorted(file_list, keylambda x: os.path.getmtime(x)) # 按修改时间排序3.2 打印队列管理实现一个带错误处理和状态报告的打印队列from queue import Queue from threading import Thread class PrintWorker(Thread): def __init__(self, queue): Thread.__init__(self) self.queue queue def run(self): while True: file_path, printer_name, settings self.queue.get() try: if file_path.lower().endswith(.pdf): print_pdf(file_path, printer_name, copiessettings.get(copies, 1), duplexsettings.get(duplex, False)) elif file_path.lower().endswith((.doc, .docx)): print_word(file_path, printer_name, copiessettings.get(copies, 1)) print(f成功打印: {file_path}) except Exception as e: print(f打印失败: {file_path} - {str(e)}) finally: self.queue.task_done() def batch_print(files, printer_name, max_workers3, **print_settings): queue Queue() # 启动工作线程 for _ in range(max_workers): worker PrintWorker(queue) worker.daemon True worker.start() # 添加打印任务 for file_path in files: queue.put((file_path, printer_name, print_settings)) queue.join() # 等待所有任务完成4. 高级功能与实战技巧4.1 打印机状态监控实时监控打印机状态避免任务堆积def check_printer_status(printer_name): handle win32print.OpenPrinter(printer_name) try: status win32print.GetPrinter(handle)[18] status_messages { 0: 准备就绪, 1: 暂停, 2: 错误, 4: 待定删除, 8: 纸张用完, 16: 卡纸, 32: 手动送纸, 64: 门打开, 128: 用户干预, 256: 缺墨, 512: 输出仓满, 1024: 不可用, 2048: 等待 } return status_messages.get(status, 未知状态) finally: win32print.ClosePrinter(handle)4.2 打印任务取消功能有时我们需要中断批量打印def cancel_all_jobs(printer_name): handle win32print.OpenPrinter(printer_name) try: win32print.SetPrinter(handle, 0, None, win32print.PRINTER_CONTROL_PURGE) print(f已清除{printer_name}上的所有打印任务) finally: win32print.ClosePrinter(handle)4.3 配置文件管理将常用配置保存为JSON文件{ default_printer: HP LaserJet Pro MFP, default_copies: 1, default_duplex: true, watched_folders: [ C:\\打印队列\\PDF, D:\\共享文档\\待打印 ] }加载配置的函数import json def load_config(config_pathconfig.json): try: with open(config_path) as f: return json.load(f) except FileNotFoundError: return { default_printer: win32print.GetDefaultPrinter(), default_copies: 1, default_duplex: False }5. 完整解决方案与使用示例将所有功能整合成一个命令行工具import argparse def main(): parser argparse.ArgumentParser(description批量打印PDF和Word文档) parser.add_argument(path, help文件或目录路径) parser.add_argument(-p, --printer, help打印机名称) parser.add_argument(-c, --copies, typeint, default1, help打印份数) parser.add_argument(-d, --duplex, actionstore_true, help双面打印) args parser.parse_args() config load_config() printer_name args.printer or config.get(default_printer) if os.path.isfile(args.path): files [args.path] else: files get_printable_files(args.path) print(f准备打印 {len(files)} 个文件到 {printer_name}) batch_print(files, printer_name, copiesargs.copies, duplexargs.duplex) if __name__ __main__: main()使用示例# 打印单个PDF文件 python print_tool.py document.pdf -p HP Printer -c 2 -d # 批量打印整个目录 python print_tool.py C:\办公文档\月度报告 -c 1实际项目中这个脚本帮我节省了大量重复劳动时间。最初版本在处理特殊字符的文件名时会失败后来增加了文件名清洗逻辑才彻底稳定。建议在正式使用前先用虚拟打印机测试几次。
Python办公自动化:用Win32print实现批量打印PDF和Word文档(附完整代码)
Python办公自动化实战Win32print批量打印PDF/Word全攻略办公室里堆积如山的PDF和Word文档需要打印还在手动一个个点击打印按钮今天我们就用Python的Win32print模块配合PyPDF2和python-docx库打造一个全自动的批量打印解决方案。这个脚本不仅能处理本地文件还能自动识别网络打印机甚至支持双面打印和份数设置。1. 环境准备与基础配置在开始编写批量打印脚本前我们需要先搭建好Python环境并安装必要的库。这里推荐使用Python 3.8版本兼容性和稳定性都经过验证。首先安装核心依赖库pip install pywin32 PyPDF2 python-docxPyPDF2用于处理PDF文件python-docx用于操作Word文档而pywin32则提供了Win32print模块来与Windows打印系统交互。检查打印机是否就绪import win32print def list_printers(): printers win32print.EnumPrinters( win32print.PRINTER_ENUM_LOCAL | win32print.PRINTER_ENUM_CONNECTIONS ) for i, printer in enumerate(printers): print(f{i1}. {printer[2]}) return printers available_printers list_printers()这段代码会列出所有可用的本地和网络打印机。在实际办公环境中我们经常会遇到需要选择特定打印机的情况比如彩色打印机 vs 黑白打印机本地打印机 vs 网络共享打印机普通打印机 vs 虚拟PDF打印机提示如果打印机列表为空请检查打印机是否已正确连接并开启共享权限。网络打印机可能需要先手动连接一次。2. 文档处理核心模块批量打印不同格式的文档需要不同的处理方式。我们分别实现PDF和Word文档的打印逻辑。2.1 PDF文档打印优化PDF是最常见的办公文档格式我们使用PyPDF2来确保打印质量import os from PyPDF2 import PdfFileReader def validate_pdf(file_path): try: with open(file_path, rb) as f: reader PdfFileReader(f) if reader.isEncrypted: print(f警告{file_path} 已加密无法直接打印) return False return True except Exception as e: print(fPDF文件验证失败{e}) return FalsePDF打印函数需要处理一些特殊情况def print_pdf(file_path, printer_name, copies1, duplexFalse): if not validate_pdf(file_path): return printer_handle win32print.OpenPrinter(printer_name) try: # 设置打印参数 attributes win32print.GetPrinter(printer_handle)[13] if duplex: attributes[Duplex] win32print.DUPLEX_VERTICAL # 开始打印任务 job_name os.path.basename(file_path) doc_info (job_name, None, RAW) job_id win32print.StartDocPrinter(printer_handle, 1, doc_info) for _ in range(copies): win32print.StartPagePrinter(printer_handle) with open(file_path, rb) as f: win32print.WritePrinter(printer_handle, f.read()) win32print.EndPagePrinter(printer_handle) finally: win32print.ClosePrinter(printer_handle)2.2 Word文档打印方案Word文档打印需要额外处理格式问题from docx import Document import tempfile def print_word(file_path, printer_name, copies1): try: # 验证Word文档 doc Document(file_path) temp_pdf tempfile.mktemp(suffix.pdf) # 转换为PDF打印更可靠 doc.save(temp_pdf) print_pdf(temp_pdf, printer_name, copies) except Exception as e: print(fWord文档打印失败{e}) finally: if os.path.exists(temp_pdf): os.remove(temp_pdf)注意直接打印Word文档有时会出现格式错乱转换为PDF再打印能确保格式准确。这种方法虽然多了一步转换但可靠性大大提高。3. 批量打印系统实现现在我们将各个模块整合成一个完整的批量打印系统。3.1 文件扫描与过滤智能识别目录下的可打印文件def get_printable_files(directory, extensions(.pdf, .doc, .docx)): file_list [] for root, _, files in os.walk(directory): for file in files: if file.lower().endswith(extensions): file_path os.path.join(root, file) file_list.append(file_path) return sorted(file_list, keylambda x: os.path.getmtime(x)) # 按修改时间排序3.2 打印队列管理实现一个带错误处理和状态报告的打印队列from queue import Queue from threading import Thread class PrintWorker(Thread): def __init__(self, queue): Thread.__init__(self) self.queue queue def run(self): while True: file_path, printer_name, settings self.queue.get() try: if file_path.lower().endswith(.pdf): print_pdf(file_path, printer_name, copiessettings.get(copies, 1), duplexsettings.get(duplex, False)) elif file_path.lower().endswith((.doc, .docx)): print_word(file_path, printer_name, copiessettings.get(copies, 1)) print(f成功打印: {file_path}) except Exception as e: print(f打印失败: {file_path} - {str(e)}) finally: self.queue.task_done() def batch_print(files, printer_name, max_workers3, **print_settings): queue Queue() # 启动工作线程 for _ in range(max_workers): worker PrintWorker(queue) worker.daemon True worker.start() # 添加打印任务 for file_path in files: queue.put((file_path, printer_name, print_settings)) queue.join() # 等待所有任务完成4. 高级功能与实战技巧4.1 打印机状态监控实时监控打印机状态避免任务堆积def check_printer_status(printer_name): handle win32print.OpenPrinter(printer_name) try: status win32print.GetPrinter(handle)[18] status_messages { 0: 准备就绪, 1: 暂停, 2: 错误, 4: 待定删除, 8: 纸张用完, 16: 卡纸, 32: 手动送纸, 64: 门打开, 128: 用户干预, 256: 缺墨, 512: 输出仓满, 1024: 不可用, 2048: 等待 } return status_messages.get(status, 未知状态) finally: win32print.ClosePrinter(handle)4.2 打印任务取消功能有时我们需要中断批量打印def cancel_all_jobs(printer_name): handle win32print.OpenPrinter(printer_name) try: win32print.SetPrinter(handle, 0, None, win32print.PRINTER_CONTROL_PURGE) print(f已清除{printer_name}上的所有打印任务) finally: win32print.ClosePrinter(handle)4.3 配置文件管理将常用配置保存为JSON文件{ default_printer: HP LaserJet Pro MFP, default_copies: 1, default_duplex: true, watched_folders: [ C:\\打印队列\\PDF, D:\\共享文档\\待打印 ] }加载配置的函数import json def load_config(config_pathconfig.json): try: with open(config_path) as f: return json.load(f) except FileNotFoundError: return { default_printer: win32print.GetDefaultPrinter(), default_copies: 1, default_duplex: False }5. 完整解决方案与使用示例将所有功能整合成一个命令行工具import argparse def main(): parser argparse.ArgumentParser(description批量打印PDF和Word文档) parser.add_argument(path, help文件或目录路径) parser.add_argument(-p, --printer, help打印机名称) parser.add_argument(-c, --copies, typeint, default1, help打印份数) parser.add_argument(-d, --duplex, actionstore_true, help双面打印) args parser.parse_args() config load_config() printer_name args.printer or config.get(default_printer) if os.path.isfile(args.path): files [args.path] else: files get_printable_files(args.path) print(f准备打印 {len(files)} 个文件到 {printer_name}) batch_print(files, printer_name, copiesargs.copies, duplexargs.duplex) if __name__ __main__: main()使用示例# 打印单个PDF文件 python print_tool.py document.pdf -p HP Printer -c 2 -d # 批量打印整个目录 python print_tool.py C:\办公文档\月度报告 -c 1实际项目中这个脚本帮我节省了大量重复劳动时间。最初版本在处理特殊字符的文件名时会失败后来增加了文件名清洗逻辑才彻底稳定。建议在正式使用前先用虚拟打印机测试几次。