我们在例7中已经批量生成了采购合同。但是假设我们现在的公司名称由“ABC Trading Co., Ltd.”更改。 为“ABC Trading Co., Ltd.”,那么我们需要在每份合约的相应位置替换它。 当然,也可以修改原来的模板,然后重新生成合约。 这里介绍一下如何使用Python批量替换多个Word文件中的文本,即将“业务”替换为“贸易”。

我们先到Word文件中,找出“业务”一词出现了多少次。 如下图可以看到,幸运的是,它只出现了两次,一次出现在正文的段落中,一次出现在最后的表格中,这两个都是我们要替换的。

<code class="language-python" style="border-radius: 0px;font-family: Menlo, Monaco, Consolas, "Andale Mono", "lucida console", "Courier New", monospace;font-size: inherit;background-color: inherit;">import docx
def info_update(doc,old_info, new_info):
'''此函数用于批量替换合同中需要替换的信息
doc:文件
old_info和new_info:原文字和需要替换的新文字
'''

#读取段落中的所有run,找到需替换的信息进行替换
for para in doc.paragraphs: #
for run in para.runs:
run.text = run.text.replace(old_info, new_info) #替换信息
#读取表格中的所有单元格,找到需替换的信息进行替换
for table in doc.tables:
for row in table.rows:
for cell in row.cells:
cell.text = cell.text.replace(old_info, new_info) #替换信息

我们直接借用例 7 中定义的函数 info_update 来替换文本。 只需要传入目标文件的路径、要替换的词和新词即可。 然后导入os库得到目标文件及其路径,如下。

import os #用于获取目标文件所在路径
path="data/" # 文件夹路径
files=[]
for file in os.listdir(path):
if file.endswith(".docx"): #排除文件夹内的其它干扰文件,只获取word文件
files.append(path+file)
files
>>
['data/公司001合同.docx',
'data/公司002合同.docx',
'data/公司003合同.docx',
'data/公司004合同.docx',
'data/公司005合同.docx',
'data/公司006合同.docx',
'data/公司007合同.docx',
'data/公司008合同.docx',
'data/公司009合同.docx',
'data/公司010合同.docx']

然后就可以开始批量替换操作了。 结果可以在“替换结果”文件夹中查看。

for file in files:
doc = docx.Document(file)
info_update(doc,"商贸", "贸易")
doc.save("data/替换结果/{}".format(file.split("/")[-1]))
print("{}替换完成".format(file))
>>
data/公司001合同.docx替换完成
data/公司002合同.docx替换完成
data/公司003合同.docx替换完成
data/公司004合同.docx替换完成
data/公司005合同.docx替换完成
data/公司006合同.docx替换完成
data/公司007合同.docx替换完成
data/公司008合同.docx替换完成
data/公司009合同.docx替换完成
data/公司010合同.docx替换完成

但是,如果“商贸”一词在其他地方出现一次或多次,无法替代怎么办? 还有一种方法,我们可以指定要替换的段落范围。 例如,我们故意在“special_contains noise words.docx”中间插入了4个词“business”。 这样,我们在文档中就有了6个“业务”。

wps批量替换_excel 批量替换超链接_会声会影批量替换素材

假设我们要把第一个、第三个、第六个“commerce”替换成“trade”wps批量替换,那么首先要判断它们在第几段,也就是该段对应的index。 由于第六个“业务”在表中,而不在段落中,所以我们只需要找出第一和第三个所在的段落即可。

#获取词"商贸"所在段落
import docx #导入docx库
doc = docx.Document("data/含干扰词/特殊_含干扰词.docx") #打开word文件
text=[]
for para in doc.paragraphs: #读取word中的每个段落
text.append(para.text)
print(len(text))

target_index=[]
for i in text:
if "商贸" in i:
target_index.append(text.index(i))
target_index
>>
77
[15, 26, 32, 38, 66]

上面,我们还是使用docx模块来读取目标word文件。 我们需要知道包含“业务”一词的段落,我们需要知道它的索引。 但是我在docx模块中没有找到索引相关的函数,所以这里使用了一个workaround。 即创建一个空列表文本,然后将word文档中所有段落对应的文本提取存储到这个列表中。 列表可以使用index函数,列表中元素的索引对应段落的索引。 所以只要你在列表文本中找到“业务”这个词的索引,你也会在段落段落中找到它的索引。 根据len(text),共有77段。

然后创建一个空列表target_index,用于存放列表文本中包含“business”一词的字符串的索引。 使用for循环遍历列表文本中的所有元素,使用if语句判断是否包含“商业”字样。 如果是,则将该元素对应的索引text.index(i)存储到列表target_index中。 通过结果可以看出,找到了5个包含“commerce and trade”字符串的地方,索引分别是15、26、32、38、66。

为了验证是否准确,我们可以打印一下对应索引对应的段落是否真的包含“业务”二字。 下面的打印结果表明,结果比较理想。

for j in target_index:
print(doc.paragraphs[j].text)

>>
乙方:ABC商贸有限责任公司
1.交货方法:由乙方送货(国家主管部门规定有送货办法的,按规定的办法执行;没有规定送货办法的,按双方协议执行);商贸
1.所有货物由乙方送到交货地点且甲方确认收货后5天内,由甲乙双方共同对货物的包装、外观、数量、商标、型号、规格及性能
等进行验收,签署检验报告。如乙方未按约定到甲方指定地点参加检验的,应视为乙方对甲方单方检验的结果予以确认。验收标准
执行合同规定的货物质量标准。商贸
总价指甲方的交货价格,该价格应包含货物价格、通关费、包装费、物流费、装卸费、保险费、在甲方指定场所的安装调试费、
必要的培训费以及增值税等一切费用。在乙方完全履行本合同下全部义务的情形下,除非另有书面约定,否则合同金额是甲方应
当向乙方支付的全部费用 。商贸
本合同自双方法定代表人或委托代理人签字盖章后生效,至合同条款履行完毕时终止。商贸

因为我们只是把第1、3、6个“Commerce”换成了“Trade”,而第6个在表中。 所以我们需要改变原来的替换函数info_updatewps批量替换,命名为新函数info_update_new。 我们在函数中指定只替换第15段和第32段的目标词,表中的目标词继续替换。

import docx
def info_update_new(doc,old_info, new_info):
'''此函数用于批量替换合同中需要替换的信息
doc:文件
old_info和new_info:原文字和需要替换的新文字
'''

#读取段落中的所有run,找到需替换的信息进行替换
for i in [15,32]:
para=doc.paragraphs[i]
for run in para.runs:
run.text = run.text.replace(old_info, new_info) #替换信息
#读取表格中的所有单元格,找到需替换的信息进行替换
for table in doc.tables:
for row in table.rows:
for cell in row.cells:
cell.text = cell.text.replace(old_info, new_info) #替换信息

import os #用于获取目标文件所在路径
path="data/含干扰词/" # 文件夹路径
files=[]
for file in os.listdir(path):
if file.endswith(".docx"): #排除文件夹内的其它干扰文件,只获取word文件
files.append(path+file)

for file in files:
doc = docx.Document(file)
info_update_new(doc,"商贸", "贸易")
doc.save("data/替换结果/{}".format(file.split("/")[-1]))
print("{}替换完成".format(file))
>>
data/含干扰词/特殊_含干扰词.docx替换完成

调用新的替换函数info_update_new,并将结果保存到“data/replacement result”文件夹中。

结果如下。 可以看到替换后的文档中,“business”和“trade”各有3个词,只替换了我们指定位置的词。

所有的源代码和使用说明都在Jupyter notebook上完成,使用的Excel数据已经上传到GitHub。 欢迎fork或下载到本地自由发挥。 . . 转载请注明出处,谢谢。

GitHub 链接:

知乎专栏: