python連線印表機實現列印文件、圖片、pdf檔案等功能
阿新 • • 發佈:2020-02-10
引言
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,"printto",'"%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,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),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(),y2)) hDC.EndPage() hDC.EndDoc() hDC.DeleteDC() return True except: return False
列印效果:
以上內容為二賽君整理髮布,轉載請註明出處,謝謝。
參考
http://timgolden.me.uk/python/win32_how_do_i/print.htm