程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

python應用之Word生成

編輯:Python

1. 介紹

最近一個做文職的朋友提出了一個想法, 希望實現自動修改他的一個Word內容. 因為正常情況下一個工程其實只需要修改Word裡面的日期, 名稱, 和一些參數, 所以希望我能為他寫個腳本, 完成Word的自動填充並生成新的Word.

1.1 需求

  • 指定位置關鍵詞填充: 比如XXXXX村飲水安全鞏固提升工程
  • 時間填充: 已知A時間, B時間=A時間+days
  • 隨機數: 允許偏差:±10mm 生成指定范圍內的N個隨機數

1.2 對應解決方案

  1. 編寫Word模板, 裡面標記需要填充的關鍵字
  2. 指定Excel表格填寫關鍵字和對應的值
  3. 讀取Word模板待填充關鍵字, 匹配Excel表格中的關鍵字對應的值
  4. 根據關鍵字格式如
    1. date_1-4 在date_1的基礎上+4天
    2. random_1_4(1,5) 生成4個范圍是1,5的隨機數
  5. 寫入到新的Word

2. 實現

2.1 環境

python3.8
pip install docx-mailmerge==0.5.0 # 用於對Word裡面設置的域(關鍵字)進行解析和填充
pip install python-docx==0.8.11 # 用於讀取Word的段落, 表格進行解析和增刪改查
pip install pandas==1.4.2 # 用於讀取Excel表格數據

2.2 創建Word模板, 增加域定位關鍵字

2.3 編寫對應的Excel

2.4 文件存儲路徑

.
├── main.py # 主函數
├── readme.md
├── req.txt # 環境包request
├── result
│ └── t.docx # 生成的文件
├── sources
│ ├── doc1.docx # Word模板
│ └── input.csv # 定義的key-value
$ python main.py # 運行

2.5 main.py代碼

'''
1. 初始化對象
2. 獲取模本對象 <- template_file_path
3. 讀取輸入csv文件<- input_csv_path
4. 寫數據到對象
1. 模板對象中key, 直接填csv中對應的key數據
2. 模板對象中的date, 根據csv中的數據填充, 並依次生成date_n_long的數據進行填充
3. 模板對象中的random, 根據key中的(a,b), 生成對應的隨機數, 進行填充
5. 對象保存 <- save_path
'''
import pandas as pd # pandas==1.4.2
from mailmerge import MailMerge # docx-mailmerge==0.5.0
import random
import re
from datetime import datetime
from dateutil.relativedelta import relativedelta
class WriteDocx():
def __init__(self,format_date='%Y.%m.%d'):
super().__init__()
self.doc = None
self.doc_key = None
self.dict_csv = {
}
self.format_date = format_date
def createTemplateDoc(self, template_file_path = "sources/doc1.docx"):
self.doc = MailMerge(template_file_path)
self.doc_key = self.doc.get_merge_fields()
print("模板裡面的關鍵字包含如下: ", self.doc_key)
print("模板對象創建完畢, 開始向對象填充數據...")
def getInputData(self, input_csv_path = "sources/input.csv"):
csv = pd.read_csv("sources/input.csv")
print(csv.head(2))
for i in range(len(csv["key"].values)):
self.dict_csv[csv.loc[i]["key"]] = csv.loc[i]["value"]
print(self.dict_csv)
# 解析生成隨機數的方案
def getRandom(self, data = "random_2_6(1,3)")->list:
random_order = [eval(_) for _ in list(re.findall(r"(.*)\((.*),(.*)\)", data.split("_")[-1])[0])]
res_list = ["%0.2f"%random.uniform(random_order[1], random_order[2]) for i in range(random_order[0])]
return "[%s]"%",".join(res_list)
def getDate(self, date="2017.10.23", data = 'date_2-6'):
add_day = int(data.split("-")[-1]) # 增加的天數
time_1 = datetime.strptime(date, "%Y.%m.%d") + relativedelta(days=add_day)
return datetime.strftime(time_1, '%Y.%m.%d') # 這裡是最終的格式
# 格式化日期格式
def format_date_(self, date):
time_1 = datetime.strptime(date, "%Y.%m.%d")
return datetime.strftime(time_1, self.format_date) # 這裡是最終的格式
def writeDoc(self, ):
# 生成doc_key中random和date的數據
# 對於random生成對應的數據, 對於date生成對應的延時
for _ in self.doc_key:
if "random" in _:
self.dict_csv[_] = self.getRandom(_) # random_2_2(0,3) --> [1.2, 0.5]
if "date" in _ and len(_.split("-"))==2: # '2017.10.23', 'date_2-6' --> 2017.10.29
self.dict_csv[_] = self.getDate(self.dict_csv[_.split("-")[0]], _)
if "date" in _: # 統一格式化日期格式 2017.10.23->
self.dict_csv[_] = self.format_date_(self.dict_csv[_])
print("要填充的數據是: ", self.dict_csv)
print(type(self.dict_csv))
self.doc.merge(** self.dict_csv) #生成一份Word文檔
def save(self, save_path = "result/t.docx"):
self.doc.write(save_path)
print("新文件已經成功保存到: ", save_path)
# 只需要修改這裡的位置即可
def main():
object = WriteDocx(format_date='%Y年%m月%d日')
object.createTemplateDoc("sources/doc1.docx")
object.getInputData("sources/input.csv")
object.writeDoc()
object.save("result/t.docx")
if __name__=='__main__':
main()

3. 思考

通過這次練習, 讓我發現文職人員能夠改進很多工作流程. 就拿我們每次轉團關系的介紹信, 都是發下來自己手寫裡面的內容, 比如姓名等個人信息, 團關系從哪個位置轉到哪個位置, 在交上去蓋章. 如果根據本文的工作流程, 只需要統計每個人的上述信息保存到Excel的每一列, 做一個Word模板, 就可以一次性按列生成所有人對應的轉團關系介紹信, 打印蓋章即可, 完全不必要自己手寫, 流水線操作總是比分開單干更加便捷順利. 最後2202年了, 希望文職工作的同志都能擁有編程思想, 也許無法實現, 但是咱可以找編程朋友改善工作流程, 提高工作效率, 提高幸福指數!!!

未完待續

  1. 利用python-docx處理段落和表格 (其實這塊跟前端HTML很像, 一塊一塊拼湊, 也跟爬蟲很像, 一個關鍵字關鍵字的解析)

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved