美文网首页
2022-01-12 python连接打印机实现打印文档、图片

2022-01-12 python连接打印机实现打印文档、图片

作者: netppp | 来源:发表于2022-01-12 11:43 被阅读0次

    https://www.jb51.net/article/179850.htm

    引言

    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](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

    |

    相关文章

      网友评论

          本文标题:2022-01-12 python连接打印机实现打印文档、图片

          本文链接:https://www.haomeiwen.com/subject/uvcwcrtx.html