在docx中替换文本并使用python-docx保存更改的文件

时间:2013-07-25 06:03:19

标签: python ms-word docx python-docx

我尝试使用python-docx module替换文件中的单词并保存新文件,但需要注意新文件必须与旧文件具有完全相同的格式,但是单词被取代。我该怎么做?

docx模块有一个带有7个输入的savedocx:

  • 文档
  • coreprops
  • appprops
  • CONTENTTYPES
  • websettings
  • wordrelationships
  • 输出

除了替换的单词外,如何将原始文件中的所有内容保持不变?

8 个答案:

答案 0 :(得分:9)

这对我有用:

def docx_replace(old_file,new_file,rep):
    zin = zipfile.ZipFile (old_file, 'r')
    zout = zipfile.ZipFile (new_file, 'w')
    for item in zin.infolist():
        buffer = zin.read(item.filename)
        if (item.filename == 'word/document.xml'):
            res = buffer.decode("utf-8")
            for r in rep:
                res = res.replace(r,rep[r])
            buffer = res.encode("utf-8")
        zout.writestr(item, buffer)
    zout.close()
    zin.close()

答案 1 :(得分:4)

似乎是,Docx for Python并不意味着存储带有图像,标题......的完整Docx,而只包含文档的内部内容。所以没有简单的方法可以做到这一点。

Howewer,您可以这样做:

首先,看看docx tag wiki

它解释了如何解压缩docx文件:以下是典型文件的样子:

+--docProps
|  +  app.xml
|  \  core.xml
+  res.log
+--word //this folder contains most of the files that control the content of the document
|  +  document.xml //Is the actual content of the document
|  +  endnotes.xml
|  +  fontTable.xml
|  +  footer1.xml //Containst the elements in the footer of the document
|  +  footnotes.xml
|  +--media //This folder contains all images embedded in the word
|  |  \  image1.jpeg
|  +  settings.xml
|  +  styles.xml
|  +  stylesWithEffects.xml
|  +--theme
|  |  \  theme1.xml
|  +  webSettings.xml
|  \--_rels
|     \  document.xml.rels //this document tells word where the images are situated
+  [Content_Types].xml
\--_rels
   \  .rels

Docx只获取文档的一部分,方法 opendocx

def opendocx(file):
    '''Open a docx file, return a document XML tree'''
    mydoc = zipfile.ZipFile(file)
    xmlcontent = mydoc.read('word/document.xml')
    document = etree.fromstring(xmlcontent)
    return document

它只获取document.xml文件。

我建议你做的是:

  1. 使用** opendocx *
  2. 获取文档的内容
  3. 将document.xml替换为 advReplace 方法
  4. 以zip格式打开docx,并用新的xml内容替换document.xml内容。
  5. 关闭并输出压缩文件(将其重命名为output.docx)
  6. 如果安装了node.js,请告知我已经使用DocxGenJS作为docx文档的模板引擎,该库正处于活动开发状态,并将很快作为节点模块发布。

答案 2 :(得分:3)

您使用的是here中的docx模块吗?

如果是,则docx模块已经公开了replace,advReplace等方法,可以帮助您完成任务。有关公开方法的更多详细信息,请参阅source code

答案 3 :(得分:1)

我已经分享了一个python-docx here的repo,它保存了docx文件中的所有预先存在的数据,包括格式化。希望这是你正在寻找的。

答案 4 :(得分:0)

除了@ramil之外,你必须在将它们作为字符串值放入XML之前转义一些字符,这对我有用:

def escape(escapee):
  escapee = escapee.replace("&", "&")
  escapee = escapee.replace("<", "&lt;")
  escapee = escapee.replace(">", "&gt;")
  escapee = escapee.replace("\"", "&quot;")
  escapee = escapee.replace("'", "&apos;")
return escapee

答案 5 :(得分:0)

from docx import Document
file_path = 'C:/tmp.docx'
document = Document(file_path)

def docx_replace(doc_obj, data: dict):
    """example: data=dict(order_id=123), result: {order_id} -> 123"""
    for paragraph in doc_obj.paragraphs:
        for key, val in data.items():
            key_name = '{{{}}}'.format(key)
            if key_name in paragraph.text:
                paragraph.text = paragraph.text.replace(key_name, str(val))
    for table in doc_obj.tables:
        for row in table.rows:
            for cell in row.cells:
                docx_replace(cell, data)

docx_replace(document, dict(order_id=123, year=2018, payer_fio='payer_fio', payer_fio1='payer_fio1'))
document.save(file_path)

答案 6 :(得分:0)

上述方法的问题在于它们会丢失现有的格式。请参阅我的answer,它执行替换并保留格式。

还有python-docx-template允许在docx模板中进行jinja2样式模板化。这是指向documentation

的链接

答案 7 :(得分:0)

我们可以使用python-docx将图像保存在docx上。 docx将图像检测为段落。 但对于此段,该文本为空。 因此,您可以像这样使用。 paragraphs = document.paragraphs for paragraph in paragraphs: if paragraph.text == '': continue