python win32print not printing

2020-07-27 03:56发布

问题:

I need to print some information directly (without user confirmation) and I'm using Python and the win32print module.

I've already read the whole Tim Golden win32print page (even read the win32print doc, which is small) and I'm using the same example he wrote there himself, but I just print nothing.

If I go to the interactive shell and make one step at a time, I get the document on the printer queue (after the StartDocPrinter), then I get the document size (after the StartPagePrinter, WritePrinter, EndPagePrinter block) and then the document disappear from the queue (after the EndDocPrinter) without printing.

I'm aware of the ShellExecute method Tim Golden showed. It works here, but it needs to create a temp file and it prints this filename, two things I don't want.

Any ideas? Thanks in advance.

This is the code I'm testing (copy and paste of Tim Golden's):

import os, sys  
import win32print
import time
printer_name = win32print.GetDefaultPrinter()
if sys.version_info >= (3,):
    raw_data = bytes ("This is a test", "utf-8")
else:
    raw_data = "This is a test"

hPrinter = win32print.OpenPrinter (printer_name)
try:
    hJob = win32print.StartDocPrinter (hPrinter, 1, ("test of raw data", None, "RAW"))
    try:
        win32print.StartPagePrinter (hPrinter)
        win32print.WritePrinter (hPrinter, raw_data)
        win32print.EndPagePrinter (hPrinter)
    finally:
        win32print.EndDocPrinter (hPrinter)
finally:
    win32print.ClosePrinter (hPrinter)

[EDIT]

I installed a pdf printer in my computer to test with another printer (CutePDF Writer) and I could generate the test of raw data.pdf file, but when I look inside there is nothing. Meaning: all commands except WritePrinter appears to be doing what they were supposed to do. But again, as I said in the comments, WritePrinter return the correct amount of bytes that were supposed to be written to the printer. I have no other idea how to solve this, but just comproved there is nothing wrong with my printer.

回答1:

I'm still looking for the best way to do this, but I found an answer that satisfy myself for the problem that I have. In Tim Golden's site (linked in question) you can find this example:

import win32ui
import win32print
import win32con

INCH = 1440

hDC = win32ui.CreateDC ()
hDC.CreatePrinterDC (win32print.GetDefaultPrinter ())
hDC.StartDoc ("Test doc")
hDC.StartPage ()
hDC.SetMapMode (win32con.MM_TWIPS)
hDC.DrawText ("TEST", (0, INCH * -1, INCH * 8, INCH * -2), win32con.DT_CENTER)
hDC.EndPage ()
hDC.EndDoc ()

I adapted it a little bit after reading a lot of the documentation. I'll be using win32ui library and TextOut (device context method object).

import win32ui
# X from the left margin, Y from top margin
# both in pixels
X=50; Y=50
multi_line_string = input_string.split()
hDC = win32ui.CreateDC ()
hDC.CreatePrinterDC (your_printer_name)
hDC.StartDoc (the_name_will_appear_on_printer_spool)
hDC.StartPage ()
for line in multi_line_string:
     hDC.TextOut(X,Y,line)
     Y += 100
hDC.EndPage ()
hDC.EndDoc ()

I searched in meta stackoverflow before answering my own question and here I found it is an encouraged behavior, therefore I'm doing it. I'll wait a little more to see if I get any other answer.



回答2:

# U must install pywin32 and import modules:
import win32print, win32ui, win32con  
# X from the left margin, Y from top margin 
# both in pixels
X=50; Y=50
# Separate lines from Your string 
# for example:input_string and create 
# new string for example: multi_line_string 
multi_line_string = input_string.splitlines()  
hDC = win32ui.CreateDC ()
# Set default printer from Windows:
hDC.CreatePrinterDC (win32print.GetDefaultPrinter ())
hDC.StartDoc (the_name_will_appear_on_printer_spool)
hDC.StartPage ()
for line in multi_line_string:
     hDC.TextOut(X,Y,line)
     Y += 100
hDC.EndPage ()
hDC.EndDoc ()
#I like Python