文章目录

  • 1、背景
    • 首次签合同人员.xlsx
    • 模板:简易劳动合同.docx
  • 2、python代码
    • 问题
  • 3、word vba
    • 1) 根据模板批量生成文件
    • 2) 批量打印文件
  • 4、总结:
  • 5、PS:

1、背景

行政部的同事每次都要根据excel里面的信息,制作word版的劳动合同,然后他们有一天找到了我,问我可不可以帮忙。

首次签合同人员.xlsx

需要获取该表的【姓名】【证件号码】【岗位】【到职日期】

模板:简易劳动合同.docx

原来的word模板如下

因为用python的docxtpl批量修改就要把需要替换的地方用2个花括号+变量名。例如:{{name}},表示这个变量名是name.修改后word模板如下:

2、python代码

#-*-coding:utf-8-*-
from docxtpl import DocxTemplate
import xlrd#要1.2.0版本or其他可用版本!!!我下了个2.1.0的版本,打不开xlsx文件。
import os
import win32api,win32con,win32print,win32gui
import sys
from dateutil.relativedelta import relativedelta
import time
import shutildef printer_loading(filename):#用win32api.ShellExecute发送打印文件命令open(filename, "r")"""打开文件,这个只有open,没有close,所以会打开很多窗口。如果用with open我的电脑会出现“word还有对话框正在打开,不能强制关闭”的问题。如果不执行这一句,下面的打印命令发送了没反应???不知道是不是我的电脑有问题"""print("打开:",filename)time.sleep(3)#公司的电脑不行,要等待一下win32api.ShellExecute(0,"print",#执行【打印】操作filename,#文件路径'/d:"%s"' % win32print.GetDefaultPrinter(),#打印机设定:默认打印机".",0)def close_word():"""关闭多余的word窗口???大概是这个功能主要是我的电脑如果不关闭窗口,打开了15个窗口它就会出现问题,文字消失了!!!!我的微信、鼠标右键菜单等.....文字都消失了,不知道为啥"""while True:time.sleep(0.5)hwnd = win32gui.FindWindow("OpusApp", None)#找到word的句柄# print(hwnd)if hwnd == 0:#如果没有找到hwnd就说明没有word窗口了break# print("关闭",win32gui.GetWindowText(hwnd))win32gui.PostMessage(hwnd, win32con.WM_NULL, 0, 0)#发送关闭窗口的命令def message_exit(msg,exit=True):#弹窗+退出程序win32api.MessageBox(0, msg, "提示",win32con.MB_OK)if exit:win32api.MessageBox(0, "退出程序", "提示",win32con.MB_OK)sys.exit()def main():try:current_path = os.getcwd()#当前路径excel_path = os.path.join(current_path,"首次签合同人员.xlsx")#excel数据文件路径doc_path = os.path.join(current_path,"模板:简易劳动合同.docx")#word模板文件路径result_dir = os.path.join(current_path,"结果")#生成的文件放在这个文件夹里if not os.path.exists(excel_path):#是否找到工作簿message_exit("没有找到excel工作簿\n"+excel_path,exit=True)if not os.path.exists(doc_path):#是否找到word文件message_exit("没有找到word文件\n"+doc_path,exit=True)if  os.path.exists(result_dir):#当前文件夹下是否已经存在【结果】文件夹,如果存在,手动删除message_exit("请先手动删除结果文件夹\n程序退出" + result_dir, exit=True)os.makedirs(result_dir)#创建【结果】文件夹excel_content = []workbook = xlrd.open_workbook(excel_path)if  not "首次简易合同人员" in workbook.sheet_names():#看看是不是有【首次简易合同人员】这个sheetmessage_exit("没有找到excel工作簿中的【首次简易合同人员】工作表,请把sheet的名称改为“首次简易合同人员”" , exit=True)data = workbook.sheet_by_name("首次简易合同人员")data_row = data.nrows#总行数for i in range(data_row):if i == 0:#第一行是标题,略过continue#处理时间:入职时间yyyy/m/d --> 入职年月日和合同到期1年后的年月日time1 = xlrd.xldate_as_datetime(data.cell(i, 7).value,0)year1 = time1.strftime("%Y-%m-%d")year2 = (time1 + relativedelta(years=1)).strftime("%Y-%m-%d")y1 = year1.split("-")[0]m1 = year1.split("-")[1]d1 = year1.split("-")[2]y2 = year2.split("-")[0]m2 = year2.split("-")[1]d2 = year2.split("-")[2]content = {'name': data.cell(i,1).value,'idcard': data.cell(i,4).value,'y1':y1,'m1':m1,'d1':d1,'y2': y2,'m2': m2,'d2': d2,'work': data.cell(i,6).value}if i < 10:#这个是因为文件名是根据字符串排序的,所以小于10要加0n="0" + str(i)else:n=str(i)excel_content.append([content,n])#n不放在content里,是因为content都是要修改的内容,到时候直接rander就可以了,而n不是要修改的内容,是文件名,方便排序# print(excel_content)for context,n in excel_content:doc = DocxTemplate(doc_path)#指定文件doc.render(context)#渲染文件doc.save(os.path.join(result_dir ,n+context["name"] + context["idcard"]  + ".docx"))#保存文件is_print = win32api.MessageBox(0, "word已生成\n是否现在打印????\n打印的话可能会卡,请耐心", "是否打印", win32con.MB_YESNO)#询问是否打印if is_print == 6:#如果点击yesis_printer = win32api.MessageBox(0, "打印机是"+win32print.GetDefaultPrinter()+"\n如果不是这个打印机,请把你想要打印的打印机设置为默认打印机!!!", "默认打印机", win32con.MB_YESNO)#询问默认打印机if is_printer == 6:#如果点击yesn=0files_dir_list = os.listdir(os.path.join(os.getcwd(),"结果"))#遍历当前文件夹下的【结果】文件夹里的文件time_start = time.time()#开始时间for files in files_dir_list:print("="*30)n = n+1if n !=1:print("正在打印:第",n,"个文件,共",len(excel_content),"个文件\n剩余时间:"+str(round((time.time()-time_start)/60/n*(len(excel_content)-n),2)) + "分钟")#这个时间不是很准if n % 5 == 0:#每发送5次命令的时候,把word窗口清理一次。如果太大,我的电脑会漏打几个文件close_word()printer_loading(os.path.join(result_dir,files))close_word()#全部结束了,再执行一次关闭word窗口message_exit("请等待打印机加载好了再点击!!!!!!!\n要不然会有没打印完的文件!!!!!!!", exit=False)#因为发送命令比打印快,所以程序完成的时候并不是所有文件都加载到打印列队了elif is_printer == 7:#如果点击了nopasspasselif is_print == 7:#如果点击了nopassmessage_exit("完成!",exit=True)except Exception as err:message_exit("发生错误:\n{}\n请拍照联系开发人员".format(err),exit=True)if __name__ == '__main__':main()

问题

我用printer_loading(),如果命令发送太快不加控制的话,我电脑上就会有很多word窗口。
问题不严重就是漏打。
问题如果很严重,那就会微信等软件、鼠标右键菜单、word、弹窗大部分文字都消失。

3、word vba

1) 根据模板批量生成文件

程序/函数 作用
FileFolderExists() 函数:判断文件或文件夹是否存在
read_excel() 程序:读取excel数据,放到公共变量里
replace(old_text, new_text) 程序:用录制宏录制的【替换】操作,变量:旧文字、新文字
make_contract() 主程序:根据模板批量生成文件
Public excel_content(1 To 1000, 1 To 8)
Public current_path As StringPublic Function FileFolderExists(strFullPath As String) As Boolean '判断文件or文件夹是否存在,复制粘贴别人的On Error GoTo EarlyExitIf Not Dir(strFullPath, vbDirectory) = vbNullString Then FileFolderExists = True
EarlyExit:On Error GoTo 0
End FunctionSub read_excel()Dim ExcelApp As ObjectDim mybook As ObjectDim mysheet As ObjectDim excel_rowsApplication.ScreenUpdating = FalseIf Tasks.Exists("Microsoft Excel") = True ThenTasks("Microsoft Excel").CloseEnd IfSet ExcelApp = CreateObject("Excel.Application")Set mybook = ExcelApp.Workbooks.Open(current_path & "\首次签合同人员.xlsx") '链接工作簿Set mysheet = mybook.worksheets("首次简易合同人员") '链接工作表With mysheetexit_row_for = FalseFor Row = 2 To 1000'因为range好像不能用,所以只能循环了If exit_row_for = True Then '循环的控制开关Exit ForEnd IfFor col = 1 To 8If .Cells(Row, col) = "" Thenexit_row_for = TrueExit ForEnd Ifexcel_content(Row - 1, col) = .Cells(Row, col)NextNextEnd WithApplication.ScreenUpdating = True
End SubSub replace(old_text, new_text) '用录制宏录制的【替换】操作,变量:旧文字、新文字Selection.Find.ClearFormattingSelection.Find.Replacement.ClearFormattingWith Selection.Find.Text = old_text.Replacement.Text = new_text.Forward = True.Wrap = wdFindContinue.Format = False.MatchCase = False.MatchWholeWord = False.MatchByte = True.MatchWildcards = False.MatchSoundsLike = False.MatchAllWordForms = FalseEnd WithSelection.Find.Execute replace:=wdReplaceAll
End SubSub make_contract()current_path = ActiveDocument.Path '当前文件夹路径If FileFolderExists(current_path & "\结果") Then '判断是不是有【结果】文件夹MsgBox "请先删除【" & current_path & "\结果】文件夹"Exit SubEnd IfMkDir current_path & "\结果" '创建【结果】文件夹Dim nian As Integer '合同有1年期和3年期的,我直接让他自己输入nian = InputBox("请问合同是几年的?" & Chr(13) & "请输入数字:123....")Application.ScreenUpdating = FalseCall read_excel '读取excel数据Dim cuurent_doc As ObjectFor i = 1 To UBound(excel_content, 1)If excel_content(i, 1) = "" Then '如果是空的,说明已经到底了,就退出程序Exit ForEnd IfSet currnet_doc = Documents.Open(FileName:=current_path & "\模板:简易劳动合同.docx")If excel_content(i, 1) < 10 Then '如果序号小于10,那要加个0,方便文件名按字符串排序Num = "0" & excel_content(i, 1)ElseNum = excel_content(i, 1)End Ifcurrnet_doc.SaveAs (current_path & "\结果\" & Num & excel_content(i, 2) & excel_content(i, 5) & ".docx") '另存为With current_doc'处理日期date1 = Format(excel_content(i, 8), "yyyy/mm/dd")date2 = Format(DateAdd("yyyy", nian, date1), "yyyy/mm/dd")date1_arr = Split(date1, "/")date2_arr = Split(date2, "/")'替换Call replace("{{name}}", excel_content(i, 2))Call replace("{{idcard}}", excel_content(i, 5))Call replace("{{work}}", excel_content(i, 7))Call replace("{{y1}}", date1_arr(0))Call replace("{{y2}}", date2_arr(0))Call replace("{{m1}}", date1_arr(1))Call replace("{{m2}}", date2_arr(1))Call replace("{{d1}}", date1_arr(2))Call replace("{{d2}}", date2_arr(2))End Withcurrnet_doc.Savecurrnet_doc.CloseSet currnet_doc = NothingNextApplication.ScreenUpdating = TrueMsgBox "完成:" & Chr(13) & "生成的文件在【" & current_path & "\结果】文件夹下"
End Sub

2) 批量打印文件

Sub print_doc() '批量打印【结果】文件夹下的文档
'Application.ActivePrinter = sr2
Application.ScreenUpdating = False'询问打印机:如果不是的话,要在【开始】->【打印】那里选择了打印机后在运行
msg = MsgBox("当前活动打印机是:" & Chr(13) & ActivePrinter & Chr(13), vbInformation + vbOKCancel)
If msg = 2 Then
MsgBox "请稍后再来"
Exit Sub
Else
End IfC = 0
On Error Resume Next  '有错继续current_path = ActiveDocument.Path '当前文件夹路径
Set fso = CreateObject("Scripting.filesystemobject") '取目标文件
Set myf = fso.getfolder(current_path & "\结果")
n = InputBox("请问每个文件要打印几份" & Chr(13) & "请输入数字:123.....") '询问要打印几份For Each i In myf.Files '开始打开文件C = C + 1 '计数Application.PrintOut FileName:=i.Path, Range:=wdPrintAllDocument, Item:= _wdPrintDocumentWithMarkup, Copies:=n, Pages:="", PageType:= _wdPrintAllPages, Collate:=True, Background:=True, PrintToFile:=False, _PrintZoomColumn:=0, PrintZoomRow:=0, PrintZoomPaperWidth:=0, _PrintZoomPaperHeight:=0 '两个变量:i.path打印路径和n打印几份
NextMsgBox "完成:" & Chr(13) & "共" & C & "个文件"  '提示文件个数
Application.ScreenUpdating = True
End Sub

4、总结:

语言 批量生成word文档 批量打印 总评
python 很好,可以在后台生成 差,要控制速度,要不然可能会漏打或文字消失 单用【批量生成word文档】功能就好,还是别打印了
word vba 不能在后台生成,速度比python略慢,还是很快的 very very 快!赞! 就冲这打印速度,赞!

5、PS:

如果有什么写错了的,欢迎指点

读取excel数据,根据word模板生成word文件。【python】【word vba】两种方法相关推荐

  1. 生成多文件的Assembly 的两种方法

    VS不支持将多文件Assembly生成, 使用命令行完成 方法1:生成一个不带manifest的.netmodule和一个带mainfest的.dll 两个源文件 RUT.cs contain rar ...

  2. 使用MyBatis Generator自动生成持久层CRUD代码的两种方法

    最近在使用MyBatis,得知可以利用MyBatis Generator自动生成实体类.DAO接口和Mapping映射文件.当数据库中的表多的时候,让你不用再手写Mapping映射文件,和实体类,就可 ...

  3. yii2 php 生成小程序分享海报的两种方法

    前段时间做了个小程序-爱小环保,现在要给它加一个生成海报分享朋友圈的功能. 先简单介绍下这个小程序,主要是号召大家随手捡垃圾,如果你在马路上见到别人随手丢的垃圾,可以将它拍下来,然后丢到垃圾桶,拍下来 ...

  4. Excel信息批量替换Word模板生成新文件

    Python批量处理Excel文件信息替换Word模板 原由和思路 工具准备 1. 前期处理 1.1 数据处理 1.2 模板处理 2. 编写代码 2.1 使用Pycharm新建项目ExcelToWor ...

  5. java word 读取excel数据_在Java中实现读写操作Word、Excel等文件

    Jakarta的POI项目提供了一组操纵Windows文档的Java API,如下几个类提供了操作Excel文件的方便的途径:HSSFWorkbook.HSSFSheet.HSSFRow.HSSFCe ...

  6. 根据word模板生成pdf文件

    1.首先建一个word,插入一个表格,需要填充的值用${parame}代替 (注意:这里的参数要和java实体类里面的参数对应起来,代码放在下面) 2.制作完成后另存为xml格式 3.然后用文本编辑工 ...

  7. Unity读取excel 数据 并创建对应的json文件

    https://download.csdn.net/download/jinxiul5/85188120 工具下载链接是 : https://download.csdn.net/download/ji ...

  8. 数据湖 数据仓库 数据集市_还原数据仓库/数据集市环境的两种方法

    数据湖 数据仓库 数据集市 Implementing best data warehouse designs and practices such as data lineage reduces th ...

  9. Office Excel阅读模式(记忆和高亮选中的单元格)的两种方法

    金山WPS上非常好用的阅读模式,到了微软Office上就就没有了,很是心痛. 然而网上搜到的Office阅读模式,要么需要用到插件(比如"方方格子"的"聚光灯" ...

  10. python中文件的存储类型_关于python中数据存储大总结,涵盖文件系统和数据库存储两种方法-文件系统类型...

    存储数据是python必不可免的话题,数据的存储类型也多种多样,文件系统存储(.txt..csv..json.多媒体存储).关系型数据库存储(MySQL等).非关系型数据库存储(MongoDB).今天 ...

最新文章

  1. Mac OS X 安装教程
  2. 十分钟掌握pyecharts十类顶级图,都很实用!
  3. (四)数据结构之“队列”
  4. 1.0jpa 2.0_JPA 2.1类型转换器–持久枚举的更好方法
  5. php 发送短信 sms,php 调用百度sms来发送短信的实现示例
  6. 基于 Springboot 和 Mybatis 的后台管理系统 BootD
  7. 由旋转矩阵计算欧拉角的方法
  8. 再获信通院权威认证,优等生华为云GaussDB数据库凭什么?
  9. PCL之点云坐标系空间转换
  10. (三)java版spring cloud+spring boot 社交电子商务平台 - Spring Cloud集成项目简介
  11. 怎么用PDF转换器将PDF文件转成txt
  12. 《天才在左、疯子在右》随笔
  13. QT图形显示和处理1
  14. 文件关联修复命令ftype用法
  15. 未来人类殡葬一览:太空中正飘着上千个骨灰盒
  16. 爸爸妈妈儿子女儿吃水果问题以及五个哲学家吃饭问题
  17. https防止注入_离子注入新法,将钢的耐磨性提高百倍
  18. 中原银行实时风控体系建设实践
  19. 全能编码器Mencoder(mencoder.exe)命令行用法
  20. poi在pptx中动态刷新已经存在的图

热门文章

  1. RayData学习总结
  2. docker阿里云镜像加速器
  3. matlab/simulink实现QPSK调制和解调实验
  4. python中wordcloud函数不同形状云图_Python实现Wordcloud生成词云图的示例
  5. oracle数据导出工具sqluldr2安装及使用
  6. 从Gauss-Newton算法到 LM算法 (详细推导及MATLAB实现、多自变量问题)
  7. 线上展示3D可视化电子沙盘管理系统
  8. 分区桌面背景制作方法-EXCEL
  9. 《FLUENT 14流场分析自学手册》——导读
  10. PaddleNLP--UIE(二)--小样本快速提升性能(含doccona标注)