1

Using the Python win32 API wrapper, I want to select a specific printer, then use that printer to print a pdf file. I wrote this function:

import win32print

def send_to_printer(pdf_file_path, printer_name):
    try:
        # Get a handle to the printer
        printer_handle = win32print.OpenPrinter(printer_name)

        # Set up the document info as a sequence of three elements
        doc_info = ("My Document", None, "RAW")

        # Start the printing job
        job_handle = win32print.StartDocPrinter(printer_handle, 1, doc_info)

        # Open the PDF file
        pdf_file = open(pdf_file_path, 'rb')

        try:
            # Read and print the content of the PDF file
            data = pdf_file.read()
            win32print.StartPagePrinter(printer_handle)
            win32print.WritePrinter(printer_handle, data)
            win32print.EndPagePrinter(printer_handle)

        finally:
            # Close the PDF file and end the printing job
            pdf_file.close()
            win32print.EndDocPrinter(printer_handle)
            win32print.ClosePrinter(printer_handle)

        print(f"Printing completed on {printer_name}")
    except Exception as e:
        print(f"Error printing the PDF: {e}")

and tested it like so:

printer = 'Zebra 450 ZPL'
pdf = 'myfile.pdf'

# This should print out a hard copy of my PDF
send_to_printer(printer, pdf)

When I try this, it seems like everything is working (on Windows 10). The PDF file is sent to the printer, and the printer processes the PDF (the file disappears in the printing pool), but nothing comes out of the actual printer. After that, my printer (Zebra 450 ZPL) is unable to print anything else unless I turn it off and on again.

What is wrong with the code, and how do I fix it?

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
Cellanet
  • 11
  • 2

1 Answers1

0

I've been using this script to print QRCodes from my printer with my script. See if it helps:

Install pywin32
pip install pywin32
See the name of your available printers
import win32print

def get_available_printer_names():
    printer_names = []
    flags = win32print.PRINTER_ENUM_LOCAL | win32print.PRINTER_ENUM_CONNECTIONS
    
    printers = win32print.EnumPrinters(flags)
    for printer in printers:
        printer_name = printer['pPrinterName']
        printer_names.append(printer_name)
    
    return printer_names

if __name__ == "__main__":
    available_printers = get_available_printer_names()
    if available_printers:
        print("Available printers:")
        for printer_name in available_printers:
            print(printer_name)
    else:
        print("No printers found.")
Input the name of your printer and .pdf path
import win32print
import win32ui
import win32com.client
import os

def print_pdf_to_printer(printer_name, pdf_path):

    printer_handle = win32print.OpenPrinter(printer_name)
    
    try:
        default_printer_info = win32print.GetPrinter(printer_handle, 2)
        printer_info = default_printer_info.copy()
        printer_info['pDevMode'].DriverData = b'RAW'
        pdf_file = open(pdf_path, 'rb')
        printer = win32ui.CreatePrinterDC(printer_name)
        printer.StartDoc(pdf_file_path)
        printer.StartPage()
        pdf_data = pdf_file.read()
        printer.Write(pdf_data)
        printer.EndPage()
        printer.EndDoc()
        
    except Exception as e:
        print("Exception occurred: ",e)    
    
    finally:

        win32print.ClosePrinter(printer_handle)
        pdf_file.close()

if __name__ == "__main__":
    
    # Replace 'Your Printer Name' with the actual name of the printer you want to use
    selected_printer = 'Your Printer Name'
    
    # Replace this with the path to your PDF file
    pdf_file_path = "path/to/your/file.pdf"
    
    if os.path.exists(pdf_file_path):
        print(f"Printing '{pdf_file_path}' to '{selected_printer}'...")
        print_pdf_to_printer(selected_printer, pdf_file_path)
        print("Printing complete.")
    else:
        print(f"PDF file not found at '{pdf_file_path}'.")

Musabbir Arrafi
  • 744
  • 4
  • 18