Python print pdf file with win32print

时间:2016-08-31 12:13:40

标签: python pdf printing

I'm trying to print a pdf file from python with module win32print but the only way i can print success is a text.

hPrinter = win32print.OpenPrinter("\\\\Server\Printer")
    filename = "test.pdf"
    try:
        hJob = win32print.StartDocPrinter(hPrinter, 1, ('PrintJobName',None,'RAW'))
        try:
            win32api.ShellExecute(0, "print", filename, None,  ".",  0)
            win32print.StartPagePrinter(hPrinter)
            win32print.WritePrinter(hPrinter, "test") #Instead of raw text is there a way to print PDF File ?
            win32print.EndPagePrinter(hPrinter)
        finally:
            win32print.EndDocPrinter(hPrinter)
    finally:
        win32print.ClosePrinter(hPrinter)

So instead of printing a text i need to print the "test.pdf" file.

I also tried with win32api.ShellExecute(0, "print", filename, None, ".", 0) but is not working, after some test like (getprinter, getdefault, setprinter, setdefaultprinter) it seems not to be attaching the printer. So at this way i can't get working.

This is the code i used !

win32print.SetDefaultPrinter(hPrinter)
win32api.ShellExecute(0, "print", filename, None,  ".",  0)

3 个答案:

答案 0 :(得分:9)

我想要一个能够每天打印大约100个pdf文件的解决方案 每约200页长。文件存储在特定目录中。

{
  bar: {
    baz: string
  }
}

注意:

  1. 您可以使用DevMode对象(GUI代码上的示例)来更改打印机属性,例如颜色/黑色,缩放,质量等。
  2. 提供文件名的绝对路径
  3. 在退出脚本之前,有足够的时间来处理作业。

虽然不能直接回答问题,但我无法抗拒使用import win32api import win32print from glob import glob # A List containing the system printers all_printers = [printer[2] for printer in win32print.EnumPrinters(2)] # Ask the user to select a printer printer_num = int(input("Choose a printer:\n"+"\n".join([f"{n} {p}" for n, p in enumerate(all_printers)])+"\n")) # set the default printer win32print.SetDefaultPrinter(all_printers[printer_num]) pdf_dir = "D:/path/to/pdf_dir/**/*" for f in glob(pdf_dir, recursive=True): win32api.ShellExecute(0, "print", f, None, ".", 0) input("press any key to exit") 制作GUI的机会。可以很容易地更改它以选择目录-以及其中的所有文件-而不是单个文件。

tkinter

GIST

enter image description here enter image description here


来源:

  1. Python printing a pdf file on my Brother Laser printer (Duplex print on/off)
  2. Python print pdf file with win32print
  3. http://docs.activestate.com/activepython/3.1/pywin32/PyDEVMODE.html
  4. https://www.thecodingforums.com/threads/printing-using-python.502484/
  5. https://stackoverflow.com/a/37586129/797495
  6. https://stackoverflow.com/a/56638762/797495
  7. https://t.codebug.vip/questions-712908.htm
  8. How do I create a button in Python Tkinter to increase integer variable by 1 and display that variable?
  9. https://gregcaporale.wordpress.com/2012/01/18/powershell-to-print-files-automatically/这也可能是解决方案

PS:我可能无法赢得赏金,但我当然喜欢制作GUI。 import win32api import win32print import traceback from tkinter.filedialog import askopenfilename from tkinter import * from tkinter import font # * doesn't import font or messagebox from tkinter import messagebox root = Tk() root.title("Python Printer") root.geometry("410x310") root.resizable(False, False) root.tk.call('encoding', 'system', 'utf-8') def font_size(fs): return font.Font(family='Helvetica', size=fs, weight='bold') # Add a grid mainframe = Frame(root) #mainframe.grid(column=0,row=0, sticky=(N,W,E,S) ) mainframe.grid(column=0,row=0, sticky=(N) ) mainframe.columnconfigure(0, weight = 1) mainframe.rowconfigure(0, weight = 1) mainframe.pack(pady = 10, padx = 0) # Create a _printer variable _printer = StringVar(root) # Create a _color variable _color = StringVar(root) _filename = "" # on change dropdown value def sel_printer(*args): print( _printer.get() ) # link function to change dropdown _printer.trace('w', sel_printer) def sel_color(*args): print( _color.get() ) # link function to change dropdown _color.trace('w', sel_color) def UploadAction(event=None): global _filename _filename = filedialog.askopenfilename() #print('Selected:', _filename) def PrintAction(event=None): PRINTER_DEFAULTS = {"DesiredAccess":win32print.PRINTER_ALL_ACCESS} pHandle = win32print.OpenPrinter(_printer.get(), PRINTER_DEFAULTS) properties = win32print.GetPrinter(pHandle, 2) properties['pDevMode'].Color = 1 if str(_color.get()) == "Color" else 2 properties['pDevMode'].Copies = 1 win32print.SetPrinter(pHandle, 2, properties, 0) if not _filename: messagebox.showerror("Error", "No File Selected") return elif not _printer.get(): messagebox.showerror("Error", "No Printer Selected") return try: #win32print.SetDefaultPrinter(_printer.get()) win32api.ShellExecute(0, "print", _filename, None, ".", 0) win32print.ClosePrinter(pHandle) except: pass messagebox.showerror("Error", "There was an error printing the file :(") choices = [printer[2] for printer in win32print.EnumPrinters(2)] _printer.set(win32print.GetDefaultPrinter()) # set the default option popupMenu = OptionMenu(mainframe, _printer, *choices) popupMenu['font'] = font_size(12) Label(mainframe, text="SELECT PRINTER").grid(row = 1, column = 1) popupMenu.grid(row = 2, column =1) # Dictionary with options choices = ["COLOR", "MONOCHROME"] _color.set("COLOR") # set the default option popupMenu2 = OptionMenu(mainframe, _color, *choices) popupMenu2['font'] = font_size(12) Label(mainframe, text="COLOR MODE").grid(row = 3, column = 1) popupMenu2.grid(row = 4, column =1) Label(mainframe, text="SELECT FILE").grid(row = 5, column = 1) button = Button(mainframe, text=u"\uD83D\uDCC1" ' BROWSE', command=UploadAction) button['font'] = font_size(12) button.grid(row = 6, column =1) _copies = IntVar() _copies.set(1) def copies_increase(event=None): _copies.set(_copies.get() + 1) def copies_decrease(event=None): _copies.set(_copies.get() - 1) if _copies.get() < 1 : _copies.set(1) Label(mainframe, textvariable=_copies).grid(columnspan=2) button_frame = Frame(mainframe) button_frame.grid(columnspan=2) dec_button = Button(button_frame, text=u"\u2212", command=copies_decrease, fg="dark green", bg = "white", height=1, width=3 ) dec_button['font'] = font_size(10) inc_button = Button(button_frame, text=u"\uFF0B", command=copies_increase, fg="dark green", bg = "white", height=1, width=3 ) inc_button['font'] = font_size(10) button_frame.columnconfigure(0, weight=1) button_frame.columnconfigure(1, weight=1) dec_button.grid(row=0, column=0, sticky=W+E) inc_button.grid(row=0, column=1, sticky=W+E) Label(mainframe).grid(row = 10, column = 1) p_button = Button(mainframe, text=u'\uD83D\uDDB6' + " PRINT", command=PrintAction, fg="dark green", bg = "white") p_button['font'] = font_size(18) p_button.grid(row = 11, column =1) root.mainloop() 布局是最困难的部分!

答案 1 :(得分:0)

You can try

win32print.SetDefaultPrinter("\\\\Server\Printer")

This method accepts a String, not the printer object you tried to pass it.

答案 2 :(得分:0)

这是我使用的代码,它可以正常工作。

name = win32print.GetDefaultPrinter() # verify that it matches with the name of your printer
printdefaults = {"DesiredAccess": win32print.PRINTER_ALL_ACCESS} # Doesn't work with PRINTER_ACCESS_USE
handle = win32print.OpenPrinter(name, printdefaults)
level = 2
attributes = win32print.GetPrinter(handle, level)
#attributes['pDevMode'].Duplex = 1  #no flip
#attributes['pDevMode'].Duplex = 2  #flip up
attributes['pDevMode'].Duplex = 3   #flip over
win32print.SetPrinter(handle, level, attributes, 0)
win32print.GetPrinter(handle, level)['pDevMode'].Duplex
win32api.ShellExecute(0,'print','manual1.pdf','.','/manualstoprint',0)