繁体   English   中英

在 .docx 文件中查找和替换文本 - Python

[英]Find and replace text in .docx file - Python

我一直在寻找一种方法来查找和替换 docx 文件中的文本,但运气不佳。 我已经尝试过 docx 模块,但无法让它工作。 最终,我使用 zipfile 模块并替换了 docx 存档中的 document.xml 文件,找到了下面描述的方法。 为此,您需要一个模板文档 (docx),其中包含要替换为唯一字符串的文本,这些字符串不可能与文档中的任何其他现有或未来文本匹配(例如“与 XXXCLIENTNAMEXXX 在 XXXMEETDATEXXX 上的会议进行得非常顺利。 ”)。

import zipfile

replaceText = {"XXXCLIENTNAMEXXX" : "Joe Bob", "XXXMEETDATEXXX" : "May 31, 2013"}
templateDocx = zipfile.ZipFile("C:/Template.docx")
newDocx = zipfile.ZipFile("C:/NewDocument.docx", "a")

with open(templateDocx.extract("word/document.xml", "C:/")) as tempXmlFile:
    tempXmlStr = tempXmlFile.read()

for key in replaceText.keys():
    tempXmlStr = tempXmlStr.replace(str(key), str(replaceText.get(key)))

with open("C:/temp.xml", "w+") as tempXmlFile:
    tempXmlFile.write(tempXmlStr)

for file in templateDocx.filelist:
    if not file.filename == "word/document.xml":
        newDocx.writestr(file.filename, templateDocx.read(file))

newDocx.write("C:/temp.xml", "word/document.xml")

templateDocx.close()
newDocx.close()

我的问题是这种方法有什么问题? 我对这个东西很陌生,所以我觉得其他人应该已经弄清楚了。 这让我相信这种方法有一些非常错误的地方。 但它有效! 我在这里缺少什么?

.

以下是我的思考过程的演练,供其他试图学习这些东西的人使用:

步骤 1) 准备一个 Python 字典,其中包含要替换为键的文本字符串和作为项目的新文本(例如 {"XXXCLIENTNAMEXXX" : "Joe Bob", "XXXMEETDATEXXX" : "May 31, 2013"})。

步骤 2) 使用 zipfile 模块打开模板 docx 文件。

步骤 3) 使用附加访问模式打开一个新的 docx 文件。

步骤 4)从模板 docx 文件中提取 document.xml(所有文本所在的位置)并将 xml 读取到文本字符串变量。

步骤 5) 使用 for 循环将 xml 文本字符串中字典中定义的所有文本替换为新文本。

步骤 6) 将 xml 文本字符串写入一个新的临时 xml 文件。

步骤 7) 使用 for 循环和 zipfile 模块将模板 docx 存档中的所有文件复制到新的 docx 存档中,除了 word/document.xml 文件。

步骤 8) 将带有替换文本的临时 xml 文件作为新的 word/document.xml 文件写入新的 docx 存档。

步骤 9) 关闭您的模板和新的 docx 档案。

第 10 步)打开您的新 docx 文档并享受替换后的文本!

--Edit-- 第 7 行和第 11 行缺少右括号“)”

有时,Word 会做一些奇怪的事情。 您应该尝试删除文本并一次性重写它,例如不要在中间编辑文本。

您的文档保存在 xml 文件中(通常在 word/document.xml 中用于 docx,解压后)。 有时,您的文本可能不在一笔:可能在文档中的某处,它们是 XXXCLIENT,而在其他地方,它们是 NAMEXXX。

像这样的东西:

<w:t> XXXCLIENT </w:t> ... <w:t> NAMEXXX </w:t>

由于语言支持,这种情况经常发生:当他认为一个单词属于一种特定语言时,单词会拆分单词,并且可能会在单词之间这样做,这会将单词拆分为多个标签。

您的解决方案的唯一问题是您必须一口气写下所有内容,这不是最用户友好的。

我创建了一个使用类似胡子的 JS 库:{clientName} https://github.com/edi9999/docxgenjs

它与您的算法在全局范围内工作,但如果内容不是一笔画就不会崩溃(当您在 Word 中编写 {clientName} 时,文本通常会被拆分:{, clientName, } 在文档中。

您可以尝试一种解决方法。 使用 Word 的搜索/替换功能,一键获取文本。

例如,搜索"XXXCLIENTNAMEXXX"并将其再次替换为"XXXCLIENTNAMEXXX"

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM