【问题标题】:Printing PDF's using Python,win32api, and Acrobat Reader 9使用 Python、win32api 和 Acrobat Reader 9 打印 PDF
【发布时间】:2012-03-30 02:09:11
【问题描述】:

我有报告要发送到要求报告为可读 PDF 格式的系统。我尝试了所有免费的库和应用程序,发现唯一有效的是 Adob​​e 的 acrobat 系列。

我在 python 中编写了一个快速脚本,它使用 win32api 使用默认注册的应用程序 (Acrobat Reader 9) 将 pdf 打印到我的打印机,然后在完成时终止任务,因为 acrobat 喜欢在从命令行。

我将它编译成可执行文件并通过命令行传入值 (例如printer.exe %OUTFILE% %PRINTER%)然后在批处理文件中调用它

import os,sys,win32api,win32print,time

# Command Line Arguments.  
pdf = sys.argv[1]
tempprinter = sys.argv[2]

# Get Current Default Printer.  
currentprinter = win32print.GetDefaultPrinter()
# Set Default printer to printer passed through command line.  
win32print.SetDefaultPrinter(tempprinter)
# Print PDF using default application, AcroRd32.exe
win32api.ShellExecute(0, "print", pdf, None, ".", 0)
# Reset Default Printer to saved value
win32print.SetDefaultPrinter(currentprinter)
# Timer for application close
time.sleep(2)
# Kill application and exit scipt
os.system("taskkill /im AcroRd32.exe /f")

这似乎适用于大量报告,大约 2000 个报告在 3-4 小时内,但我有一些下降,我不确定脚本是否变得不堪重负,或者我是否应该研究多线程或别的东西。

它处理如此大的数量而没有丢失的事实让我相信问题不在于脚本,但我不确定它是否与主机系统或 Adob​​e Reader 或其他问题有关。

任何建议或意见将不胜感激。

【问题讨论】:

  • win32api.ShellExecute() 是否同步? IE。是否要等到 AcrobatReader 完成打印?
  • 根据文档我不这么认为,这就是我设置计时器的原因,我总是可以扩大时间范围。我考虑过生成进程,以便我可以知道应用程序何时完成。问题是我不知道打印作业何时实际打印在打印机上。它的变量取决于网络流量、打印命令的处理时间。
  • 我对你的第一句话有点困惑; “免费库和应用程序”到底有什么不适合的?打印的 PDF 是否不可读或根本无法打印,或者无法创建正确的 PDF?
  • 从 Python 创建 pdf 的另一种方法是使用 Pisa (www.xhtml2pdf.com/) 将 HTML 转换为 PDF
  • Aaron,它的标题信息以及打开时 PRN/PCL 文件的外观。至少在我不得不研究它们的小时间范围内,免费库都是编码的。 Acrobat 的打印文件不能编写正则表达式函数来提取特定数据,因此可以获取报告的人口统计数据。我更愿意使用 ghostscript 和 gsprint,但打印作业文件的格式不适合正则表达式。

标签: python windows printing adobe acrobat


【解决方案1】:

根据您的反馈(win32api.ShellExecute() 可能同步),您的问题是超时:如果您的计算机或打印队列繁忙,kill 命令可能会过早到达。

如果您的脚本同时运行(即您一次打印所有文档,而不是一个接一个地打印),kill 命令甚至可能杀死错误的进程(即由另一个脚本调用启动的 acrobat 进程)。

所以你需要一个更好的同步。您可以尝试以下几件事:

  1. 将其转换为服务器脚本,该脚本启动 Acrobat 一次,然后将许多打印命令发送到同一进程并随后终止。

  2. 使用全局锁确保只运行一个脚本。我建议在某处创建一个文件夹;这是对每个文件系统的原子操作。如果文件夹存在,则脚本在某处处于活动状态。

最重要的是,您需要知道工作何时完成。为此使用win32print.EnumJobs()

如果失败,另一种解决方案可能是在某处安装 Linux 服务器。你可以在这个盒子上运行一个 Python 服务器,它接受你在客户端机器上的一个小 Python 脚本的帮助下发送的打印作业。然后,服务器可以在后台为您打印 PDF。

这种方法允许您添加您喜欢的任何类型的监控(在出现故障时发送邮件或在所有工作完成后发送状态邮件)。

【讨论】:

    猜你喜欢
    • 2018-06-26
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 2017-04-29
    • 1970-01-01
    • 2017-08-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多