2022-01-12 python連接打印機(jī)實(shí)現(xiàn)打印文檔、圖片、pdf文件等功能

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

|

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容