用python將word文檔合并實(shí)例代碼
背景:
? ? ? ? 由于工作需要,現(xiàn)在有這么一個(gè)需求,要合并大量的word文檔,而且要在不同的目錄下找到同一個(gè)人的word文檔,進(jìn)行合并,最終輸出一個(gè)合并后的word文檔。一般來說幾個(gè)或者十幾個(gè)量不多的話,就手工合并一下好了,但現(xiàn)在這個(gè)量是真的大。目錄有十多個(gè),每個(gè)目錄又有50多個(gè)不同人的word文檔,而且同一個(gè)人在不同目錄下又不一定都有word文檔,因此,整個(gè)合并工作就出現(xiàn)了人工操作的困難:
工作量多;容易疏漏犯錯(cuò)。
?為此,利用python進(jìn)行高效準(zhǔn)確的執(zhí)行這類工作,尤為凸顯現(xiàn)代自動(dòng)化辦公的能力。因此,我寫了這個(gè)python腳本,作為一個(gè)小工具來輔助我的工作需求。
設(shè)計(jì)思路:
? ? ? ? 首先,整個(gè)腳本實(shí)現(xiàn)兩個(gè)功能:
查看各目錄下未提交word文檔的名單合并各目錄下的word文檔查看各目錄未提交名單:
? ? ? ? 對(duì)于這個(gè)需求,首先是讀一個(gè)寫有所有人姓名等信息的Excel文件,有格式要求。然后通過遍歷Excel的信息,獲取到所有人的姓名。遍歷各目錄下,是否有對(duì)應(yīng)姓名的文件存在,如果沒有,則輸出沒有提交文件的姓名。
合并word文件:
? ? ? ? 合并word文件和上一個(gè)需求有類似的地方。首先我們都需要讀Excel文件,得到姓名信息,然后在各目錄下獲取到這個(gè)人所提交的所有word文件的文件路徑,然后通過合并word的操作實(shí)現(xiàn)文件合并,合并后最終輸出到指定的目錄下。
腳本環(huán)境說明:
? ? ? ? 腳本對(duì)第三方包有依賴,執(zhí)行前必須先安裝對(duì)應(yīng)的第三方包
pip install python-docx pywin32 xlrd
? ? ? ??首先,目錄結(jié)構(gòu)必須是如下圖所示,所有需要遍歷的目錄名稱都必須是【實(shí)訓(xùn)+數(shù)字】,因?yàn)槟_本中涉及多處正則匹配。
? ? ? ? 其次,Excel文件必須遵循下圖所示的格式,首行是標(biāo)題行,遍歷的時(shí)候會(huì)自動(dòng)跳過,遍歷時(shí)會(huì)遍歷C列和D列,其中C列是人員編號(hào),D列是人員姓名
?
? ? ? ? 接著,python腳本必須要根目錄下
? ? ? ? 最后,執(zhí)行腳本的時(shí)候,必須帶有傳參,傳遞的參數(shù)就是那個(gè)Excel表
Microsoft Windows [版本 10.0.19043.1415] (c) Microsoft Corporation。保留所有權(quán)利。 C:\Windows\system32>python tools.py 花名冊(cè).xlsx
完整代碼:
#! /usr/bin env python # -*- coding:utf-8 -*- """ ============================ ======Power By Python3====== ====== Author Task138 ====== ============================ """ import sys import xlrd, os, re from docx import Document from docxcompose.composer import Composer from win32com import client as wc # 讀Excel表獲取學(xué)生的學(xué)號(hào)和姓名 def read_excel(excel_file): workbook = xlrd.open_workbook(excel_file) sheet = workbook.sheet_by_index(0) name_list = [] name_dict = [] Sno_list = sheet.col_values(2)[1::] Sname_list = sheet.col_values(3)[1::] for i in range(len(Sno_list)): try: Sno = str(int(Sno_list[i])) except: Sno = Sno_list[i] dict = {} dict['Sno'] = Sno dict['Sname'] = Sname_list[i] name_list.append(Sname_list[i]) name_dict.append(dict) return name_list, name_dict # 合并文檔 def merge_doc(source_file_path_list,target_file_path): #填充分頁符號(hào)文檔 page_break_doc = Document() page_break_doc.add_page_break() #定義新文檔 target_doc = Document(source_file_path_list[0]) target_composer = Composer(target_doc) for i in range(len(source_file_path_list)): #跳過第一個(gè)作為模板的文件 if i==0: continue #填充分頁符文檔 target_composer.append(page_break_doc) #拼接文檔內(nèi)容 f = source_file_path_list[i] target_composer.append(Document(f)) #保存目標(biāo)文檔 target_composer.save(target_file_path) print('[ %s ]保存成功' % target_file_path) if __name__ == '__main__': if len(sys.argv) < 2: print('缺乏必要的參數(shù),請(qǐng)輸入學(xué)生Excel表作為參數(shù)') print('程序終止') exit() excel_file = sys.argv[1] print('請(qǐng)選擇需要執(zhí)行的功能:') print('[ 0 ] 查看各實(shí)訓(xùn)目錄下未提交的學(xué)生名單') print('[ 1 ] 合并實(shí)訓(xùn)文件') cmd = input('請(qǐng)選擇: ') while cmd not in ['0','1']: print('輸入有誤,請(qǐng)重新輸入,按 Ctrl+C 可退出程序') print('請(qǐng)選擇需要執(zhí)行的功能:') print('[ 0 ] 查看各實(shí)訓(xùn)目錄下未提交的學(xué)生名單') print('[ 1 ] 合并實(shí)訓(xùn)文件') cmd = input('請(qǐng)選擇: ') try: name_list, name_dict = read_excel(excel_file) except Exception as e: print('Excel讀取失敗,程序終止,錯(cuò)誤如下:') print(e) print() exit() else: if cmd == '0': # 實(shí)訓(xùn)目錄的數(shù)列 file_list = [] for i in os.listdir(): if os.path.isdir(i): if re.match(r'實(shí)訓(xùn)\d', i): file_list.append(i) for i in range(1, len(file_list) + 1): dir_name = '實(shí)訓(xùn)%s' % i # 進(jìn)入該實(shí)訓(xùn)目錄 os.chdir(dir_name) file_list = os.listdir() submit_list = [] for x in file_list: for j in name_list: if j in x and j not in submit_list: submit_list.append(j) result = list(set(submit_list) ^ set(name_list)) if result: print(dir_name, result) os.chdir('../') if cmd == '1': if not os.path.exists('實(shí)訓(xùn)匯總'): os.mkdir('實(shí)訓(xùn)匯總') print('目錄[ 實(shí)訓(xùn)匯總 ]創(chuàng)建成功') # 實(shí)訓(xùn)目錄的數(shù)列 file_list = [] for i in os.listdir(): if os.path.isdir(i): if re.match(r'實(shí)訓(xùn)\d',i): file_list.append(i) for i in name_dict: doc_list = [] for j in range(1,len(file_list)+1): dir_name = '實(shí)訓(xùn)%s' % j # 進(jìn)入該實(shí)訓(xùn)目錄 os.chdir(dir_name) tmp = [] for x in os.listdir(): # 判斷文件尾綴 fname,fext = os.path.splitext(x) # 如果是.doc,則轉(zhuǎn)換為.docx if fext == '.doc' and not x.startswith('~$'): w = wc.Dispatch('Word.Application') doc = w.Documents.Open(os.path.abspath(x)) doc.SaveAs(os.path.join(os.getcwd(),'%s.docx' % fname), 16) doc.Close() os.remove(x) print('轉(zhuǎn)換文件[ %s ]類型為.docx' % x) elif fext == '.docx': if (i['Sname'] in x) and (len(tmp) == 0): # 只有一個(gè)文件 tmp.append(x) elif (i['Sname'] in x) and (len(tmp) != 0): # 有多個(gè)文件,按照最新的修改時(shí)間進(jìn)行替換 tmp_file = tmp.pop() old_file_mtime = os.path.getmtime(tmp_file) new_file_mtime = os.path.getmtime(x) if new_file_mtime > old_file_mtime: # 新文件比較新,以新的為準(zhǔn) tmp.append(x) else: # 老文件比較新,以老文件為準(zhǔn) tmp.append(tmp_file) else: # 其它文件類型,直接跳過 # print('當(dāng)前文件[ %s ]類型不是.doc或者.docx,跳過此文件的合并' % os.path.abspath(x)) continue if tmp: # 如果這次實(shí)訓(xùn)有這位同學(xué)的文件 doc_list.append(os.path.join(dir_name,tmp.pop())) # 返回父目錄 os.chdir('../') if doc_list: # 有內(nèi)容,進(jìn)行文檔合并 try: merge_file_name = i['Sno'] + '-' + i['Sname'] + '-' + '實(shí)訓(xùn)匯總' + '.docx' merge_doc(doc_list, './實(shí)訓(xùn)匯總/' + merge_file_name) except Exception as e: print() print('[ %s ]學(xué)生信息有誤,程序中斷' % i['Sname']) print(e) print()
功能執(zhí)行效果圖:
總結(jié):
通過python,我們可以很便捷的滿足我們的需求,鑒于這個(gè)需求似乎是長(zhǎng)期性的,所以還是有必要寫個(gè)小工具來優(yōu)化一下自己的辦公方式,提高自己的業(yè)務(wù)能力。
到此這篇關(guān)于用python將word文檔合并實(shí)例代碼的文章就介紹到這了,更多相關(guān)python word文檔合并內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解pandas中利用DataFrame對(duì)象的.loc[]、.iloc[]方法抽取數(shù)據(jù)
這篇文章主要介紹了pandas中利用DataFrame對(duì)象的.loc[]、.iloc[]方法抽取數(shù)據(jù),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12python使用requests庫爬取拉勾網(wǎng)招聘信息的實(shí)現(xiàn)
這篇文章主要介紹了python使用requests庫爬取拉勾網(wǎng)招聘信息的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11用實(shí)例詳解Python中的Django框架中prefetch_related()函數(shù)對(duì)數(shù)據(jù)庫查詢的優(yōu)化
這篇文章主要介紹了用實(shí)例詳解Python中的Django框架中prefetch_related()函數(shù)對(duì)數(shù)據(jù)庫查詢的優(yōu)化,可減少對(duì)數(shù)據(jù)庫的查詢次數(shù)從而優(yōu)化性能,需要的朋友可以參考下2015-04-04簡(jiǎn)單了解python 生成器 列表推導(dǎo)式 生成器表達(dá)式
這篇文章主要介紹了簡(jiǎn)單了解python 生成器 列表推導(dǎo)式 生成器表達(dá)式,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-08-08python使用threading獲取線程函數(shù)返回值的實(shí)現(xiàn)方法
這篇文章主要介紹了python使用threading獲取線程函數(shù)返回值的實(shí)現(xiàn)方法,需要的朋友可以參考下2017-11-11Python 處理數(shù)據(jù)的實(shí)例詳解
這篇文章主要介紹了Python 處理數(shù)據(jù)的實(shí)例詳解的相關(guān)資料,這里主要介紹Python 常用的基礎(chǔ)知識(shí)并附實(shí)例,需要的朋友可以參考下2017-08-08