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

强颜欢笑 提交于 2021-02-07 22:26:46

问题


I have reports that I am sending to a system that requires the reports be in a readable PDF format. I tried all of the free libraries and applications and the only one that I found worked was Adobe's acrobat family.

I wrote a quick script in python that uses the win32api to print a pdf to my printer with the default registered application (Acrobat Reader 9) then to kill the task upon completion since acrobat likes to leave the window open when called from the command line.

I compiled it into an executable and pass in the values through the command line (for example printer.exe %OUTFILE% %PRINTER%) this is then called within a batch file

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")

This seemed to work well for a large volume, ~2000 reports in a 3-4 hour period but I have some that drop off and I'm not sure if the script is getting overwhelmed or if I should look into multithreading or something else.

The fact that it handles such a large amount with no drop off leads me to believe that the issue is not with the script but I'm not sure if its an issue with the host system or Adobe Reader, or something else.

Any suggestions or opinions would be greatly appreciated.


回答1:


Based on your feedback (win32api.ShellExecute() is probably not synchronous), your problem is the timeout: If your computer or the print queue is busy, the kill command can arrive too early.

If your script runs concurrently (i.e. you print all documents at once instead of one after the other), the kill command could even kill the wrong process (i.e. an acrobat process started by another invocation of the script).

So what you need it a better synchronization. There are a couple of things you can try:

  1. Convert this into a server script which starts Acrobat once, then sends many print commands to the same process and terminates afterwards.

  2. Use a global lock to make sure that ever only a single script is running. I suggest to create a folder somewhere; this is an atomic operation on every file system. If the folder exists, the script is active somewhere.

On top of that, you need to know when the job is finished. Use win32print.EnumJobs() for this.

If that fails, another solution could be to install a Linux server somewhere. You can run a Python server on this box which accepts print jobs that you send with the help of a small Python script on your client machine. The server can then print the PDFs for you in the background.

This approach allow you to add any kind of monitoring you like (sending mails if something fails or send a status mail after all jobs have finished).



来源:https://stackoverflow.com/questions/9688028/printing-pdfs-using-python-win32api-and-acrobat-reader-9

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!