2013-05-31 86 views
10

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

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文件写入新的docx存档,作为新的word/document.xml文件。

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

第10步)打开您的新DOCX文件,享受您的替换文本!

- 编辑 - 上缺少线7右括号 ')' 和11

+0

你的意思是你发布的代码有效,你问:“为什么没有人做到这一点?”也许有人有。为什么会这样呢?粗略浏览一下你的代码,看起来是正确的。 –

+0

当然人们以前也这样做过。这是一封表格信的准系统实施。 Microsoft Word(和OpenOffice等)具有“邮件合并”功能,可以在本地执行此操作。 –

+0

这个问题似乎是脱离主题,因为它是关于审查工作代码。建议迁移到codereview.SE –

回答

1

有时,字做奇怪的事情。 你应该尝试删除文本并一举,如把它改写没有编辑文本中间

文档中保存在一个XML文件(通常在字/ document.xml中的DOCX,AFER解压缩)。有时可能你的文本不会一笔一划:文档中的某处可能是XXXCLIENT,而其他地方可能是NAMEXXX。

事情是这样的:

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

出现这种情况的经常因为语言支持:当他认为一个词是一个特定的语言,并可能单词之间这样做字拆分的话,这将将单词分成多个标签。

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

我已经创建了一个使用小胡子像标签一个JS库:{} CLIENTNAME https://github.com/edi9999/docxgenjs

它可以在全球范围与您的算法,但如果内容是不是在一个行程(当你写会不会崩溃{ CLIENTNAME}在Word中,文本通常会分裂:{,CLIENTNAME,}在文档中

-1

你可以尝试一种变通方法使用Word的查找/替换获得一举文本

例如。搜索"XXXCLIENTNAMEXXX"并将其替换为"XXXCLIENTNAMEXXX"