12

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

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 行缺少右括号 ')'

4

2 回答 2

2

有时,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, }。

于 2013-06-06T13:45:08.640 回答
-1

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

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

于 2016-02-12T14:08:08.077 回答