我正在使用python-docx模块读取和编辑一个.docm文件,该文件包含书签,如何使用该模块访问已经存储的所有书签,在文档对象中似乎没有任何方法。
发布于 2021-11-21 23:18:38
正如@D Malan所评论的,现在在2021年11月,它仍然是python-docx中的一个开放的issue。
同时,我们可以接受我们自己的实现。
请在可作为导入访问的文件夹中创建名为docxbookmark.py的文件:
from docx.document import Document as _innerdoclass
from docx import Document as _innerdocfn
from docx.oxml.shared import qn
from lxml.etree import Element as El
class Document(_innerdoclass):
def _bookmark_elements(self, recursive=True):
if recursive:
startag = qn('w:start')
bkms = []
def _bookmark_elements_recursive(parent):
if parent.tag == startag:
bkms.append(parent)
for el in parent:
_bookmark_elements_recursive(el)
_bookmark_elements_recursive(self._element)
return bkms
else:
return self._element.xpath('//'+qn('w:bookmarkStart'))
def bookmark_names(self):
"""
Gets a list of bookmarks
"""
return [v for bkmkels in self._bookmark_elements() for k,v in bkmkels.items() if k.endswith('}name')]
def add_bookmark(self, bookmarkname):
"""
Adds a bookmark with bookmark with name bookmarkname to the end of the file
"""
el = [el for el in self._element[0] if el.tag.endswith('}p')][-1]
el.append(El(qn('w:bookmarkStart'),{qn('w:id'):'0',qn('w:name'):bookmarkname}))
el.append(El(qn('w:bookmarkEnd'),{qn('w:id'):'0'}))
def __init__(self, innerDocInstance = None):
super().__init__(Document, None)
if innerDocInstance is not None and type(innerDocInstance) is _innerdoclass:
self.__body = innerDocInstance.__body
self._element = innerDocInstance._element
self._part = innerDocInstance._part
def DocumentCreate(docx=None):
"""
Return a |Document| object loaded from *docx*, where *docx* can be
either a path to a ``.docx`` file (a string) or a file-like object. If
*docx* is missing or ``None``, the built-in default document "template"
is loaded.
"""
return Document(_innerdocfn(docx))现在我们可以像使用旧的外观实现一样使用我们的外观实现,以及那些新的add_bookmark和bookmark_names。
要在新文件中添加书签,请导入我们的实现并在document对象上使用add_bookmark:
from docxbookmark import DocumentCreate as Document
doc = Document()
document.add_paragraph('First Paragraph')
document.add_bookmark('FirstBookmark')
document.add_paragraph('Second Paragraph')
document.save('docwithbookmarks.docx')要查看文档中的书签,请导入我们的实现并在document对象上使用bookmark_names:
from docxbookmark import DocumentCreate as Document
doc = Document('docwithbookmarks.docx')
doc.bookmark_names()返回的列表比其他对象更简单,它只显示字符串而不显示对象。有一个内部_bookmark_elements将返回与python-docx对象不同的lxml节点。
只做了几次测试,可能在很多情况下都不起作用。如果不起作用,请在评论中说明。
https://stackoverflow.com/questions/66355172
复制相似问题