2

At the organization I work for, different printers are set up at various locations. All are mainly used to print A4-sized documents, so the defaults are set up accordingly.

We are also using a bunch of custom-sized forms which people have up to now been filling in by hand. Recently, I was tasked with setting up print-automation onto the said forms from our central database.

I'm using reportlab to create temporary pdf files which I am then trying to send to the default printer. All is relatively simple, save for getting the printers to register a custom paper size.

I got as far as the following code snippet, but I'm really stuck.

import tempfile
import win32api
import win32print

pdf_file = tempfile.mktemp(".pdf")

#CREATION OF PDF FILE WITH REPORTLAB

printer = win32print.GetDefaultPrinter()
PRINTER_DEFAULTS = {"DesiredAccess":win32print.PRINTER_ALL_ACCESS}
pHandle = win32print.OpenPrinter(printer, PRINTER_DEFAULTS)
level = 2
properties = win32print.GetPrinter(pHandle, level)
pDevModeObj = properties["pDevMode"]

pDevModeObj.PaperSize = 0
pDevModeObj.PaperLength = 2200 #SIZE IN 1/10 mm
pDevModeObj.PaperWidth = 1000 #SIZE IN 1/10 mm

properties["pDevMode"]=pDevModeObj
win32print.SetPrinter(pHandle,level,properties,0)
    
#OPTION ONE
#win32api.ShellExecute(0, "print", pdf_file, None, ".", 0)

#OPTION TWO
win32api.ShellExecute (0,"printto",pdf_file,'"%s"' % printer,".",0)

win32print.ClosePrinter(pHandle)

It just does not work. Printers do not report a "paper size mismatch", like they should when a non-A4 document is being sent to them. And when I try printing to a PDF printer, it also defaults to A4.

When calling

print(pDevModeObj.PaperSize)
print(pDevModeObj.PaperLength)
print(pDevModeObj.PaperWidth)

everything seems to be in order, so I'm guessing I don't know how to send those paper size values back to the printer settings.

Here is a list of all the resources I checked out (examples not all in python, and a few are not using the win32api), and couldn't get the thing to work properly:

Nimantha
  • 6,405
  • 6
  • 28
  • 69
Jure T
  • 199
  • 1
  • 8
  • Using the shell to print is pretty flaky. If you spoke to the printer directly you'd be able to control the paper. I suspect your real problem is actually having chosen the wrong way to print. – David Heffernan Nov 17 '20 at 06:38

1 Answers1

1

ShellExecute is using the default printing parameters. If you need to use the reset DevMode for printing, you can use CreateDC.

Refer: GDI Print API


If you use SetPrinter to modify the default DEVMODE structure for a printer (globally setting the printer defaults), you must first call the DocumentProperties function to validate the DEVMODE structure.

Refer:

You can also directly use DocumentProperties to modify printer initialization information.

Then pass pDevModeObj to CreateDC, and use StartDoc and StartPage to print.

Similar case: Change printer tray with pywin32

Strive Sun
  • 5,988
  • 1
  • 9
  • 26
  • @Jure T Hi, please tell me if the answer useful to you? – Strive Sun Nov 19 '20 at 08:52
  • Dear Strive Sun! I apologize for a late reply. Your answer did help, ... ironically by making me re-evaluate my approach and go back to the basics. :) ... so ... I ended up using the wxwidgets wrapper for page creation and for sending it to the prinder. Somehow, the page size and all works when I use, as I said, wxwidgets. ... To anyone failing to properly do what StriveSun suggested, which I guess works, but I just don't get it, you can try changing your approach altogether. – Jure T Dec 14 '20 at 20:57
  • ... just don't ask me what happens in the background in wxwidgets :). – Jure T Dec 14 '20 at 21:03