gpt4 book ai didi

python-3.x - python-docx插入点

转载 作者:行者123 更新时间:2023-12-04 10:07:19 24 4
gpt4 key购买 nike

我不确定是否遗漏了任何明显的内容,但是我还没有找到任何有关如何将Word元素(例如表格)插入文档中特定位置的文档?

我正在使用以下方式加载现有的MS Word .docx文档:

my_document = Document('some/path/to/my/document.docx')

我的用例是获取文档中书签或部分的“位置”,然后继续在该点下方插入表格。

我正在考虑一个API,该API可以使我沿着这些思路做一些事情:
insertion_point = my_document.bookmarks['bookmark_name'].position
my_document.add_table(rows=10, cols=3, position=insertion_point+1)

我看到有计划实现类似于MS Word API的“范围”对象的计划,这将有效地解决该问题。同时,是否有一种方法可以指示 document对象方法在哪里插入新元素?

也许我可以粘贴一些lxml代码来找到一个节点并将其传递给这些python-docx方法?在这个问题上的任何帮助将不胜感激!谢谢。

最佳答案

我想起一句古老的格言:“使用消息来源,卢克!”,并且可以弄清楚。 python-docx所有者在其git项目页面上的帖子也给了我一个提示:https://github.com/python-openxml/python-docx/issues/7

完整的XML文档模型可以通过使用其_document_part._element属性进行访问。它的行为完全类似于lxml etree元素。从那里,一切皆有可能。

为了解决特定的插入点问题,我创建了一个temp docx.Document对象,该对象用于存储生成的内容。

import docx
from docx.oxml.shared import qn
tmp_doc = docx.Document()

# Generate content in tmp_doc document
tmp_doc.add_heading('New heading', 1)
# more content generation using docx API.
# ...

# Reference the tmp_doc XML content
tmp_doc_body = tmp_doc._document_part._element.body
# You could pretty print it by using:
#print(docx.oxml.xmlchemy.serialize_for_reading(tmp_doc_body))

然后,我将docx模板(包含名为“insertion_point”的书签)加载到第二个docx.Document对象中。
doc = docx.Document('/some/path/example.docx')
doc_body = doc._document_part._element.body
#print(docx.oxml.xmlchemy.serialize_for_reading(doc_body))

下一步是解析doc XML以找到插入点的索引。我为手头的任务定义了一个小函数,该函数返回一个命名的书签父段元素:
def get_bookmark_par_element(document, bookmark_name):
"""
Return the named bookmark parent paragraph element. If no matching
bookmark is found, the result is '1'. If an error is encountered, '2'
is returned.
"""
doc_element = document._document_part._element
bookmarks_list = doc_element.findall('.//' + qn('w:bookmarkStart'))
for bookmark in bookmarks_list:
name = bookmark.get(qn('w:name'))
if name == bookmark_name:
par = bookmark.getparent()
if not isinstance(par, docx.oxml.CT_P):
return 2
else:
return par
return 1

新定义的函数用于获取书签“insertion_point”的父段。错误控制留给读者。
bookmark_par = get_bookmark_par_element(doc, 'insertion_point')

现在,我们可以使用bookmark_par的etree索引在正确的位置插入我们的tmp_doc生成的内容:
bookmark_par_parent = bookmark_par.getparent()
index = bookmark_par_parent.index(bookmark_par) + 1
for child in tmp_doc_body:
bookmark_par_parent.insert(index, child)
index = index + 1
bookmark_par_parent.remove(bookmark_par)

现在完成文档,将生成的内容插入到现有Word文档的书签位置。
# Save result
# print(docx.oxml.xmlchemy.serialize_for_reading(doc_body))
doc.save('/some/path/generated_doc.docx')

我希望这可以对某人有所帮助,因为与此相关的文档尚未编写。

关于python-3.x - python-docx插入点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24965042/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com