在docx中按顺序处理对象

问题描述 投票:0回答:1

我想按照Word文档中写入的顺序处理对象。我遇到的对象是段落、段落中的文本、段落中的运行、运行中的文本、表格以及表格单元格中的段落。到目前为止我有两个有用的程序。 遍历文档的段落并获取该段落的文本;存储在由[第#段]索引的列表中。这个程序能够从运行中收集文本;存储在由[段落#][运行#]索引的二维列表中,但我没有发现运行比段落的整个文本更有用。 我的第二个程序遍历整个文档并查找表格。当它有一个表格时,它会按行、单元格和单元格中的段落浏览表格。

现在这些似乎是实现我的目标的重要基石。我想按顺序收集文本。抽象地说,就好像一个人按住键盘上的右箭头命令闪烁的文本光标移动。当文本光标在对象上移动时,它通过多个索引来存储它们,标记对象的 # 和对象的类型。

假设我有子函数paragraph_read和table_read。假设文档具有以下对象顺序: 。我想仔细检查这些并按以下顺序执行我的子功能:paragraph_read、paragraph_read、table_read、paragraph_read

我想知道我的程序是否可以像向右滑动光标一样在文档对象中移动。

非常感谢您的帮助。谢谢。

-克里斯

python ms-word python-docx
1个回答
7
投票

更新

python-docx
中有一些新方法可以处理这里的大部分细节:

Document.iter_inner_content()
- 提供对文档中的
Paragraph
Table
对象的访问,按文档顺序:

for block_item in document:
    if isinstance(block_item, Paragraph):
        ... process paragraph ...
    elif isinstance(block_item, Table):
        ... process table ...

表格单元格也是块项容器并且具有相同的方法。如果您愿意,这允许递归到表中。

页眉和页脚对象也是块项容器并具有此方法。

节本身不是块项容器,但当您想要逐节迭代文档时,确实有此方法。


您需要将此函数添加到代码中方便的地方:

from docx.document import Document
from docx.oxml.table import CT_Tbl
from docx.oxml.text.paragraph import CT_P
from docx.table import _Cell, Table
from docx.text.paragraph import Paragraph


def iter_block_items(parent):
    """
    Yield each paragraph and table child within *parent*, in document
    order. Each returned value is an instance of either Table or
    Paragraph. *parent* would most commonly be a reference to a main
    Document object, but also works for a _Cell object, which itself can
    contain paragraphs and tables.
    """
    if isinstance(parent, Document):
        parent_elm = parent.element.body
    elif isinstance(parent, _Cell):
        parent_elm = parent._tc
    else:
        raise ValueError("something's not right")

    for child in parent_elm.iterchildren():
        if isinstance(child, CT_P):
            yield Paragraph(child, parent)
        elif isinstance(child, CT_Tbl):
            yield Table(child, parent)

然后你像这样使用它:

document = Document('my_document.docx')

for block_item in iter_block_items(document):
    if isinstance(block_item, Paragraph):
        do_paragraph_thing(paragraph=block_item)
    elif isinstance(block_item, Table):
        do_table_thing(table=block_item)
    else:
        # raise an exception or do nothing or whatever. This branch would
        # only be reached on an unforeseen error.
© www.soinside.com 2019 - 2024. All rights reserved.