读取excel数据,根据word模板生成word文件。【python】【word vba】两种方法
生活随笔
收集整理的這篇文章主要介紹了
读取excel数据,根据word模板生成word文件。【python】【word vba】两种方法
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- 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() | 主程序:根據模板批量生成文件 |
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 Sub4、總結:
| python | 很好,可以在后臺生成 | 差,要控制速度,要不然可能會漏打或文字消失 | 單用【批量生成word文檔】功能就好,還是別打印了 |
| word vba | 不能在后臺生成,速度比python略慢,還是很快的 | very very 快!贊! | 就沖這打印速度,贊! |
5、PS:
如果有什么寫錯了的,歡迎指點
總結
以上是生活随笔為你收集整理的读取excel数据,根据word模板生成word文件。【python】【word vba】两种方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网站 smtp服务器,网站smtp服务器
- 下一篇: 基于Django的网上书城系统