Python 3 根据模板生成Word文档

缘起

有朋友拜托写段程序,根据系统导出的txt文件和Word模板生成文档。

txt部分内容:

1
2
3
4
5
6
7
8
9
10
11
12
ersonInfo:
id=3XXXXXXXXXX
accountUid=XXXXXXXXXXXXXXXXXXXXXXX
createDate=2017-01-16 14:44:37.0
name=王XX
idNo=61XXXXXXXXXXXXXXX

Project:
id=1XX
name=XX
projectId=1XXXXXXXXXXXX
createDate=2015-12-14 17:39:50.0

把Word中相关字段替换成txt中的值。

思路

  • txt的格式很像INI文件,把以冒号结尾的项处理成方括号,另存为.ini,再用Python自带的configparser读取。
  • 使用docx库操作Word文档

难题

1.pip install docx装好包后,运行代码提示:

1
2
3
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/site-packages/docx-0.2.4-py3.3.egg/docx.py", line 30, in <module>
from exceptions import PendingDeprecationWarning
ImportError: No module named 'exceptions'

爆栈找到解决方案:docx包不兼容Python 3,卸载后,改用pip install python-docx安装即可正常使用

2.生成的新Word文档中,原有的图片丢失。

翻了docx的API文档,它把文件中的每一段作为一个paragraph,每个paragraph分为许多不同的run,同一句话中,如果字体、大小、粗细等不同,也算不同的run。不知道这图片是怎么算的。只要操作过一次文字,图片就会丢失。

替换之后再用代码插入图片。

3.先if再替换,有许多地方没有替换成功。

没想明白怎么回事,去掉if,不管有没有字段,全部替换。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
#! python3
# -*- coding: utf-8 -*-
# @Author: LoveNight
# @Date: 2017-07-18 13:13:26
# @Last Modified by: LoveNight
# @Last Modified time: 2017-07-26 13:39:29

from docx import Document
from datetime import datetime
import re
import os
import sys
import shutil
import configparser

'''
下面是参数配置,可以根据实际情况修改
'''


templateFile = "data\\模版.docx" # 模板文件
newFile = r"{0}.docx" # 生成的文件名

# 六张图
pic1 = "data\\1.png"
pic2 = "data\\2.jpg"
pic3 = "data\\3.jpg"
pic4 = "data\\4.jpg"
pic5 = "data\\5.jpg"
pic6 = "data\\6.jpg"
picTuple = (pic1, pic2, pic3, pic4, pic5, pic6)

# 模板中的替换图片用占位符
PLACE = ("AAAAAA", "BBBBBB", "CCCCCC", "DDDDDD", "EEEEEE", "FFFFFF")


##############配置完毕###################


# 切换脚本所在目录为工作目录,后面可以使用相对路径
os.chdir(sys.path[0])

# 新建temp文件夹
if os.path.isdir("temp"):
shutil.rmtree("temp")
os.mkdir("temp")

# 列出此脚本目录下所有的txt文件
txtList = [x for x in os.listdir(
sys.path[0]) if os.path.splitext(x)[1] == ".txt"]


# 先处理成INI文件,存到temp文件夹下
for x in txtList:
with open(x, "r", encoding="utf-8") as f:
content = f.read()
content = content.replace("PersonInfo:", "[PersonInfo]")
content = content.replace("Project:", "[Project]")
content = content.replace("AccountCertInfo:", "[AccountCertInfo]")
content = content.replace("Signlog:", "[Signlog]")
content = content.replace("EvidenceInfo:", "[EvidenceInfo]")
with open(os.path.join(sys.path[0], "temp", os.path.splitext(x)[0] + ".ini"), "w", encoding="utf-8") as f:
f.write(content)


# 下面开始生成Word文件
iniList = os.listdir("temp")

now = datetime.now()
year = now.year
month = now.month
day = now.day

for x in iniList:
config = configparser.ConfigParser()
config.read(os.path.join(sys.path[0], "temp", x), encoding="utf-8")
accountUid = config.get("PersonInfo", "accountUid")
namePerson = config.get("PersonInfo", "name")
idNo = config.get("PersonInfo", "idNo")
nameProject = config.get("Project", "name")
nameAccount = config.get("AccountCertInfo", "certName")
sn = config.get("AccountCertInfo", "sn")
issuer = config.get("AccountCertInfo", "issuer")
endDate = config.get("AccountCertInfo", "endDate")
startDate = config.get("AccountCertInfo", "startDate")
certBase64 = config.get("AccountCertInfo", "certBase64")
signDate = config.get("Signlog", "signDate")
idSign = config.get("Signlog", "id")
fileDigist = config.get("Signlog", "fileDigist")

eidFlag = False
if "EvidenceInfo" in config:
eidFlag = True
eid = config.get("EvidenceInfo", "eid")

doc = Document(templateFile)
for p in doc.paragraphs:
for r in p.runs:
if eidFlag:
r.text = r.text.replace("EvidenceInfo.eid", eid)
else:
r.text = r.text.replace("(存证编号EvidenceInfo.eid)", "")
if issuer.startswith("ZJCA"):
r.text = r.text.replace(
"中国金融认证中心(CFCA)", "浙江省数字安全证书管理有限公司(ZJCA)")

r.text = r.text.replace("PersonInfo.accountUid", accountUid)
r.text = r.text.replace(
"2017年XX 月 XX 日(当天日期)", "{0}年{1}月{2}日".format(year, month, day))
r.text = r.text.replace("PersonInfo.name", namePerson)
r.text = r.text.replace("PersonInfo.idNo", idNo)
r.text = r.text.replace("Project.name", nameProject)
r.text = r.text.replace("AccountCertInfo.name", nameAccount)
r.text = r.text.replace("AccountCertInfo.sn", sn)
r.text = r.text.replace("AccountCertInfo.issuer", issuer)
r.text = r.text.replace("AccountCertInfo.issuer", endDate)
r.text = r.text.replace("AccountCertInfo.startDate", startDate)
r.text = r.text.replace("AccountCertInfo.endDate", endDate)
r.text = r.text.replace("AccountCertInfo.certBase64", certBase64)
r.text = r.text.replace("Signlog.signDate", signDate)
r.text = r.text.replace("Signlog.id", idSign)
r.text = r.text.replace("Project.fileDigist", fileDigist)

# 重新来一次,下面添加图片
for p in doc.paragraphs:
for i in range(6):
if PLACE[i] in p.text:
for r in p.runs:
r.text = r.text.replace(PLACE[i], "")
p.runs[0].add_picture(picTuple[i])
# p.runs[0].add_picture(pic1)

# for p in doc.paragraphs:
# for r in p.runs:
# if r.text.find("PersonInfo.accountUid"):
# r.text = r.text.replace("PersonInfo.accountUid", accountUid)
# if r.text.find("2017年XX 月 XX 日(当天日期)"):
# r.text = r.text.replace("2017年XX 月 XX 日(当天日期)", "{0}年{1}月{2}日".format(year,month,day))
# if r.text.find("PersonInfo.name"):
# r.text = r.text.replace("PersonInfo.name", namePerson)
# if r.text.find("PersonInfo.idNo"):
# r.text = r.text.replace("PersonInfo.idNo", idNo)
# if r.text.find("Project.name平台自身"):
# r.text = r.text.replace("Project.name", nameProject)
# if r.text.find("AccountCertInfo.name"):
# r.text = r.text.replace("AccountCertInfo.name", nameAccount)
# if r.text.find("AccountCertInfo.sn"):
# r.text = r.text.replace("AccountCertInfo.sn", sn)
# if r.text.find("AccountCertInfo.issuer"):
# r.text = r.text.replace("AccountCertInfo.issuer", issuer)
# if r.text.find("AccountCertInfo.issuer"):
# r.text = r.text.replace("AccountCertInfo.issuer", endDate)
# if r.text.find("AccountCertInfo.startDate"):
# r.text = r.text.replace("AccountCertInfo.startDate", startDate)
# if r.text.find("AccountCertInfo.certBase64"):
# r.text = r.text.replace("AccountCertInfo.certBase64", certBase64)
# if r.text.find("Signlog.signDate"):
# r.text = r.text.replace("Signlog.signDate", signDate)
# if r.text.find("Signlog.id"):
# r.text = r.text.replace("Signlog.id", idSign)
# if r.text.find("Project.fileDigist"):
# r.text = r.text.replace("Project.fileDigist", fileDigist)
doc.save(newFile.format(nameProject + namePerson))


shutil.rmtree("temp")

# doc = Document("test.docx")

# for p in doc.paragraphs:
# for r in p.runs:
# if r.text.find(r"我"):
# r.text = r.text.replace(r"我", r"测试成功")
# print(r.text)
# newFileName = "测试.docx"
# doc.save(newFileName)
loveNight wechat
我的微信公众号,放一些有趣的内容,不定期更新。