I'm trying to use win32api
to output a PDF document to a particular printer.
win32api.ShellExecute(0, "print", filename, '/d:"%s"' % printername, ".", 0)
filename
is a full pathname to the file, and printname
is the name of the target printer I get by going through the output of win32api.EnumPrinters(6)
.
The file is sent to the Windows default printer even if printername
is the name of a different target (my expectation is that passing a specific printer would send the named file to that printer, rather than the default).
Any hints as to what I'm doing wrong? Is there a different way of generically printing a PDF file to a specific printer? Barring all else, is there a way of temporarily changing the default printer from my program?
MikeHunter's answer was a decent starting point.
The proposed solution is calling out to Acrobat or Acrobat Reader to do the actual printing, rather than going through the win32api
. For my purposes, this is sufficient:
from subprocess import call
acrobat = "C:\Program Files\Adobe\Acrobat 7.0\Acrobat.exe" ## Acrobat reader would also work, apparently
file = "C:\path\to\my\file.pdf"
printer = "Printer Name Goes Here"
call([acrobat, "/T", file, printer])
That starts up Acrobat, and prints the given file to the named printer even if it's not the Windows default. The first print job processed this way takes a few seconds (I'm assuming this is the Acrobat service being started and cached in memory), subsequent jobs print instantly. I have not done any kind of load testing on this, but I assume the call is less than trivial, so don't trust it for massive throughput.
I use SumatraPDF to achieve a similar solution (Python 3) as user Inaimathi posted:
import time
from subprocess import call
start = time.perf_counter()
sumatra = "C:\\Program Files\\SumatraPDF\\SumatraPDF.exe"
file = "C:\\Users\\spiderman\\Desktop\\report.pdf"
call([sumatra, '-print-to-default', '-silent', file])
end = time.perf_counter()
print("PDF printing took %5.9f seconds" % (end - start))
The list of command-line arguments you can pass to SumatraPDF is here.
I'm trying to print any old file to a specific printer, so these answers did not help me. However, I did find the perfect solution. Windows has a canonical verb called printto
that does not show up in the context menu. It is used as a way for users to drag and drop a document onto a printer to enable printing in that manner. We can use that feature; the second argument is the name of the printer. I could never get the /d:
parameter to work correctly in conjunction with the print
canonical verb, but this solution solved it for me. I put the printername
in quotes in case there are spaces in it.
win32api.ShellExecute(0, "printto", filename, f'"{printername}"', ".", 0)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With