Python调用打印机参考例子
第一个

from PyQt5.QtWidgets import (QApplication, QWidget, QTableWidget,QPushButton, QVBoxLayout,QTableWidgetItem)
from PyQt5.QtGui import  QPixmap,QPainter,QImage,QTextDocument
from PyQt5.QtPrintSupport import  QPrinter,QPrintDialog,QPrintPreviewDialog
from PyQt5.QtCore import QRect,QPoint,QSize,Qt
 
 
# 有预览框<br># 908204694@qq.com<br>#
 
 
def on_htmlButton_clicked():
    printer =QPrinter(QPrinter.HighResolution)
    #/* 打印预览 */
    preview =QPrintPreviewDialog(printer,widget )  
    preview.paintRequested.connect(printHtml)
     
    #
    #   显示 预览框
    #
    #preview.exec()
    preview.exec_()
 
def printHtml(printer):
 
    html = """<html>
    <head></head>
    <body>
        <h1>55555</h1><b>bold</b><h1>55555</h1><b>bold</b>
        <h1>55555</h1><b>bold</b>
        <h1>55555</h1><b>bold</b><h1>55555</h1><b>bold</b>
        <h1>55555</h1><b>bold</b>
        <h1>55555</h1><b>bold</b>
        <h1>55555</h1><b>bold</b>
        <h1>55555</h1><b>bold</b>
        <h1>55555</h1><b>bold</b>
        <h1>55555</h1><b>bold</b>
        <h1>55555</h1><b>bold</b><h1>55555</h1><b>bold</b>
        <h1>55555</h1><b>bold</b>
        <h1>55555</h1><b>bold</b>
        <h1>55555</h1><b>bold</b>
        <h1>55555</h1><b>bold</b><h1>55555</h1><b>bold</b>
        <h1>55555</h1><b>bold</b>
        <h1>55555</h1><b>bold</b>
        <h1>55555</h1><b>bold</b>
        <h1>55555</h1><b>bold</b>
    </body>
    </html>"""
 
    textDocument = QTextDocument()
    textDocument.setHtml(html)
    #textDocument.print(printer)
    textDocument.print_(printer)
    
 
 
def on_picButton_clicked():
 
    printer =QPrinter(QPrinter.HighResolution)
#/* 打印预览 */
    preview =QPrintPreviewDialog(printer,widget )  
 
    """
     * QPrintPreviewDialog类提供了一个打印预览对话框,里面功能比较全,
     * paintRequested(QPrinter *printer)是系统提供的,
     * 当preview.exec()执行时该信号被触发,
     * plotPic(QPrinter *printer)是用户自定义的槽函数,图像的绘制就在这个函数里。
    """
    preview.paintRequested.connect(plotPic)
 
    preview.exec()#/* 等待预览界面退出 */
 
 
 
def  plotPic(printer):
 
    
    
    painter =QPainter(printer);
    image = QPixmap()
 
    image=widget.grab(QRect( QPoint( 0, 0 ),
                                            QSize( widget.size().width(),
                                                        widget.size().height()
                                                    )
                                        )
                                )# /* 绘制窗口至画布 */
   #QRect
    rect = painter.viewport();
   #QSize
    size = image.size();
    size.scale(rect.size(), Qt.KeepAspectRatio)#     //此处保证图片显示完整
    painter.setViewport(rect.x(), rect.y(),size.width(), size.height());
    painter.setWindow(image.rect());
 
    painter.drawPixmap(0,0,image); #/* 数据显示至预览界面 */
 
 
 
import sys
 
app = QApplication(sys.argv)
tablewidget = QTableWidget()
## 设置列数
tablewidget.setColumnCount(4)
tablewidget.horizontalHeader().setDefaultSectionSize(150)
 
## QStringList在PyQt5
header= ["name", "last modify time","type",  "size"]
 
tablewidget.setHorizontalHeaderLabels(header)
tablewidget.insertRow(0)
tablewidget.insertRow(0)
 
pItem1 =  QTableWidgetItem("aa" )
pItem2 =  QTableWidgetItem("bb" )
pItem3 =  QTableWidgetItem("cc" )
pItem4 =  QTableWidgetItem("dd" )
tablewidget.setItem( 0, 0, pItem1 )
tablewidget.setItem( 0, 1, pItem2 )
tablewidget.setItem( 0, 2, pItem3 )
tablewidget.setItem( 0, 3, pItem4 )
 
tablewidget.setMinimumSize(800, 600)
 
 
 
button = QPushButton('打印界面')
button.clicked.connect(on_picButton_clicked)
 
button_txt = QPushButton('打印文字')
button_txt.clicked.connect(on_htmlButton_clicked)
 
widget = QWidget()
layout = QVBoxLayout(widget)
layout.addWidget(button)
layout.addWidget(button_txt)
layout.addWidget(tablewidget)
widget.show()
 
sys.exit(app.exec_())

第二个:

#------------------------- printer.py ----------------------
# 直接打印,不预览
# -*- coding: utf-8 -*-
from PyQt5.QtCore import *
from PyQt5.QtGui import *
 
from PyQt5.QtPrintSupport import QPrinterInfo, QPrinter
 
class Printer:
 
#打印机列表
@staticmethod
def printerList():
printer = []
printerInfo = QPrinterInfo()
print('availablePrinterNames', printerInfo.availablePrinterNames() )
print('defaultPrinterName', printerInfo.defaultPrinterName())
 
for item in printerInfo.availablePrinters():
printer.append(item.printerName())
return printer
 
#打印任务
@staticmethod
def printing(printer, context):
 
p = QPrinter()
 
doc = QTextDocument()
 
htmlStr = context
print('aaaa', htmlStr)
doc.setHtml(htmlStr)
doc.setPageSize(QSizeF(p.logicalDpiX()*(80/25.4),
p.logicalDpiY()*(297/25.4)))
p.setOutputFormat(QPrinter.NativeFormat)
doc.print_(p)
 
@staticmethod
def printing_22(printer, context):
printerInfo = QPrinterInfo()
p = QPrinter()
for item in printerInfo.availablePrinters():
if printer == item.printerName():
p = QPrinter(item)
doc = QTextDocument()
doc.setHtml(u'%s' % context)
doc.setPageSize(QSizeF(p.logicalDpiX()*(80/25.4),
p.logicalDpiY()*(297/25.4)))
p.setOutputFormat(QPrinter.NativeFormat)
doc.print_(p)
 
 
 
 
 
if __name__ == '__main__':
import sys
from PyQt5.QtWidgets import QApplication
app = QApplication(sys.argv)
##########################################
html = '<html><head></head><body><h1>55555</h1><b>bold</b></body></html>'
p = "defaultPrinter" #打印机名称
#Printer.printing(p, html)
#Printer.printerList()
Printer.printing_22(p, html)
 
#####################################################
sys.exit(app.exec_())

第三个:

from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import QApplication
from PyQt5.QtPrintSupport import QPrinter
# 将要打印的东西生成pdf 
a=QApplication([])
document = QTextDocument()
html = """
<head>
<title>Report</title>
<style>
</style>
</head>
<body>
<table width="100%">
<tr>
<td><img src="{}" width="30"></td>
<td><h1>REPORT汉字试试哈</h1></td>
</tr>
</table>
<hr>
<p align=right><img src="{}" width="300"></p>
<p align=right>Sample</p>
</body>
""".format('./aa.png', './bb.png')
 
document.setHtml(html)
printer = QPrinter()
printer.setResolution(96)
printer.setPageSize(QPrinter.Letter)
printer.setOutputFormat(QPrinter.PdfFormat)
printer.setOutputFileName("test.pdf")
 
# 设置纸张的边距
printer.setPageMargins(12, 16, 12, 20, QPrinter.Millimeter)
document.setPageSize(QSizeF(printer.pageRect().size()))
print(document.pageSize(), printer.resolution(), printer.pageRect())
document.print_(printer)

连接打印机打印文档,图片,pdf文件
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
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐