在 docx 中按顺序处理对象
Processing objects in order in docx
我想按照在 word 文档中写入的顺序处理对象。我遇到的对象是段落、段落中的文本、段落中的 运行、运行 中的文本、table 中的文本以及 table 单元格中的段落。到目前为止,我有两个有用的程序。
一个遍历文档的段落并获取该段落的文本;存储在由 [paragraph #] 索引的列表中。同一个程序能够从 运行s 中收集文本;存储在由 [paragraph#][运行#] 索引的二维列表中,但我没有找到更多的 运行s比段落的整个文本有用。
我的第二个程序遍历整个文档并找到 tables。当它有 table 时,它按行、单元格和单元格中的段落遍历 table。
现在这些似乎是我实现目标的重要组成部分。我想按顺序收集文本。抽象地说,就好像有人在键盘上按住向右箭头,命令闪烁的文本光标移动。当文本光标移动到对象上时,它通过标记对象的 # 和对象类型的几个索引来存储它们。
假设我有子函数 paragraph_read 和 table_read。假设文档具有以下对象顺序: .我想通过这些并按以下顺序执行我的子功能:paragraph_read、paragraph_read、table_read、paragraph_read
我想知道我的程序是否可以像向右滑动光标一样一个对象一个对象地移动文档对象。
非常感谢您的帮助。谢谢。
-克里斯
您需要将此函数添加到代码中方便的地方:
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.
我想按照在 word 文档中写入的顺序处理对象。我遇到的对象是段落、段落中的文本、段落中的 运行、运行 中的文本、table 中的文本以及 table 单元格中的段落。到目前为止,我有两个有用的程序。 一个遍历文档的段落并获取该段落的文本;存储在由 [paragraph #] 索引的列表中。同一个程序能够从 运行s 中收集文本;存储在由 [paragraph#][运行#] 索引的二维列表中,但我没有找到更多的 运行s比段落的整个文本有用。 我的第二个程序遍历整个文档并找到 tables。当它有 table 时,它按行、单元格和单元格中的段落遍历 table。
现在这些似乎是我实现目标的重要组成部分。我想按顺序收集文本。抽象地说,就好像有人在键盘上按住向右箭头,命令闪烁的文本光标移动。当文本光标移动到对象上时,它通过标记对象的 # 和对象类型的几个索引来存储它们。
假设我有子函数 paragraph_read 和 table_read。假设文档具有以下对象顺序: .我想通过这些并按以下顺序执行我的子功能:paragraph_read、paragraph_read、table_read、paragraph_read
我想知道我的程序是否可以像向右滑动光标一样一个对象一个对象地移动文档对象。
非常感谢您的帮助。谢谢。
-克里斯
您需要将此函数添加到代码中方便的地方:
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.