在保持功能的同时替换 XML 中的字符串

Replace String in XML while keeping function

嗨,我是新来的,我需要帮助解决一个问题。

我正在尝试使用 python-docx 基于模板生成包含数据的 word 文档。 在大多数情况下,我已经设法解决了一些问题。但是,我的文档有一些我想要满足的条件,即我只需要在 最后一页 .

中生成某些数据

问题是,我不知道 "last page" 是什么,因为它取决于添加到模板中的数据量,所以它可能是 1、2 或 50。Python-docx ,像 Reportlab 等许多其他类似的库一样,没有指示最后一页是什么的功能(至少,我发现 none)。因此,在大量谷歌搜索之后,我发现了一个可以在我的模板中实现的 Microsoft Word 中创建的函数: { IF PAGE=NUMPAGES testVar }

而且我设法做到了 testVar 只显示在最后一页。

现在的问题是,在生成文档之前,我需要通过 Python 将 testVar 替换为实际计算值。 我之前试过:

theFooter = section.footer.tables[0]
theFooter.cell(0,2).text = 1000

(上述函数在模板页脚的table中)

虽然它用 1000 替换了 testVar,但模板中的 docx 函数也被 替换了。 所以现在我卡住了,试图弄清楚如何替换 testVar 而无需 删除 docx 函数,以便显示我的 100 值 在最后一页,无论在哪里。

A crop of the template in question (100值只是一个占位符变量,对应testVar

关于如何正确执行此操作的任何建议? 我搜索了 Whosebug,遇到了一些 similar 但它们最终与我需要的不同。

经过大量阅读,我想我可能终于找到了解决方案,尽管是间接的。

根据this and (我通过 dir() 进行了验证),每个 _element 也有一个 'text' 属性。

所以,我按照这些思路做了一些事情:

    theFooter = document.sections[0].footer.tables[0]
    for run in theFooter.cell(1,3).paragraphs[0].runs:
        if 'w:instrText' in run._element.xml and 'xml:space="preserve"' in run._element.xml:
            if (run._element.xml.find("testVar") >= 0): run._element.text= "1000"

这似乎成功地将我模板中的 'testVar' 替换为 '1000' 字符串,而不影响我生成 word 文档时的 docx 函数,导致 '1000' 被打印 在最后一页的页脚。

唯一奇怪的是,当我运行打印输出时使用:

theFooter.cell(1,3).text

我得到的输出是“1000testVar”,所以我不确定这在长期 运行 中是否重要。

编辑 2020 年 6 月 2 日

Welp,发现了一个限制(或者它可能与 Word 功能有关,我不确定):替换文本不能有任何间距(例如,“Replace Var”与“ReplaceVar”相比),否则它所做的只是将“testVar”替换为“Var”(而不是将“testVar”替换为“Replace Var”)并且“Replace”仍将显示在输出中。

编辑 2020 年 9 月 9 日

只是觉得我应该更新这个,因为我找到了对上述限制的修复。

我需要做的就是将模板中的变量封装在引号 "" 中,如下所示:

{IF PAGE=NUMPAGES "testVar" }

并且按预期工作;用数据正确替换 testVar 变量,即使所述数据是带间距的文本。(例如“100 次”)