本文作者之前发过一篇Python实现打印机批量打印文件,经作者反复练习与测试,总感觉未尽预期效果,经过不断学习和参考,使用ThreadPoolExecutor线程池来批量打印文件,进一步实现在“d:\文件”目录或用户自定义的目录下包含office系列软件文档、pdf、txt、png、jpg等格式文件的一键批量打印。

python如何打印表格 windows10操作系统下python实现多格式文件一键批量打印(1)

(d:\文件目录下的文件结构图,本次代码就是实现这些类型一次性提交全部打印)

在win r 输入cdm 进入到python安装目录c:\python38(请根据实际情况使用你自己的python安装文件目录)下输入 1、pip install pywin32 安装pywin32 2、pip install pillow 安装pillow (俗称PIL)

C:\>cd python38 C:\Python38>pip install pywin32 Requirement already satisfied: pywin32 in c:\python38\lib\site-packages (301) C:\Python38>pip3 install pillow Collecting pillow Downloading Pillow-8.3.1-1-cp38-cp38-win_amd64.whl (3.2 MB) |████████████████████████████████| 3.2 MB 547 kB/s Installing collected packages: pillow Successfully installed pillow-8.3.1 C:\Python38>

【小提示】:如遇见:WARNING: You are using pip version 21.2.2; however, version 21.2.4 is available.You should consider upgrading via the 'c:\python38\python.exe -m pip install --upgrade pip' command.这个提示,请按如下方式升级pip后进行操作。

C:\Python38>python.exe -m pip install --upgrade pip Requirement already satisfied: pip in c:\python38\lib\site-packages (21.2.2) Collecting pip Downloading pip-21.2.4-py3-none-any.whl (1.6 MB) |████████████████████████████████| 1.6 MB 437 kB/s Installing collected packages: pip Attempting uninstall: pip Found existing installation: pip 21.2.2 Uninstalling pip-21.2.2: Successfully uninstalled pip-21.2.2 Successfully installed pip-21.2.4

python如何打印表格 windows10操作系统下python实现多格式文件一键批量打印(2)

(pip安装参考图)

查看当前电脑上安装了哪些打印机:

#查看当前电脑上安装了哪些打印机: import win32print printers = win32print.EnumPrinters(3) print(printers)

python如何打印表格 windows10操作系统下python实现多格式文件一键批量打印(3)

(获取得到的系统已经安装的所有打印机名称)

获取默认打印机:

#查看当前电脑默认的打印机名称 import win32print printer = win32print.GetDefaultPrinter() print(printer)

python如何打印表格 windows10操作系统下python实现多格式文件一键批量打印(4)

(当前系统默认打印机名称)

python打印文档文件

实现python批量打印微软office系列的word、excel、ppt文档、pdf、txt等格式文件,前提是要有打开这些文件的软件,不然会报错。比如安装好office 软件、pdf阅读软件(并默认打开pdf文件,而不是其它方式打开pdf,比如浏览器打开方式。)

import win32api #定义打印函数,以便重复调用 def printer_file(fileName): win32api.ShellExecute ( 0, #指定父窗口句柄 "print", #指定操作,这里的"print"表示启动打印应用程序 fileName, #要打印的文件名 #方法一:None, #打印机设置,若是"None",则使用windows设置的默认打印机 #方法二:'/d:"%s"' % win32print.GetDefaultPrinter () '/d:"%s"' % win32print.GetDefaultPrinter (), ".", #指定默认目录,照抄的,搞不懂 0 #若fileName参数是一个可执行程序,则此参数指定程序窗口的初始显示方式,否则此参数应设置为0 ) print(filename '----打印成功') printer_loading(r'd:\文件\测试.jpg')

python打印图片文件

实现python批量打印图片,要有对应图片查看器,并设置默认打开指定类型的图片格式文件,不然会报错。

def printer_pic(pic_path, printer_name): # 物理宽度、高度 PHYSICALWIDTH = 110 PHYSICALHEIGHT = 111 # 物理偏移位置 PHYSICALOFFSETX = 112 PHYSICALOFFSETY = 113 printer_name = win32print.GetDefaultPrinter() hDC = win32ui.CreateDC() hDC.CreatePrinterDC(printer_name) printer_size = hDC.GetDeviceCaps(PHYSICALWIDTH), hDC.GetDeviceCaps(PHYSICALHEIGHT) # printer_margins = hDC.GetDeviceCaps (PHYSICALOFFSETX), hDC.GetDeviceCaps (PHYSICALOFFSETY) # 打开图片,通过每个像素使它尽可能大,页面不失真。 bmp = Image.open(file_name) ratios = [1.0 * 1754 / bmp.size[0], 1.0 * 1240 / bmp.size[1]] scale = min(ratios) # 开始打印作业,并将位图绘制到,按比例缩放打印机设备。 hDC.StartDoc(file_name) hDC.StartPage() dib = ImageWin.Dib(bmp) scaled_width, scaled_height = [int(scale * i) for i in bmp.size] print(scaled_width, scaled_height) x1 = int((printer_size[0] - scaled_width) / 2) y1 = int((printer_size[1] - scaled_height) / 2) # 横向位置坐标 x1 = 1580 # 竖向位置坐标 y1 = 30 # 4倍为自适应图片实际尺寸打印 x2 = x1 bmp.size[0] * 4 y2 = y1 bmp.size[1] * 4 dib.draw(hDC.GetHandleOutput(), (x1, y1, x2, y2)) hDC.EndPage() hDC.EndDoc() hDC.DeleteDC() printer_name = win32print.GetDefaultPrinter() pic_path = r'd:\文件\测试.jpg' printer_pic(file_name, printer_name)

项目print.py完整代码:

import win32ui from PIL import Image, ImageWin #使用ThreadPoolExecutor线程池来批量打印文件 from concurrent.futures import ThreadPoolExecutor import win32api import win32print import os import collections class Printer: def __init__(self): #__init__()方法又被称为构造器(constructor)声明该属性为私有, #不能在类的外部被使用或访问 #self在定义类的方法时是必须有的,self指的是类实例对象本身(注意:不是类本身)。 self.printer_name = win32print.GetDefaultPrinter() self.path = None self.file_path_list = [] # 打印启动项 def printer_loading(self, path): self.path = path png_path_list, pdf_path_list = self.get_file_all() #执行线程 executor = ThreadPoolExecutor(max_workers=3) #使用 ThreadPoolExecutor 来实例化线程池对象。 #传入max_workers=3参数来设置线程池中最多能同时运行的3个线程数目。 #executor.map 将序列中的每个元素都执行同一个函数 #下面代码是对png_path_list的每个元素都执行printer_png_loading函数,并分配到线程池里 #下面代码是对pdf_path_list的每个元素都执行printer_other_loading函数,并分配到线程池里 executor.map(self.printer_png_loading, png_path_list) executor.map(self.printer_other_loading, pdf_path_list) # 打印图片 def printer_png_loading(self, file_path): try: # HORZRES / VERTRES = printable area 可打印的区域 HORZRES = 8 VERTRES = 10 # PHYSICALWIDTH/HEIGHT = total area 总面积 # PHYSICALWIDTH = 110 PHYSICALHEIGHT = 111 printer_name = win32print.GetDefaultPrinter() hDC = win32ui.CreateDC() hDC.CreatePrinterDC(printer_name) printable_area = hDC.GetDeviceCaps(HORZRES), hDC.GetDeviceCaps(VERTRES) printer_size = hDC.GetDeviceCaps(PHYSICALWIDTH), hDC.GetDeviceCaps(PHYSICALHEIGHT) # #打开图像,如果宽度大于高,计算出要乘的倍数 # #通过每个像素使它尽可能大 # #页面不失真。 bmp = Image.open(file_path) 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) # #开始打印作业,并将位图绘制到 # #按比例缩放打印机设备。 hDC.StartDoc(file_path) 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() print('-ok!!--文件成功打印!---' file_path) except Exception as ex: print('-error!!--文件打印失败!---' file_path) print(repr(ex)) # 打印其他文件 def printer_other_loading(self, file_path): try: open(file_path, "r") win32api.ShellExecute ( 0, #指定父窗口句柄 "print", #指定操作,这里的"print"表示启动打印应用程序 #fileName, #要打印的文件名 #方法一:None, #打印机设置,若是"None",则使用windows设置的默认打印机 #方法二:'/d:"%s"' % win32print.GetDefaultPrinter () file_path, #要打印的文件目录 '/d:"%s"' % self.printer_name, ".", #指定默认目录,照抄的,搞不懂 0 #若fileName参数是一个可执行程序,则此参数指定程序窗口的初始显示方式,否则此参数应设置为0 ) print('--ok!!-文件成功打印!---' file_path) except Exception as ex: print(repr(ex)) print('-error!!--文件打印失败!---', file_path) # 递归查找文件,并放入到对应的列表中 def get_file_all(self): dl = collections.deque() #collections模块常用类型deque 设定队列 #deque是双端队列(double-ended queue)的缩写, #由于两端都能编辑,deque既可以用来实现栈(stack)也可以用来实现队列(queue) dl.append(self.path) #入队(append)从右端添加元素(与list同) #入队(appendleft)从左端添加元素(与list同) png_path_list = [] pdf_path_list = [] while len(dl) != 0: # != 不等于 - 比较两个对象是否不相等 #len() 方法返回对象(字符、列表、元组等)长度或项目个数 pop = dl.popleft() #移除列表中的一个元素(默认最左端的一个元素),并且返回该元素的值, #pooleft是用于collections中 dl.popleft() ()中不可以带参数 #pop移除列表中的一个元素(默认最右端的一个元素) #是用于stack中的 dl.pop() ()中可以带参数, #出队(pop) listfile = os.listdir(pop) #os.listdir() 方法用于返回指定的文件夹包含的文件或文件夹的名字的列表 for i in listfile: newpath = os.path.join(pop, i) #os.path.join()函数用于路径拼接文件路径,可以传入多个路径 if os.path.isdir(newpath): #os.path.isdir()用于判断对象是否为一个目录 #os.path.isfile()用于判断对象是否为一个文件 print("目录:", newpath) dl.append(newpath) #在dl右端添加新的对象newpath else: #根据需要指定所需要打印的图片文件的后缀名,便于系统作出是否打印的判断 if newpath.split(".")[-1] in ['png', 'img', 'jpg', 'jpeg']: png_path_list.append(newpath) #根据需要指定所需要打印的文档文件的后缀名,便于系统作出是否打印的判断 elif newpath.split(".")[-1] in ['pdf', 'txt', 'xlsx', 'xls','md', 'doc','docx','pptx','ppt','docx']: pdf_path_list.append(newpath) return png_path_list, pdf_path_list if __name__ == '__main__': #指定所需要打印的文件目录: #path = r'd:\文件' #也可以手动输入需要打印的文件目录,便于用户灵活使用: path= input("请在英文输入法状态下输入文件目录,然后回车运行。文件目录:") #打印已经打印的文件路径及文件完成情况 Printer().printer_loading(path)

python如何打印表格 windows10操作系统下python实现多格式文件一键批量打印(5)

(代码预览效果图)

python如何打印表格 windows10操作系统下python实现多格式文件一键批量打印(6)

(代码执行效果)

细心的小伙伴运行代码后会发现一个问题,那就是pdf文件打印完毕之后,对应的PDF阅读软件并没有自动关闭。使用如下语句,即可实现打印完毕之后关闭对应的软件进程。

import os os.system("taskkill /F /IM AcroRd32.exe") #…… #当然你还可以添加很多你需要启动的软件

扩展,与关闭进程对应的就是打开软件进程

import win32api win32api.ShellExecute(0, 'open', r'D:\QQ\Bin\QQ.exe', '','',1) #…… #当然你还可以添加很多你需要启动的软件

如果有小伙伴能够将关闭进程的代码有机结合在print.py代码中合并执行,就能够实现py脚本运行的最佳体验效果了。欢迎小伙伴们一起进行探讨和交流学习,并将实现方法分享一下,大家共同学习与进步。

,