python連接打印機(jī)實(shí)現(xiàn)打印文檔、圖片、pdf文件等功能
引言
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
)
另一個版本
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ī);
- 快速而且容易;
- 而且可以定義選擇哪個打印機(jī)打??;
- 但是要打印的數(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ī)打印盡可能大的尺寸且不失比例。
- 還可以選擇使用哪個打印機(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#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
打印效果:

以上內(nèi)容為二賽君整理發(fā)布,轉(zhuǎn)載請注明出處,謝謝。
參考
相關(guān)文章
Python數(shù)據(jù)庫反向生成Model最優(yōu)方案示例
這篇文章主要介紹了Python數(shù)據(jù)庫反向生成Model最優(yōu)方案的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07
探索Python?Slice函數(shù)靈活而強(qiáng)大的序列切片技術(shù)
Python中的Slice函數(shù)是一種強(qiáng)大且靈活的序列切片技術(shù),用于從字符串、列表、元組等序列類型中提取子集,本文將深入研究Slice函數(shù)的功能和用法,提供詳細(xì)的示例代碼和解釋,幫助讀者更全面地了解和應(yīng)用這一功能2024-01-01
一文詳解如何在Python中從字符串中提取部分內(nèi)容
這篇文章主要介紹了如何在Python中從字符串中提取部分內(nèi)容的相關(guān)資料,包括使用正則表達(dá)式、Pyparsing庫、AST(抽象語法樹)、字符串操作和函數(shù)式編程,每種方法都有其適用場景和優(yōu)缺點(diǎn),需要的朋友可以參考下2025-04-04
Python實(shí)現(xiàn)日志實(shí)時監(jiān)測的示例詳解
觀察者模式:是一種行為型設(shè)計模式。主要關(guān)注的是對象的責(zé)任,允許你定義一種訂閱機(jī)制,可在對象事件發(fā)生時通知多個"觀察"該對象的其他對象。本文將利用觀察者模式實(shí)現(xiàn)日志實(shí)時監(jiān)測,需要的可以參考一下2022-04-04

