求助:win32print打印PDF文件出现空白,如何修复?
修复空白PDF打印问题的解决方案
我来帮你搞定这个问题!你得到空白PDF的核心原因是:你使用了RAW打印模式,但Microsoft Print to PDF并不支持直接接收原始PDF字节流——它需要的是Windows打印系统能识别的打印指令(比如EMF、PostScript这类格式),而不是PDF文件本身的二进制数据。下面是两种可靠的修复方案,都保留了你需要的打印状态检查功能:
方案一:使用Ghostscript转换PDF为打印机兼容格式(推荐)
既然你允许使用Ghostscript,这是最稳定的方案。Ghostscript可以把PDF文件转换成Windows打印队列能处理的数据流,这样Microsoft Print to PDF就能正确生成有内容的PDF了。
步骤1:安装Ghostscript
先下载安装Ghostscript(注意选择对应你系统的版本,32/64位),安装后记得把Ghostscript的bin目录添加到系统环境变量PATH里,或者在代码里直接指定gswin64c.exe(或gswin32c.exe)的完整路径。
步骤2:修改后的代码
from win32 import win32print import subprocess def get_pdf_print_stream(pdf_path): # 用Ghostscript把PDF转换成打印机兼容的数据流 gs_cmd = [ "gswin64c.exe", # 如果是32位系统换成gswin32c.exe "-dNOPAUSE", "-dBATCH", "-dSAFER", "-sDEVICE=mswinpr2", # 针对Windows打印机的专用设备 "-sOutputFile=%stdout%", # 输出到标准输出 pdf_path ] result = subprocess.run(gs_cmd, capture_output=True, check=True) return result.stdout if __name__ == "__main__": printer_name = "Microsoft Print to PDF" pdf_to_print = "to_print\\document1.pdf" print(f"Printer: {printer_name}") hPrinter = win32print.OpenPrinter(printer_name) try: # 这里的文档名是最终输出的PDF文件名 hJob = win32print.StartDocPrinter(hPrinter, 1, ("output.pdf", None, "RAW")) try: print_stream = get_pdf_print_stream(pdf_to_print) win32print.StartPagePrinter(hPrinter) win32print.WritePrinter(hPrinter, print_stream) win32print.EndPagePrinter(hPrinter) # 检查打印状态 job_info = win32print.GetJob(hPrinter, hJob, 2) print(f"Print Job Status: {job_info['Status']}") if job_info['Status'] == win32print.JOB_STATUS_PRINTING or job_info['Status'] == win32print.JOB_STATUS_COMPLETED: print("Print job is successful!") else: print(f"Print job may have issues. Status code: {job_info['Status']}") finally: win32print.EndDocPrinter(hPrinter) finally: print(f"Print Job ID: {hJob}") win32print.ClosePrinter(hPrinter)
代码说明
get_pdf_print_stream函数:调用Ghostscript把目标PDF转换成打印机能识别的数据流,mswinpr2是Ghostscript针对Windows打印系统的专用设备。- 保留了所有原有的打印状态检查逻辑:通过
GetJob获取任务状态,判断打印是否成功。 StartDocPrinter里的第一个参数是最终输出的PDF文件名(Microsoft Print to PDF会用这个名称生成文件)。
方案二:不使用Ghostscript,改用EMF格式(限简单内容)
如果不想依赖Ghostscript,你可以通过Windows的设备上下文(DC)来绘制内容,但这种方式更适合简单的文本或图形,复杂PDF还是推荐方案一。核心思路如下:
- 创建打印机DC,用
pywin32的win32ui、win32gdi等模块在DC上绘制PDF内容(需要额外处理PDF渲染逻辑)。 - 将DC的内容发送给打印机,这种方式不需要
RAW模式,能被Microsoft Print to PDF正确解析。
为什么原代码会生成空白PDF?
原代码中StartDocPrinter的第三个参数是"RAW",这意味着你直接把PDF的二进制字节流发送给打印机。但Microsoft Print to PDF是虚拟打印机,它无法直接解析原始PDF文件,只能接收Windows打印系统的标准指令(比如EMF),所以它无法识别你发送的PDF字节,最终生成空白文件。
内容的提问来源于stack exchange,提问作者xralf




