python连接打印机实现打印文档、图片、pdf文件等功能


Posted in Python onFebruary 07, 2020

引言

python连接打印机进行打印,可能根据需求的不同,使用不同的函数模块。

  1. 如果你只是简单的想打印文档,比如office文档,你可以使用ShellExecute方法,对于微软office的文档、pdf、txt等有用,你可以尝试下;
  2. 如果你输入某些数据,文字信息,就想直接把它发送给打印机打印,那么可以尝试使用win32print;
  3. 如果你有一张图片,那么你可以结合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

打印效果:

python连接打印机实现打印文档、图片、pdf文件等功能

以上内容为二赛君整理发布,转载请注明出处,谢谢。

参考

http://timgolden.me.uk/python/win32_how_do_i/print.htm

Python 相关文章推荐
Python同时向控制台和文件输出日志logging的方法
May 26 Python
Python基于Matplotlib库简单绘制折线图的方法示例
Aug 14 Python
使用PyInstaller将python转成可执行文件exe笔记
May 26 Python
使用python实现http及ftp服务进行数据传输的方法
Oct 26 Python
pandas数据集的端到端处理
Feb 18 Python
使用TensorFlow实现简单线性回归模型
Jul 19 Python
python3实现mysql导出excel的方法
Jul 31 Python
django实现日志按日期分割
May 21 Python
python filecmp.dircmp实现递归比对两个目录的方法
May 22 Python
Python爬虫过程解析之多线程获取小米应用商店数据
Nov 14 Python
Python爬虫之Selenium库的使用方法
Jan 03 Python
Python使用BeautifulSoup4修改网页内容
May 20 Python
解决Keras 与 Tensorflow 版本之间的兼容性问题
Feb 07 #Python
tensorflow2.0与tensorflow1.0的性能区别介绍
Feb 07 #Python
python第三方库学习笔记
Feb 07 #Python
Python字典添加,删除,查询等相关操作方法详解
Feb 07 #Python
tensorflow之自定义神经网络层实例
Feb 07 #Python
在tensorflow中设置使用某一块GPU、多GPU、CPU的操作
Feb 07 #Python
谈一谈数组拼接tf.concat()和np.concatenate()的区别
Feb 07 #Python
You might like
无数据库的详细域名查询程序PHP版(4)
2006/10/09 PHP
PHP 5.3新特性命名空间规则解析及高级功能
2010/03/11 PHP
destoon实现调用当前栏目分类及子分类和三级分类的方法
2014/08/21 PHP
Smarty foreach控制循环次数的一些方法
2015/07/01 PHP
php实现将HTML页面转换成word并且保存的方法
2016/10/14 PHP
php简单随机字符串生成方法示例
2017/04/19 PHP
php 根据URL下载远程图片、压缩包、pdf等文件到本地
2019/07/26 PHP
30个最好的jQuery 灯箱插件分享
2011/04/25 Javascript
js 中将多个逗号替换为一个逗号的代码
2014/06/07 Javascript
Javascript正则控制文本框只能输入整数或浮点数
2014/09/02 Javascript
使用JS实现jQuery的addClass, removeClass, hasClass函数功能
2014/10/31 Javascript
基于javascript实现简单计算器功能
2016/01/03 Javascript
基于Vuejs框架实现翻页组件
2020/06/29 Javascript
Node.js中文件操作模块File System的详细介绍
2017/01/05 Javascript
JavaScript制作简易计算器(不用eval)
2017/02/05 Javascript
vue-hook-form使用详解
2017/04/07 Javascript
深入理解vue.js中$watch的oldvalue与newValue
2017/08/07 Javascript
three.js实现3D视野缩放效果
2017/11/16 Javascript
详细讲解如何创建, 发布自己的 Vue UI 组件库
2019/05/29 Javascript
JS+CSS实现动态时钟
2021/02/19 Javascript
python 七种邮件内容发送方法实例
2014/04/22 Python
Python读大数据txt
2016/03/28 Python
发布你的Python模块详解
2016/09/15 Python
Python中垃圾回收和del语句详解
2018/11/15 Python
使用Python实现跳帧截取视频帧
2019/05/31 Python
Python Threading 线程/互斥锁/死锁/GIL锁
2019/07/21 Python
关于python导入模块import与常见的模块详解
2019/08/28 Python
python智联招聘爬虫并导入到excel代码实例
2019/09/09 Python
W Concept美国:精选全球独立设计师
2017/02/22 全球购物
Sofft鞋官网:世界知名鞋类品牌
2017/03/28 全球购物
英国最大的汽车配件在线商店:Euro Car Parts
2019/09/30 全球购物
高中的职业生涯规划书
2013/12/28 职场文书
小学生春游活动方案
2014/08/20 职场文书
期中考试复习计划
2015/01/19 职场文书
测量JavaScript函数的性能各种方式对比
2021/04/27 Javascript
MySQL数据库如何使用Shell进行连接
2022/04/12 MySQL