查找并替换.docx文件中的文本 - Python

时间:2013-05-31 23:51:53

标签: python text replace docx zipfile

我一直在寻找一种方法来查找和替换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”:“2013年5月31日”} )。

步骤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文档,享受被替换的文本!

- 在第7行和第11行编辑 - 缺少右括号')'

2 个答案:

答案 0 :(得分:2)

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

您的文档保存在xml文件中(通常在docx的word / document.xml中,解压缩后)。有时你的文字可能不会一蹴而就:文件中的某个地方可能是XXXCLIENT,而其他地方则是NAMEXXX。

这样的事情:

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

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

只有您的解决方案的问题是您必须一次性编写所有内容,这不是最方便用户的。

我创建了一个使用小标签的JS库:{clientName} https://github.com/edi9999/docxgenjs

它的全局工作方式与您的算法相同,但如果内容不在一个笔划中,则不会崩溃(当您在Word中编写{clientName}时,文本通常会在文档中被分割:{,clientName,}。

答案 1 :(得分:0)

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

例如,搜索Pet并再次使用"XXXCLIENTNAMEXXX"替换它。