关于Windows:使用Python,win32api和Acrobat Reader 9打印PDF

Printing PDF's using Python,win32api, and Acrobat Reader 9

我有要发送到系统的报告,该报告要求报告采用可读的PDF格式。我尝试了所有免费的库和应用程序,而我发现唯一起作用的是Adobe的acrobat系列。

我在python中编写了一个快速脚本,该脚本使用win32api使用默认注册的应用程序(Acrobat Reader 9)将pdf打印到我的打印机,然后在完成时终止该任务,因为acrobat希望从命令行调用时使窗口保持打开状态。

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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")

这似乎可以很好地工作,在3-4个小时内大约有2000个报告,但是我有一些报告下降了,我不确定脚本是否不堪重负,还是应该研究多线程或其他方法。

它可以处理大量的东西而没有下降的事实使我相信问题不在于脚本,但是我不确定是否是主机系统或Adobe Reader或其他问题。

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


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

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

因此,您需要更好的同步。您可以尝试以下几种方法:

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

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

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

    如果失败,另一种解决方案可能是在某处安装Linux服务器。您可以在此框上运行Python服务器,该服务器接受在客户端计算机上借助小型Python脚本发送的打印作业。然后,服务器可以在后台为您打印PDF。

    这种方法允许您添加所需的任何类型的监视(如果发生故障则发送邮件,或在所有作业完成后发送状态邮件)。