how to create a virtual printer
eryksun ()
eryksun at gmail.com
Tue Mar 29 20:03:05 EDT 2011
On Monday, March 28, 2011 7:12:23 AM UTC-4, kalo... at gmail.com wrote:
>
> Does anybody know how to create a virtual
> printer with python (on both windows and linux)?
Here's some code I just put together showing how to use Python to create a PostScript file printer on Windows, output raw text to a file, and also output text with fonts and simple line graphics. You'll need the pywin32 extensions.
This code is only minimally tested, and it does little if any error checking. However, this is just to demonstrate the gist of using pywin32 for printing PostScript to a file. If you get an error about finding the driver for "MS Publisher Imagesetter', you may need to add the printer manually to make the driver available (it's under the 'generic' manufacturer). No doubt there's a way to install this driver automatically using the Win32 API, but I haven't looked into it.
The generated PostScript file can be viewed on Windows using the evince viewer:
http://live.gnome.org/Evince/Downloads
#
import win32print, win32ui, win32gui
import win32con, pywintypes
def create_printer(printer_name='MyPSPrinter'):
printer_info = {
'pPrinterName': printer_name,
'pDevMode': pywintypes.DEVMODEType(),
'pDriverName': 'MS Publisher Imagesetter',
'pPortName': 'FILE:',
'pPrintProcessor': 'WinPrint',
'Attributes': 0,
'AveragePPM': 0,
'cJobs': 0,
'DefaultPriority': 0,
'Priority': 0,
'StartTime': 0,
'Status': 0,
'UntilTime': 0,
'pComment': '',
'pLocation': '',
'pDatatype': None,
'pParameters': None,
'pSecurityDescriptor': None,
'pSepFile': None,
'pServerName': None,
'pShareName': None}
h_printer = win32print.AddPrinter(None, 2, printer_info)
return h_printer
def test_raw(printer='MyPSPrinter',
filename=r'D:\test.txt',
text=None):
'''send plain text to a file'''
if text is None:
text_data = "This is a test. This is only a test."
else:
text_data = text
job_info = ("Raw File Print", filename, 'RAW')
h_printer = win32print.OpenPrinter(printer)
try:
h_job = win32print.StartDocPrinter(h_printer, 1, job_info)
try:
win32print.StartPagePrinter(h_printer)
win32print.WritePrinter(h_printer, text_data)
win32print.EndPagePrinter(h_printer)
finally:
win32print.EndDocPrinter(h_printer)
finally:
win32print.ClosePrinter(h_printer)
def test_ps(printer='MyPSPrinter',
filename=r'D:\test.ps',
margin=(0.25,1.5,0.25,1.0),
font_size=24,
text=None):
'''render postscript text and graphics to a file'''
if text is None:
text_data = "This is a test.\nThis is only a test."
else:
text_data = str(text)
# Get the printer's DEVMODE structure
h_printer = win32print.OpenPrinter(printer)
devmode = win32print.GetPrinter(h_printer, 2)['pDevMode']
win32print.ClosePrinter(h_printer)
# set up the device context
# see MSDN: ff552837, aa452943, dd319099, dd145045
devmode.FormName = 'Letter' # or 'A4'
devmode.PaperSize = win32con.DMPAPER_LETTER # or DMPAPER_A4
devmode.Orientation = win32con.DMORIENT_PORTRAIT
devmode.PrintQuality = win32con.DMRES_HIGH
devmode.Color = win32con.DMCOLOR_MONOCHROME
devmode.TTOption = win32con.DMTT_SUBDEV
devmode.Scale = 100
devmode.Fields |= (win32con.DM_FORMNAME |
win32con.DM_PAPERSIZE |
win32con.DM_ORIENTATION |
win32con.DM_PRINTQUALITY |
win32con.DM_COLOR |
win32con.DM_TTOPTION |
win32con.DM_SCALE)
h_dc = win32gui.CreateDC('WINSPOOL', printer, devmode)
dc = win32ui.CreateDCFromHandle(h_dc)
dc.SetMapMode(win32con.MM_TWIPS) # or MM_HIMETRIC (0.01 mm)
# begin writing the document
dc.StartDoc('Postscript File Print', filename)
dc.StartPage()
# we need a pen and a font
scale = 20 # 72 pt/inch * 20 twip/pt = 1440
inch = 72*scale
pen = win32ui.CreatePen(win32con.PS_SOLID,
scale, # 1 pt
0) # black
dc.SelectObject(pen)
font = win32ui.CreateFont({
'name': 'Times New Roman',
'height': font_size * scale,
'weight': win32con.FW_NORMAL})
dc.SelectObject(font)
# output the text
x = int(margin[0] * inch)
y = -int(margin[1] * inch)
width = int((8.5 - margin[0] - margin[2]) * inch)
height = int((11.0 - margin[1] - margin[3]) * inch)
rect = (x, y, x + width, y - height)
dc.DrawText(text_data, rect, win32con.DT_LEFT)
if text is None:
# draw 8 steps starting at x = 0.25", y = 3"
width = inch
height = inch
for n in range(8):
x = n * width + 18*scale
y = -n * height - 3*inch
dc.MoveTo((x, y))
dc.LineTo((x + width, y))
dc.MoveTo((x + width, y))
dc.LineTo((x + width, y - height))
dc.EndPage()
dc.EndDoc()
#end
More information about the Python-list
mailing list