https://www.jb51.net/article/179850.htm
引言
python連接打印機(jī)進(jìn)行打印,可能根據(jù)需求的不同,使用不同的函數(shù)模塊。
如果你只是簡單的想打印文檔,比如office文檔,你可以使用ShellExecute方法,對于微軟office的文檔、pdf、txt等有用,你可以嘗試下;
如果你輸入某些數(shù)據(jù),文字信息,就想直接把它發(fā)送給打印機(jī)打印,那么可以嘗試使用win32print;
如果你有一張圖片,那么你可以結(jié)合python的Python Imaging Library(PIL)和win32ui模塊進(jìn)行打??;
普通打印
ShellExecute
首先確保你電腦中的應(yīng)用可以打開你要打印的文件;
是一些標(biāo)準(zhǔn)的文件類型
不用管哪些打印機(jī),也就是說和連接的打印機(jī)型號無關(guān);
你無控制設(shè)置打印屬性的權(quán)限;
import tempfile
import win32api
import win32print
filename = tempfile.mktemp (".txt")
open (filename, "w").write ("This is a test")
win32api.ShellExecute (
0,
"print",
filename,
If this is None, the default printer will
be used anyway.
'/d:"%s"' % win32print.GetDefaultPrinter (),
".",
0
)
另一個(gè)版本
import tempfile
import win32api
import win32print
filename = tempfile.mktemp (".txt")
open (filename, "w").write ("This is a test")
win32api.ShellExecute (
0,
"printto",
filename,
'"%s"' % win32print.GetDefaultPrinter (),
".",
0
)
直接打印數(shù)據(jù)
win32print
直接將數(shù)據(jù)扔給打印機(jī);
快速而且容易;
而且可以定義選擇哪個(gè)打印機(jī)打?。?br>
但是要打印的數(shù)據(jù)必須是可打印的,例如字符串等;
import os, sys
import win32print
printer_name = win32print.GetDefaultPrinter ()
raw_data could equally be raw PCL/PS read from
some print-to-file operation
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)
PIL win32ui
不使用額外的工具,在windows電腦上打印一張圖片是相當(dāng)?shù)睦щy,至少需要3種不同的且相關(guān)的設(shè)備環(huán)境才可以。
還好,device-independent bitmap(DIB)和PIL可以幫助我們快速打印。下面的代碼可以將圖片發(fā)送至打印機(jī)打印盡可能大的尺寸且不失比例。
還可以選擇使用哪個(gè)打印機(jī)
選擇加載的圖片的格式等
但是如果你電腦不是windows,那可能不是最好的方法;
import win32print
import win32ui
from PIL import Image, ImageWin
Constants for GetDeviceCaps
HORZRES / VERTRES = printable area
HORZRES = 8
VERTRES = 10
LOGPIXELS = dots per inch
LOGPIXELSX = 88
LOGPIXELSY = 90
PHYSICALWIDTH/HEIGHT = total area
PHYSICALWIDTH = 110
PHYSICALHEIGHT = 111
PHYSICALOFFSETX/Y = left / top margin
PHYSICALOFFSETX = 112
PHYSICALOFFSETY = 113
printer_name = win32print.GetDefaultPrinter ()
file_name = "test.jpg"
You can only write a Device-independent bitmap
directly to a Windows device context; therefore
we need (for ease) to use the Python Imaging
Library to manipulate the image.
Create a device context from a named printer
and assess the printable size of the paper.
hDC = win32ui.CreateDC ()
hDC.CreatePrinterDC (printer_name)
printable_area = hDC.GetDeviceCaps (HORZRES), hDC.GetDeviceCaps (VERTRES)
printer_size = hDC.GetDeviceCaps (PHYSICALWIDTH), hDC.GetDeviceCaps (PHYSICALHEIGHT)
printer_margins = hDC.GetDeviceCaps (PHYSICALOFFSETX), hDC.GetDeviceCaps (PHYSICALOFFSETY)
Open the image, rotate it if it's wider than
it is high, and work out how much to multiply
each pixel by to get it as big as possible on
the page without distorting.
bmp = Image.open (file_name)
if bmp.size[0] > bmp.size[1]:
bmp = bmp.rotate (90)
ratios = [1.0 * printable_area[0] / bmp.size[0], 1.0 * printable_area[1] / bmp.size[1]]
scale = min (ratios)
Start the print job, and draw the bitmap to
the printer device at the scaled size.
hDC.StartDoc (file_name)
hDC.StartPage ()
dib = ImageWin.Dib (bmp)
scaled_width, scaled_height = [int (scale * i) for i in bmp.size]
x1 = int ((printer_size[0] - scaled_width) / 2)
y1 = int ((printer_size[1] - scaled_height) / 2)
x2 = x1 + scaled_width
y2 = y1 + scaled_height
dib.draw (hDC.GetHandleOutput (), (x1, y1, x2, y2))
hDC.EndPage ()
hDC.EndDoc ()
hDC.DeleteDC ()
實(shí)踐
從前臺傳來要打印的字符,后端生成二維碼,并作出相應(yīng)處理后,連接打印機(jī)打印圖片。
# 打印二維碼
def print_barcode(request):
import pyqrcode
import random,string
from PIL import Image,ImageDraw,ImageFont
import numpy as np
if request.is_ajax() and request.method =``= 'POST'``:
result = {}
bar_string = 'NaN'
type = request.POST[``'type'``]
if type =``= 'box'``:
# 生成箱子碼
# 格式:P190823-K91 [P][日期][-][A-Z][0-9][0-9]
bar_string = 'P'``+``datetime.date.today().strftime(``'%y%m%d'``)``+``'-'``+``str``(random.choice(``'ABCDEFGHIGKLMNOPQRSTUVWXYZ'``))\
+ str``(random.choice(``range``(``10``)))``+ str``(random.choice(``range``(``10``)))
elif type =``= 'kuwei'``:
# 生成庫位碼
bar_string = request.POST[``'string'``]
else``:
pass
try``:
big_code = pyqrcode.create(bar_string, error``=``'L'``, version``=``2 , mode``=``'binary'``)
big_code.png(``'./code.png'``, scale``=``8``)
img_code = Image.``open``(``'code.png'``)
size = img_code.size
img_final = Image.new(``'RGB'``, (size[``0``], size[``1``]``+``35``), color``=``(``255``, 255``, 255``))
img_final.paste(img_code, (``0``, 0``, size[``0``], size[``1``]))
draw = ImageDraw.Draw(img_final)
font = ImageFont.truetype(``'AdobeGothicStd-Bold.otf'``, size``=``35``)
width, height = draw.textsize(bar_string,font``=``font)
draw.text(((size[``0``]``-``width)``/``2``, size[``1``]``-``15``), bar_string , fill``=``(``0``, 0``, 0``), font``=``font)
img_final.save(``'./code.png'``)
# 然后連接打印機(jī)將其打印出來即可
is_ok =``[]
if type =``= 'box'``:
for i in range``(``4``):
temp = print_img(``'./code.png'``)
is_ok.append(temp)
else``:
temp = print_img(``'./code.png'``)
is_ok.append(temp)
# is_ok = True
result[``'done'``] = 'ok' if np.``all``(is_ok) else '連接打印機(jī)失敗'
except Exception as e:
result[``'done'``] = e
return JsonResponse(result)
def print_img(img):
import win32print
import win32ui
from PIL import Image, ImageWin
# 參考 [http://timgolden.me.uk/python/win32_how_do_i/print.html](http://timgolden.me.uk/python/win32_how_do_i/print.html)#win32print
try``:
printer_name = win32print.GetDefaultPrinter()
hDC = win32ui.CreateDC()
hDC.CreatePrinterDC(printer_name)
#printable_area = (300, 270) # 打印紙尺寸
#printer_size = (300, 270)
# 打開圖片并縮放
bmp = Image.``open``(img)
if bmp.size[``0``] < bmp.size[``1``]:
bmp = bmp.rotate(``90``)
# ratios = [1.0 * printable_area[0] / bmp.size[1], 1.0 * printable_area[1] / bmp.size[0]]
# scale = min(ratios)
scale = 1
hDC.StartDoc(img)
hDC.StartPage()
dib = ImageWin.Dib(bmp)
scaled_width, scaled_height = [``int``(scale * i) for i in bmp.size]
x1 = 20 # 控制位置
y1 = -``30
x2 = x1 + scaled_width
y2 = y1 + scaled_height
dib.draw(hDC.GetHandleOutput(), (x1, y1, x2, y2))
hDC.EndPage()
hDC.EndDoc()
hDC.DeleteDC()
return True
except``:
return False
|