一、功能介绍图、与插件界面
二、说明
功能介绍:
批量读取excel中的姓名,项目名称,批量渲染word文档并进行打印。
适用于各类奖状,荣誉证书的打印工作等。
1、系统要求windos10(7) 64位,并安装office2007以上版本
2、设备连接打印机
3、excel数据表格(2007以上版本,文件后缀为.xlsx):
第一列为姓名,第二列为项目(不带表头)
4、word打印模板(2007以上版本,文件后缀为docx):
a、对打印模板进行设计
b、使用{{name}}占位名字的位置
c、使用{{subject}}占位项目名称的位置
特别提示:占位符请设置好字体等格式
6、运行AutoPrint.exe进入自渲染批量打印:
1、选择Excel数据表格
2、选择Word模板文档
3、点击打印
7、具体excel数据表格、word模板文件可参考【data.xlsx】、【model.docx】
三、源码
第三方库pypiwin32、pfExcel(基于openpyxl封装便于更好的操作excel文件,博客中有源码不再列举。
利用tkinter做了一个简单的页面
(使用pyinstaller可编译为exe)
import os
from threading import Thread
import win32com.client
from docxtpl import DocxTemplate
from tkinter import Tk, Button, filedialog, messagebox, StringVar
from pfExcel import ExcelWork
class AP(Tk):
def __init__(self):
super().__init__()
# 选择Excel表格按钮字符串
self.bt_excel = StringVar()
self.bt_excel.set('请选择Excel表格')
# 选择Word模板按钮字符串
self.bt_word = StringVar()
self.bt_word.set('请选择Word模板')
# 打印按钮字符串
self.bt_print = StringVar()
self.bt_print.set('打印')
# Excel表格地址
self.excelPath = ''
# Word模板地址
self.wordPath = ''
# UI初始化
self.uiInit()
self.mainloop()
def uiInit(self):
# 屏幕宽度
sw = self.winfo_screenwidth()
# 屏幕高度
sh = self.winfo_screenheight()
# 窗口大小
ww = 280
wh = 180
# 计算显示位置(垂直水平居中)
x = (sw - ww) / 2
y = (sh - wh) / 2
self.geometry("%dx%d+%d+%d" % (ww, wh, x, y))
# 标题栏
self.title('自渲染批量打印')
# 图标
self.iconbitmap('logo.ico')
# 禁止缩放
self.resizable(0, 0)
# 选择Excel按钮
Button(self,
width=22,
height=1,
textvariable=self.bt_excel,
font=('', 14),
fg='green',
command=self.getExcelPath
).pack(pady=20)
# 选择Word按钮
Button(self,
width=22,
height=1,
textvariable=self.bt_word,
font=('', 14),
fg='blue',
command=self.getWordPath
).pack(pady=10)
# 打印按钮
Button(self,
width=6,
textvariable=self.bt_print,
font=('', 12),
command=self.autoPrintDom
).pack(pady=10)
def getExcelPath(self):
"""
获取excel表格地址
:return:
"""
self.excelPath = filedialog.askopenfilename()
# 判断地址是否为空
if self.excelPath:
# 判断后缀
if self.excelPath.split('.')[1] == 'xlsx':
messagebox.showinfo('提示', '选择成功')
self.bt_excel.set('Excel表格已选中')
else:
messagebox.showinfo('提示', '请选择后缀名为xlsx的文件')
else:
messagebox.showinfo('提示', '选择失败')
def getWordPath(self):
"""
获取Word模板地址
:return:
"""
self.wordPath = filedialog.askopenfilename()
# 判断地址是否为空
if self.wordPath:
# 判断后缀
if self.wordPath.split('.')[1] == 'docx':
messagebox.showinfo('提示', '选择成功')
self.bt_word.set('Word模板已选中')
else:
messagebox.showinfo('提示', '请选择后缀名为docx的文件')
else:
messagebox.showinfo('提示', '选择失败')
def autoPrintDom(self):
"""
关联打印按钮
:return:
"""
if self.wordPath != '' and self.excelPath != '':
if self.bt_print.get() == '打印':
self.bt_print.set('取消')
hd = Thread(target=self.handle)
# 子线程跟随主进程关闭
hd.daemon = True
hd.start()
else:
self.bt_print.set('打印')
else:
messagebox.showinfo('提示', '请选择Excel与Word')
def handle(self):
"""
打印处理线程
:return:
"""
# 读取excel数据
excelData = self.readExcel(self.excelPath)
for name, subject in excelData:
# 设置按钮显示日志
# 渲染word模板
ct = {
'name': name,
'subject': subject
}
self.renderWord(self.wordPath, 'd:\\temp.docx', ct)
self.bt_excel.set(name + '->渲染完成')
self.printWord('d:\\temp.docx')
os.remove('d:\\temp.docx')
self.bt_word.set(name + '->已加入打印序列')
if self.bt_print.get() == '打印':
# 初始化按钮字符串
self.bt_excel.set('请选择Excel表格')
self.bt_word.set('请选择Word模板')
break
messagebox.showinfo('提示', '已全部加入打印序列')
# 初始化按钮字符串
self.bt_print.set('打印')
self.bt_excel.set('请选择Excel表格')
self.bt_word.set('请选择Word模板')
@staticmethod
def readExcel(excelFilePath):
"""
读取excel表格
:param excelFilePath: excel文件路径
:return: [[行], ]
"""
excel = ExcelWork(excelFilePath)
data = []
for index, var in enumerate(excel.getColumn(1)):
data.append(excel.getRow(index + 1))
excel.close()
return data
@staticmethod
def renderWord(wordFilePath, newWordFilePath, cont):
"""
渲染word模板
:param wordFilePath: word文件路径
:param newWordFilePath: 新文件路径
:param cont: {渲染数据}
:return:
"""
tpl = DocxTemplate(wordFilePath)
tpl.render(cont)
tpl.save(newWordFilePath)
@staticmethod
def printWord(wordFilePath):
"""
打印word文件
:param wordFilePath: word文件路径
:return:
"""
tool = 'Word.Application'
# WPS tool = 'wps.application'
word = win32com.client.Dispatch(tool)
# 在后台运行程序
word.Visible = 0 # 后台运行,不显示
# 运行过程不警告
word.DisplayAlerts = 0 # 不警告
# 打开word文档
doc = word.Documents.Open(wordFilePath)
# 进行打印
doc.PrintOut()
doc.Close()
word.Quit()
if __name__ == '__main__':
AP()