python 实现 docx 文本替换
目的
由于商业原因,最近要实现一个功能,就是word文档 (docx格式)的批量文本替换,把docx中的商标名换成自己的,替换过程中要保留word文档的样式。
在网上搜寻多种方案,有 python-docx, 有 apache poi, 均不符合我的要求,主要是 这些库 解析docx文档 能力有限,文档不全,而且有的内容无法识别到,
有的即使替换了,样式也乱了,下面是我自己的方案,效果堪称完美。
思路
docx 文件其实是zip文件,在windows上,我们将docx文件重命名为zip文件,解压,即可得到下面的文件:
可以看到 docx文件本质是 资源文件 + xml 文件的集合,而 word文档中的文字 都在 word/document.xml 中。
我们只要替换这个文件,再重新压缩为zip,再改成.docx格式 ,即可实现替换。
代码实现
- import zipfile
- import shutil
- import os
- import file_util
- ”’
- input_f 输入文件路径
- out_f 输出文件路径
- ”’
- def replace_text(input_f, out_f):
- owd = os.getcwd()
- # 将淘宝替换为京东
- replacements = {
- ‘淘宝’: ‘京东’,
- }
- tmp_dir = “D:\\BaiduNetdiskDownload\\tmp\\”
- try:
- filename = input_f.split(“\\”)[-1]
- os.chdir(tmp_dir)
- shutil.copy(input_f, tmp_dir) # 复制到临时目录
- copy_file = os.path.join(tmp_dir, filename)
- zip_file = copy_file.replace(“.docx”, “.zip”)
- os.rename(copy_file, zip_file)
- # 解压文件
- with zipfile.ZipFile(zip_file, “r”) as zip_ref:
- zip_ref.extractall(tmp_dir)
- os.remove(zip_file)
- # 替换文本
- with open(‘word\\document.xml’, ‘r’, encoding=“utf8”) as file:
- str = file.read()
- for k, v in replacements.items():
- str = str.replace(k, v)
- text_file = open(“out.xml”, “w”, encoding=“utf8”)
- n = text_file.write(str)
- text_file.close()
- # close input and output files
- os.remove(“word\\document.xml”)
- os.rename(“out.xml”, “word\\document.xml”)
- # 重命名文件
- dst_zip_file_name = filename.replace(“.docx”, “.zip”)
- shutil.make_archive(filename.replace(“.docx”, “”), ‘zip’, tmp_dir)
- os.rename(dst_zip_file_name, out_f)
- except Exception as e:
- pass
- finally:
- # 将临时目录清空
- file_util.clean_dir(tmp_dir)
- os.chdir(owd)