Python 实现批量生成 Word 文档:市民水电费缴费通知单

前言:

在日常办公中操作 Word 文档时,经常会对已经有的Word文档的内容进行修改,比较少会直接新建一个空白的 Word 文档,再往里面写东西。

这篇博客也是介绍一个根据已有的 Word 文档,按照特定需求生成多个Word文档的实例。

需求描述:

假定某市行政中心需要对管辖范围内的用水电气居民用户发送缴费通知单,通知单如下图:

在这里插入图片描述
用水电气数据已经统计在一个 Excel 文件中,Excel 表格数据如下:

在这里插入图片描述
上表有25条用户数据,就是要根据这些数据创建25个Word文档,手动更改Word 文档似乎也可以。但是实际情况不可能只有25条数据,很可能是几千条数据,要手动创建更改Word文档就很麻烦了。而面对这种重复性强,逻辑简单的办公需要,用 Python 来提高效率简直完美。

具体需求:

读取 Excel 文件数据,根据数据内容与Word模板,新建对应数据条数的缴费通知单,将新建通知单以用户名命令,并保存在一个文件夹中。

主要思路及代码:

读取Word模板数据:

分析:
从需求上来看,核心功能就是要: 读取模板文件,在不改变模板文件中段落、文字格式的前提下,根据数据内容替换部分文字。

根据需要,调整的 Word 模板文件截图:

在这里插入图片描述

从前面几篇博客的介绍,可知Word文档中文字信息及格式都是保存在 run 对象中的。

所以先获取 Word 模板中正文段落所有的 run 对象:

import docx

# 读取 word 模板文件
template_word = docx.Document('test01.docx')  # 获取docx对象

# word 模板正文段落、表格所有 run 对象列表
template_runs = []

# 获取正文所有段落对象列表
pars = template_word.paragraphs
print(pars)
print(len(pars))  # 8

# 遍历段落对象列表,获得每一个段落对象
for par in pars:
    # 遍历段落对象的 run 对象列表,获得每一个run对象
    for run in par.runs:
        # 测试(看一下 run 内字符串是否与预期一致!!!)
        print(run.text)
        template_runs.append(run)

测试的那一步很重要,因为在run对象中包含格式信息,所以有的 run.text 文字可能会和预期不一致

run.text 部分打印截图:

在这里插入图片描述
注:上面的打印信息里,一个 run.text 必须要包含想替换字段,否则后期替换就会失败。所以要保证:需替换字段格式必须完全一致。

接下来就是获取 Word 文档 表格内所有单元格的 run 对象 了:

# 获取 word 文档中表格对象
word_table = template_word.tables[0]
print(word_table)
# <docx.table.Table object at 0x000002173C43BB08>
# 获取文档表格中所有单元格的段落对象
for cell in word_table._cells:
    for cell_par in cell.paragraphs:
        for cell_run in cell_par.runs:
            # 测试(看一下 run 内字符串是否与预期一致!!!)
            print(cell_run.text)
            template_runs.append(cell_run)

同样,测试这一步也很关键。

cell_run.text 打印截图:

在这里插入图片描述

将上诉代码写成函数:

因需要根据数据建立多个 Word 文件,所以要多次获取模板文档及文档的 run 对象,所以将上面代码写成函数,在代码的可读性和思路的清晰性来说,写成函数都是很必要的。

# 定义获取 word 模板正文段落、表格 run 对象函数
def get_runs(path):
    doc = docx.Document(path)
    runs_g = []
    # 获取段落 run 对象
    for par_g in doc.paragraphs:
        for run_g in par_g.runs:
            runs_g.append(run_g)
    # 获取表格 run 对象
    table_g = doc.tables[0]
    for cell_g in table_g._cells:
        for cell_par_g in cell_g.paragraphs:
            for cell_run_g in cell_par_g.runs:
                runs_g.append(cell_run_g)
    return doc,runs_g

解析:get_runs 函数也很简单,传参为修正好的 Word 模板文件路径,返回文档对象和文档所有 run 对象。

读取Excel文件数据:

用Python的xlrd模块读取Excel文件数据(本系列文章有专门介绍xlrd模块的博客):

import xlrd 
# 读取 Excel 文件数据
excel_obj = xlrd.open_workbook('el01.xlsx')
# 获取 sheet
sheet = excel_obj.sheet_by_index(0)
# 按行读取所有数据
excel_data = sheet._cell_values

# 需制作缴费通知单数据
notice_data = excel_data[2:]
print(notice_data)

测试数据部分打印截图:

在这里插入图片描述

替换及新建Word文档:
# 模板内设置的标志:
tags_1 = ['用户姓名','用户居住地址','通知月份',
          '上月用水','本月用水','实际用水',
          '上月用电','本月用电','实际用电',
          '上月用气','本月用气','实际用气',
          '本月水费','本月电费','本月燃气费',
          '总计费用']

# 遍历需制作缴费单数据
for ds in notice_data:
    # 构建替换数据字典
    notice_dict = dict(zip(tags_1,ds))
    # 创建 word、run 列表
    doc_t,runs_t = get_runs('test01.docx')
    # 遍历模板run对象 和 notice_dict key 匹配
    # 匹配成功则替换 run 内容
    for run_t in runs_t:
        if run_t.text in notice_dict.keys():
            run_t.text = str(notice_dict[run_t.text])
    # 按用户名称新建Word文档,将文档保存在outpath文件夹
    doc_t.save('outpath/%s通知单.docx' % ds[0])

outpath(文件保存)路径下,批量生成的Word文档截图:

在这里插入图片描述

批量生成的缴费通知文件截图:

在这里插入图片描述

全部代码:

# 导入模块
import xlrd
import docx

# 定义获取 word 模板正文段落、表格 run 对象函数
def get_runs(path):
    doc = docx.Document(path)
    runs_g = []
    # 获取段落 run 对象
    for par_g in doc.paragraphs:
        for run_g in par_g.runs:
            runs_g.append(run_g)
    # 获取表格 run 对象
    table_g = doc.tables[0]
    for cell_g in table_g._cells:
        for cell_par_g in cell_g.paragraphs:
            for cell_run_g in cell_par_g.runs:
                runs_g.append(cell_run_g)
    return doc,runs_g

# 读取 Excel 文件数据
excel_obj = xlrd.open_workbook('el01.xlsx')
# 获取 sheet
sheet = excel_obj.sheet_by_index(0)
# 按行读取所有数据
excel_data = sheet._cell_values

# 需制作缴费通知单数据
notice_data = excel_data[2:]

# 模板内设置的标志:
tags_1 = ['用户姓名','用户居住地址','通知月份',
          '上月用水','本月用水','实际用水',
          '上月用电','本月用电','实际用电',
          '上月用气','本月用气','实际用气',
          '本月水费','本月电费','本月燃气费',
          '总计费用']

# 遍历需制作缴费单数据
for ds in notice_data:
    # 构建替换数据字典
    notice_dict = dict(zip(tags_1,ds))
    # 创建 word、run 列表
    doc_t,runs_t = get_runs('test01.docx')
    # 遍历模板run对象 和 notice_dict key 匹配
    # 匹配成功则替换 run 内容
    for run_t in runs_t:
        if run_t.text in notice_dict.keys():
            run_t.text = str(notice_dict[run_t.text])
    doc_t.save('outpath/%s通知单.docx' % ds[0])

结尾:

以上就是本篇博客的全部内容了,除了分析和测试部分,代码行数只有40行左右,不得不说 Python 开发效率真的很高,而且逻辑也很清晰,最后感谢阅读!

【Python与Office】专栏

该专栏会对 Python 的第三方模块,如:xlwt,xlrd,python-docx等,操作 Office 办公软件(Word Excel PPT)的方法进行详细讲解。同时也会搭配一些实例演练,一方面强化知识点的理解与运用,另一方面也希望能起到,引导读者进行思考:如何用 python 提高 offic 办公软件办公效率的作用。

感兴趣的朋友,可以点个 关注收藏 。如在博客中遇到任何问题或有一些想法、需求,可留言或私信。

创作不易,你的支持是我最大的动力,感谢 !

猜你喜欢

转载自blog.csdn.net/zhouz92/article/details/107302145