编辑文档 Python-docx 的 header 中的内容

Edit content in header of document Python-docx

我正在尝试在文档 Header 的 文本框中查找和替换文本。但搜索了一段时间后,似乎无法通过 python-docx 访问 Header 或 "float" 文本框中的内容(我阅读了问题 here

所以,这意味着我们必须直接在xml格式的文件上查找和替换。你知道怎么做吗?

我找到了解决这个问题的方法。例如,我有一个 template.docx 文件,我想如上所述更改 Header 中的 a 文本框中的文本。下面的流程步骤,我解决了我的问题:

  1. 将文件 template.docx 重命名为 template.zip
  2. 解压缩 template.ziptemplate 文件夹
  3. /template/word/ 文件夹中的 header<number>.xml 文件之一中查找并替换我想更改的文本。
  4. /template 文件夹中的所有文件压缩回 template.zip
  5. template.zip 重命名回 template.docx

我用Python来操纵这些

import os
import shutil
import zipfile

WORKING_DIR = os.getcwd()
TEMP_DOCX = os.path.join(WORKING_DIR, "template.docx")
TEMP_ZIP = os.path.join(WORKING_DIR, "template.zip")
TEMP_FOLDER = os.path.join(WORKING_DIR, "template")

# remove old zip file or folder template
if os.path.exists(TEMP_ZIP):
    os.remove(TEMP_ZIP)
if os.path.exists(TEMP_FOLDER):
    shutil.rmtree(TEMP_FOLDER)

# reformat template.docx's extension
os.rename(TEMP_DOCX, TEMP_ZIP)

# unzip file zip to specific folder
with zipfile.ZipFile(TEMP_ZIP, 'r') as z:
    z.extractall(TEMP_FOLDER)

# change header xml file
header_xml = os.path.join(TEMP_FOLDER, "word", "header1.xml")
xmlstring = open(header_xml, 'r', encoding='utf-8').read()
xmlstring = xmlstring.replace("#TXTB1", "Hello World!")
with open(header_xml, "wb") as f:
    f.write(xmlstring.encode("UTF-8"))

# zip temp folder to zip file
os.remove(TEMP_ZIP)
shutil.make_archive(TEMP_ZIP.replace(".zip", ""), 'zip', TEMP_FOLDER)

# rename zip file to docx
os.rename(TEMP_ZIP, TEMP_DOCX)
shutil.rmtree(TEMP_FOLDER)

另一种方法,在内存中:

def docx_setup_header(doc_sio_1, new_title):
    """
    Returns a StringIO having replaced #TITLE# placeholder in document header with new_title
    :param doc_sio_1:  A StringIO instance of the docx document.
    :param new_title:  The new title to be inserted into header, replacing #TITLE# placeholder
    :return: A new StringIO instance, with modified document.
    """

    HEADER_PATH = 'word/header1.xml'

    doc_zip_1 = zipfile.ZipFile(doc_sio_1, 'r')
    header = doc_zip_1.read(HEADER_PATH)
    header = header.replace("#TITLE#", new_title)

    doc_sio_2 = StringIO.StringIO()
    doc_zip_2 = zipfile.ZipFile(doc_sio_2, 'w')
    for item in doc_zip_1.infolist():
        content = doc_zip_1.read(item.filename)
        if item.filename == HEADER_PATH:
            doc_zip_2.writestr(HEADER_PATH, header, zipfile.ZIP_DEFLATED)
        else:
            doc_zip_2.writestr(item, content)

    doc_zip_1.close()
    doc_zip_2.close()

    return doc_sio_2

请注意,Python的zip文件不能替换或删除项目,因此您需要制作一个全新的zip文件,并从原始文件中复制未更改的元素。