python連接打印機實現打印文檔、圖片、pdf文件等功能
時間:2020-02-09來源:系統城作者:電腦系統城
引言
python連接打印機進行打印,可能根據需求的不同,使用不同的函數模塊。
- 如果你只是簡單的想打印文檔,比如office文檔,你可以使用
ShellExecute
方法,對于微軟office的文檔、pdf、txt等有用,你可以嘗試下;
- 如果你輸入某些數據,文字信息,就想直接把它發送給打印機打印,那么可以嘗試使用win32print;
- 如果你有一張圖片,那么你可以結合python的
Python Imaging Library(PIL)
和win32ui
模塊進行打??;
普通打印
ShellExecute
- 首先確保你電腦中的應用可以打開你要打印的文件;
- 是一些標準的文件類型
- 不用管哪些打印機,也就是說和連接的打印機型號無關;
- 你無控制設置打印屬性的權限;
- 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
- )
直接打印數據
win32print
- 直接將數據扔給打印機;
- 快速而且容易;
- 而且可以定義選擇哪個打印機打??;
- 但是要打印的數據必須是可打印的,例如字符串等;
- 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電腦上打印一張圖片是相當的困難,至少需要3種不同的且相關的設備環境才可以。
還好,device-independent bitmap(DIB)和PIL可以幫助我們快速打印。下面的代碼可以將圖片發送至打印機打印盡可能大的尺寸且不失比例。
- 還可以選擇使用哪個打印機
- 選擇加載的圖片的格式等
- 但是如果你電腦不是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 ()
實踐
從前臺傳來要打印的字符,后端生成二維碼,并作出相應處理后,連接打印機打印圖片。
- # 打印二維碼
- 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')
-
- # 然后連接打印機將其打印出來即可
- 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
- # 參考 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
打印效果:

以上內容為二賽君整理發布,轉載請注明出處,謝謝。
參考
相關信息
-
PyTorch兩種安裝方法
PyTorch兩種安裝方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值...
2021-03-29
-