
python確實(shí)是一款很實(shí)用的數(shù)據(jù)分析工具,尤其是在處理重復(fù)性工作方面。小編今天給大家推薦的這篇文章就是關(guān)于python自動化處理合同的,希望能幫助大家解放雙手,實(shí)現(xiàn)合同的自動化處理。
文章來源: 早起Python
作者:陳熹
大家好,又到了Python辦公自動化系列。
今天我們繼續(xù)分享一個真實(shí)的辦公自動化需求:如何使Python+Excel+Word批量生成指定格式內(nèi)容的合同。
主要涉及的知識點(diǎn)有:openpyxl模塊的綜合運(yùn)用與Word文檔的兩種遍歷邏輯。
你是乙方建筑公司,手上有一份空白合同模板的Word文件,如下圖:
另外還有一份Excel合同信息表,其中是所有甲方(發(fā)包人)在合同中需要填寫的內(nèi)容
可見一行為一個公司的全部信息,現(xiàn)在需要把Excel中每一個公司的信息填入空白Word合同模板中,生成各公司的合同,最終結(jié)果如下
原本我們需要將Excel匯總表中每一行的信息填進(jìn)word模板中,生成相應(yīng)的合同。
現(xiàn)在我們需要交給Python來實(shí)現(xiàn),就引出了一個問題:程序如何知道要將某個信息填到哪個下劃線? 為了解決這個問題,我們需要對模板進(jìn)行修改。
即將下劃線改成某種標(biāo)識,讓程序可以看到標(biāo)識就明白此處應(yīng)該放什么信息,這里采取的策略是:將需要填寫的下劃線改成匯總表中的列名,即下圖所示
這樣程序就可以識別需要填寫什么內(nèi)容了。所謂的識別在這里可以換一個特別簡單的詞,即文本替換。只要檢索到#xxxx#(excel中的列名),把這個替換成具體的信息就可以了。
出于這種策略,列名就需要用#xxxx#的格式,否則正常的無關(guān)文本中的信息也會被替換,就破壞了原有的需求,最后模板被修改成如下:
通過Excel表我們可以看到,一行為一個公司的信息,而每一列的列名就存在于模板中,用各個公司的實(shí)際信息替換到模板中的列名(程序識別和文本替換的依據(jù))
用這樣的方法就可以完成這個需求。整個大需求的實(shí)現(xiàn)可以按照下面的步驟:
分析后的步驟:
將 空白合同 調(diào)整成 合同模板,需要填寫的下劃線改成專屬的列名
打開Excel表,按行循環(huán),然后按單元格逐個循環(huán)各個信息,每個信息都找到模板中存在的對應(yīng)列名并將其替換(如果不理解下文還有解釋)
每次循環(huán)完一行的全部單元格后保存合同,生存各個公司單獨(dú)的合同
分析清楚后邏輯就非常簡單了,但有一個隱含的知識點(diǎn)沒有提到,讓我們邊寫代碼邊說!
首先導(dǎo)入模塊,設(shè)置路徑,建立文件夾,本例中涉及Excel表的打開和Word的創(chuàng)建,因此需要從openpyxl導(dǎo)入load_workbook,而Word無論打開還是創(chuàng)建,用docx模塊的Document均可
from docx import Document from openpyxl import load_workbook # 利用os模塊建立文件夾,用于存放生成的合同 import os # 給定合同模板和匯總表所在的文件夾路徑,方便復(fù)用 path = r'C:\Users\chenx\Desktop\合同' # 結(jié)合路徑判斷生成文件夾,規(guī)避程序報錯而終止的風(fēng)險 if not os.path.exists(path + '/' + '全部合同'): os.mkdir(path + '/' + '全部合同')
接著打開Excel文件
workbook = load_workbook(path + '/' + '合同信息表.xlsx') sheet = workbook.active
現(xiàn)在遍歷Excel,生成合同。前面也反復(fù)提到,Excel的每一行是一份特定合同的信息,因此docx針對Word文件的實(shí)例化和保存一定是在循環(huán)體里的,而不像Excel的實(shí)例化是在循環(huán)體外面
# 有效信息行是從第二行開始的,第二行是表頭,包含列名,也是文本替換的依據(jù) for table_row in range(2, sheet.max_row + 1): # 每循環(huán)一行實(shí)例化一個新的word文件 wordfile = Document(path + '/' + '合同模板.docx') # 單元格需要逐個遍歷,每一個都包含著有用的信息 for table_col in range(1, sheet.max_column + 1): # 舊的文本也就是列名,已經(jīng)在模板里填好了,用于文本替換,將row限定在第一行后就是列名 old_text = str(sheet.cell(row=1, column=table_col).value) # 新的文本就是實(shí)際的信息,table_col循環(huán)到某個數(shù)值時,實(shí)際的單元格和列名就確定了 new_text = str(sheet.cell(row=table_row, column=table_col).value) # 加上這個判斷是因?yàn)槿掌谛畔⒆x進(jìn)程序是“日期 時間”格式的,如果要保留日期信息可以用字符串方法或者用time/datetime模塊處理 if ' ' in new_text: new_text = new_text.split()[0]
通過下圖進(jìn)一步理解這個替換:
例如程序已經(jīng)進(jìn)入第3個循環(huán)(循環(huán)到第3個公司),針對單元格的循環(huán)進(jìn)入第4個循環(huán),那么此時獲取的實(shí)際值是建設(shè)C公園,對應(yīng)的列名是#工程內(nèi)容#。
此時就明確了需要被替換的內(nèi)容了,只要在模板中找到#工程內(nèi)容#把它替換為建設(shè)C公園即可!了解了這個替換后,下一步就是遍歷Word模板,找到對應(yīng)列名替換!
之前我們說過docx模塊,Word文本存在文檔Document-段落Paragraph-文字塊Run的三級結(jié)構(gòu),需要遍歷文本可以用以下代碼:
all_paragraphs = wordfile.paragraphs for paragraph in all_paragraphs: print(paragraph.text) for run in paragraph.runs: print(run.text)
針對段落和文字塊均可用.text獲取到文字信息。本需求隱含的陷阱就在這里,注意一下合同最后需要填寫的內(nèi)容:
這部分內(nèi)容如果用上述代碼是遍歷不到的。為什么?因?yàn)檫@是Word文檔中的表格!
遍歷表格需要有專門的遍歷邏輯:文檔Document-表格Table-行Row/列Column-單元格Cell,遍歷表格中文本的代碼如下:
all_tables = wordfile.tables for table in all_tables: # 也可按列遍歷 for row in table.rows: for cell in row.cells: print(cell.text)
有了這些補(bǔ)充的知識之后,本案例中最核心的代碼就可以這么寫
for table_row in range(2, sheet.max_row + 1): wordfile = Document(path + '/' + '合同模板.docx') for table_col in range(1, sheet.max_column + 1): old_text = str(sheet.cell(row=1, column=table_col).value) new_text = str(sheet.cell(row=table_row, column=table_col).value) if ' ' in new_text: new_text = new_text.split()[0] # 文檔Document - 段落Paragraph - 文字塊Run all_paragraphs = wordfile.paragraphs for paragraph in all_paragraphs: for run in paragraph.runs: run.text = run.text.replace(old_text, new_text) # 文檔Document - 表格Table - 行Row/列Column - 單元格Cell all_tables = wordfile.tables for table in all_tables: for row in table.rows: for cell in row.cells: cell.text = cell.text.replace(old_text, new_text) # 獲取公司名用以生成合同的名稱 company = str(sheet.cell(row=table_row, column=1).value) wordfile.save(path + '/' + f'全部合同/{company}合同.docx')
本次的案例具有較強(qiáng)的實(shí)用性,并且需求可以延伸成為:將一份信息匯總表Excel中的每一個單獨(dú)信息(每一行或者每一列為個人、公司或者其他的信息)填寫到指定的模板Eord中,生成單獨(dú)的文檔,不過在寫自動化腳本之前也要先拆分任務(wù),明確思路再進(jìn)行!
數(shù)據(jù)分析咨詢請掃描二維碼
若不方便掃碼,搜微信號:CDAshujufenxi
SQL Server 中 CONVERT 函數(shù)的日期轉(zhuǎn)換:從基礎(chǔ)用法到實(shí)戰(zhàn)優(yōu)化 在 SQL Server 的數(shù)據(jù)處理中,日期格式轉(zhuǎn)換是高頻需求 —— 無論 ...
2025-09-18MySQL 大表拆分與關(guān)聯(lián)查詢效率:打破 “拆分必慢” 的認(rèn)知誤區(qū) 在 MySQL 數(shù)據(jù)庫管理中,“大表” 始終是性能優(yōu)化繞不開的話題。 ...
2025-09-18CDA 數(shù)據(jù)分析師:表結(jié)構(gòu)數(shù)據(jù) “獲取 - 加工 - 使用” 全流程的賦能者 表結(jié)構(gòu)數(shù)據(jù)(如數(shù)據(jù)庫表、Excel 表、CSV 文件)是企業(yè)數(shù)字 ...
2025-09-18DSGE 模型中的 Et:理性預(yù)期算子的內(nèi)涵、作用與應(yīng)用解析 動態(tài)隨機(jī)一般均衡(Dynamic Stochastic General Equilibrium, DSGE)模 ...
2025-09-17Python 提取 TIF 中地名的完整指南 一、先明確:TIF 中的地名有哪兩種存在形式? 在開始提取前,需先判斷 TIF 文件的類型 —— ...
2025-09-17CDA 數(shù)據(jù)分析師:解鎖表結(jié)構(gòu)數(shù)據(jù)特征價值的專業(yè)核心 表結(jié)構(gòu)數(shù)據(jù)(以 “行 - 列” 規(guī)范存儲的結(jié)構(gòu)化數(shù)據(jù),如數(shù)據(jù)庫表、Excel 表、 ...
2025-09-17Excel 導(dǎo)入數(shù)據(jù)含缺失值?詳解 dropna 函數(shù)的功能與實(shí)戰(zhàn)應(yīng)用 在用 Python(如 pandas 庫)處理 Excel 數(shù)據(jù)時,“缺失值” 是高頻 ...
2025-09-16深入解析卡方檢驗(yàn)與 t 檢驗(yàn):差異、適用場景與實(shí)踐應(yīng)用 在數(shù)據(jù)分析與統(tǒng)計(jì)學(xué)領(lǐng)域,假設(shè)檢驗(yàn)是驗(yàn)證研究假設(shè)、判斷數(shù)據(jù)差異是否 “ ...
2025-09-16CDA 數(shù)據(jù)分析師:掌控表格結(jié)構(gòu)數(shù)據(jù)全功能周期的專業(yè)操盤手 表格結(jié)構(gòu)數(shù)據(jù)(以 “行 - 列” 存儲的結(jié)構(gòu)化數(shù)據(jù),如 Excel 表、數(shù)據(jù) ...
2025-09-16MySQL 執(zhí)行計(jì)劃中 rows 數(shù)量的準(zhǔn)確性解析:原理、影響因素與優(yōu)化 在 MySQL SQL 調(diào)優(yōu)中,EXPLAIN執(zhí)行計(jì)劃是核心工具,而其中的row ...
2025-09-15解析 Python 中 Response 對象的 text 與 content:區(qū)別、場景與實(shí)踐指南 在 Python 進(jìn)行 HTTP 網(wǎng)絡(luò)請求開發(fā)時(如使用requests ...
2025-09-15CDA 數(shù)據(jù)分析師:激活表格結(jié)構(gòu)數(shù)據(jù)價值的核心操盤手 表格結(jié)構(gòu)數(shù)據(jù)(如 Excel 表格、數(shù)據(jù)庫表)是企業(yè)最基礎(chǔ)、最核心的數(shù)據(jù)形態(tài) ...
2025-09-15Python HTTP 請求工具對比:urllib.request 與 requests 的核心差異與選擇指南 在 Python 處理 HTTP 請求(如接口調(diào)用、數(shù)據(jù)爬取 ...
2025-09-12解決 pd.read_csv 讀取長浮點(diǎn)數(shù)據(jù)的科學(xué)計(jì)數(shù)法問題 為幫助 Python 數(shù)據(jù)從業(yè)者解決pd.read_csv讀取長浮點(diǎn)數(shù)據(jù)時的科學(xué)計(jì)數(shù)法問題 ...
2025-09-12CDA 數(shù)據(jù)分析師:業(yè)務(wù)數(shù)據(jù)分析步驟的落地者與價值優(yōu)化者 業(yè)務(wù)數(shù)據(jù)分析是企業(yè)解決日常運(yùn)營問題、提升執(zhí)行效率的核心手段,其價值 ...
2025-09-12用 SQL 驗(yàn)證業(yè)務(wù)邏輯:從規(guī)則拆解到數(shù)據(jù)把關(guān)的實(shí)戰(zhàn)指南 在業(yè)務(wù)系統(tǒng)落地過程中,“業(yè)務(wù)邏輯” 是連接 “需求設(shè)計(jì)” 與 “用戶體驗(yàn) ...
2025-09-11塔吉特百貨孕婦營銷案例:數(shù)據(jù)驅(qū)動下的精準(zhǔn)零售革命與啟示 在零售行業(yè) “流量紅利見頂” 的當(dāng)下,精準(zhǔn)營銷成為企業(yè)突圍的核心方 ...
2025-09-11CDA 數(shù)據(jù)分析師與戰(zhàn)略 / 業(yè)務(wù)數(shù)據(jù)分析:概念辨析與協(xié)同價值 在數(shù)據(jù)驅(qū)動決策的體系中,“戰(zhàn)略數(shù)據(jù)分析”“業(yè)務(wù)數(shù)據(jù)分析” 是企業(yè) ...
2025-09-11Excel 數(shù)據(jù)聚類分析:從操作實(shí)踐到業(yè)務(wù)價值挖掘 在數(shù)據(jù)分析場景中,聚類分析作為 “無監(jiān)督分組” 的核心工具,能從雜亂數(shù)據(jù)中挖 ...
2025-09-10統(tǒng)計(jì)模型的核心目的:從數(shù)據(jù)解讀到?jīng)Q策支撐的價值導(dǎo)向 統(tǒng)計(jì)模型作為數(shù)據(jù)分析的核心工具,并非簡單的 “公式堆砌”,而是圍繞特定 ...
2025-09-10