Python print pdf file with win32print

后端 未结 3 759
礼貌的吻别
礼貌的吻别 2021-01-11 23:28

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.OpenPri         


        
相关标签:
3条回答
  • 2021-01-11 23:42

    I'd like a solution which is able to print about 100 pdf files daily every about 200 pages long. Files are stored in certain directory.

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

    Notes:

    1. You can change the printer attributes, such as color/black, scaling, quality, etc, by using the DevMode object (example on the GUI code).
    2. Provide the absolute paths of the filenames
    3. Give enough time to process the job before exiting the script.

    While not direct answer to the question, I couldn't resist the opportunity to make a GUI using tkinter. It can be easily changed to select a dir - and all the files inside - instead of a single file.

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

    GIST


    Sources:

    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/ (this may also be a solution)

    PS: I may not win the bounty, but I certainly enjoyed making the GUI. tkinter layout was the hardest part!

    0 讨论(0)
  • 2021-01-11 23:53

    You can try

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

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

    0 讨论(0)
  • 2021-01-11 23:55

    This is the code I have used and it works correctly.

    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)
    
    0 讨论(0)
提交回复
热议问题