python调⽤打印机打印⽂件,图⽚,pdf等
引⾔
python连接打印机进⾏打印,可能根据需求的不同,使⽤不同的函数模块。
1. 如果你只是简单的想打印⽂档,⽐如office⽂档,你可以使⽤ShellExecute⽅法,对于微软office的⽂档、pdf、txt等有⽤,你可以尝试
下;
2. 如果你输⼊某些数据,⽂字信息,就想直接把它发送给打印机打印,那么可以尝试使⽤win32print;
3. 如果你有⼀张图⽚,那么你可以结合python的Python Imaging Library(PIL)和win32ui模块进⾏打印;
普通打印
ShellExecute
⾸先确保你电脑中的应⽤可以打开你要打印的⽂件;
是⼀些标准的⽂件类型
不⽤管哪些打印机,也就是说和连接的打印机型号⽆关;
你⽆控制设置打印属性的权限;
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18import 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 (), ".",
)
另⼀个版本
1 2 3 4 5 6 7 8 9 10 11 12 13 14import 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 (), ".",
)
直接打印数据
win32print
直接将数据扔给打印机;
快速⽽且容易;
⽽且可以定义选择哪个打印机打印;
但是要打印的数据必须是可打印的,例如字符串等;1
2 3 4 5import os, sys
import win32print
printer_name =win32print.GetDefaultPrinter ()
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23# 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电脑上打印⼀张图⽚是相当的困难,⾄少需要3种不同的且相关的设备环境才可以。
还好,device-independent bitmap(DIB)和PIL可以帮助我们快速打印。下⾯的代码可以将图⽚发送⾄打印机打印尽可能⼤的尺⼨且不失⽐例。
还可以选择使⽤哪个打印机
选择加载的图⽚的格式等
但是如果你电脑不是windows,那可能不是最好的⽅法;
1
2
3
4
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36import 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.
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77# 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 =ate (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 ()
实践
从前台传来要打印的字符,后端⽣成⼆维码,并作出相应处理后,连接打印机打印图⽚。1
2
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22# 打印⼆维码
def print_barcode(request):
import pyqrcode
import random,string
from PIL import Image,ImageDraw,ImageFont
import numpy as np
if request.is_ajax() hod =='POST':
result ={}
bar_string ='NaN'
type=request.POST['type']
if type=='box':
# ⽣成箱⼦码
# 格式:P190823-K91 [P][⽇期][-][A-Z][0-9][0-9]
bar_string ='P'+day().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:
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 pass
try:
big_code =ate(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 =w('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 =uetype('f', size=35)
width, height =size(bar_string,font=font)
<(((size[0]-width)/2, size[1]-15), bar_string , fill=(0, 0, 0), font=font)
img_final.save('./code.png')
# 然后连接打印机将其打印出来即可
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'连接打印机失败'
except Exception as e:
result['done'] =e
return JsonResponse(result)
def print_img(img):
import win32print
import win32ui
from PIL import Image, ImageWin
# 参考 #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 =ate(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:
91
return False 92
93
94
打印效果:
仅供学习使⽤
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论