WordWriter,自动化Word报告生成的python脚本

介绍

这个脚本主要靠python-docx实现。同时使用pandas来处理输入的表格。基于python3。使用复杂度没有docxtpl那么高。

需要安装

pip install python-docx
pip install pandas

脚本地址:

WordWriter

脚本原理

使用python-docx,通过导入模板docx文件,寻找模板文件中预先保留的tag,对tag进行替换,最后重新保存docx文件达到自动输出报告的效果。支持对模板中的tag进行处理,替换后的字符串格式会完全跟随模板中对应tag的格式。仅支持docx格式的word文档,不支持doc格式word文档。

目前支持

整个表格插入、单元格中的字符串替换、单元格中的图片插入、文本中的字符串替换、文本框中的字符串替换、图片插入、页眉页脚字符串替换。

使用方法

在python中导入

from WordWriter import WordWriter

# 建立标签与输入内容(替换内容)对照字典
testDict = {}
testDict["#[tag]#"] = "replace string"

# 输出
WordWriter(templateDocx, outputDocx, testDict)

为了程序稳定运行,插入的tag需要规范命名。

整个表格插入

表格tag命名规则:#[TABLE-xxxx]#

表格的输入为以tab分割的txt文件路径,即

testDict["#[TABLE-xxxx]#"] = "/path/to/table/table.txt"

由于txt文件中换行符会识别为下一行,而显然单元格中需要允许换行符存在。因此需要输入到同一单元格中的换行符请修改为“\x0a”。

需要插入表格,首先需要在模板中定义一个与插入表格列数一致的表格,并且将tag放置在需要填充的第一行第一列(不包含标题)。如下表。填充时,文字格式会按照tag所在行每个单元格的格式进行填充(即每一列的格式都会参考tag所在行的单元格格式)。

标题1 标题2 标题3
#[TABLE-1]#    
     
     

当然,如果第一列是固定的字段,也可以将tag放置在第一行第二列中(类推)。

标题1 标题2 标题3
#[TABLE-2]#  
   
   

注意,应在模板中预先建立表格,并新建若干行,如模板表格行数小于输入表格行数,程序会自行创建新行;如模板表格行数大于输入表格行数,程序会自动删除空行。

图片插入

单元格图片tag命名规则:#[IMAGE-xxxx]#

包含大小格式:#[IMAGE-xxxx-(20,20)]#

输入为图片文件路径

testDict["#[TBIMG-1-(20,20)]#"] = "/path/to/picture/picture.png"

所有图片均建议加入大小格式,不要使用原始尺寸进行插入。括号中分别是(width,height)。当插入的图片不存在时,图片插入模式会更改为文字插入模式,插入图片的路径。因此这里其实是一个可以选择是插入图片还是文字的小技巧。图片插入同时支持插入在段落和单元格中。

图1 图2 图3
#[IMAGE-1-(20,20)]# #[IMAGE-2-(20,20)]# #[IMAGE-3-(20,20)]#

文本框中的字符串替换

文本框中的字符串tag命名规则:#[TX-xxxx]#

输入为字符串

testDict["#[TX-textbox]#"] = "textbox string replace"

图形中的文本也等同于文本框中文本。

段落/页眉/页脚/单元格中的字符串

段落/页眉/页脚/单元格中的字符串tag命名规则:#[xxxx]#,只要不要和IMAGE、TABLE、TX等保留前缀冲突即可。

输入为字符串,即

testDict["#[xxxx]#"] = "table cell string replace"

文本中的替换:

替换的内容的格式会完全跟随模板中tag的格式,即在模板中对tag进行加粗,如#[xxxx]#,替换内容也会加粗;将tag颜色更改为红色,如#[xxxx]#,替换内容也会是红色。单元格字符串替换以及文本框字符串替换同理。

如单元格中的替换:

标题1 标题2
结果 #[results]#

测试

测试文件

测试脚本,将WordWriter.py也放在同一文件夹时

from WordWriter import WordWriter

# 测试脚本
resultsDict = {}
resultsDict["#[testheader1]#"] = "测试页眉1"
resultsDict["#[testheader2]#"] = "页眉测试2"
resultsDict["#[testString]#"] = ",文本替换成功"
resultsDict["#[testfooter]#"] = "测试页脚"
resultsDict["#[TX-testString2]#"] = ",文本框文本替换成功"
resultsDict["#[testTableString1]#"] = "单元格文本替换成功"
resultsDict["#[testTableString2]#"] = "单元格文本替换成功"
resultsDict["#[IMAGE-test1-(30,30)]#"] = "testPicture.png"
resultsDict["#[IMAGE-test2]#"] = "testPicture2.png"
resultsDict["#[IMAGE-test3-(10,10)]#"] = "testPicture.png"
resultsDict["#[TABLE-test1]#"] = "testTable.txt"

# 使用主函数进行报告填充
WordWriter("test.docx", "output.docx", resultsDict)

注意事项

有时tag并不能被很好的识别,是因为word将一段不连续的输入的tag理解成为是多个“run”。程序需要一个tag作为一个run时才能识别出来。

所以,如果遇到这种情况,建议是将不能识别的tag完整的复制到文本文档中,再完整的(一次性的)粘贴回模板中替换掉不识别的tag。在修改格式如颜色字体等的时候也需要是将一个tag完全选中来修改,避免被认为是多次的输入内容。