python应用之Word生成

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很像, 一块一块拼凑, 也跟爬虫很像, 一个关键字关键字的解析)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

落子无悔!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>