2017-02-07 44 views
1

オブジェクトをワードドキュメントで書かれた順番で処理したい。私が遭遇したオブジェクトは、段落、段落内のテキスト、段落内の段落、実行中のテキスト、表、段落などです。これまでは2つの便利なプログラムがあります。 文書の段落を通過し段落のテキストを取得するもの。 [paragraph#]で索引付けされたリストに格納されます。この同じプログラムには、実行からテキストを収集する機能があり、[段落番号] [実行番号]でインデックス付けされた2Dリストに格納されていますが、段落のテキスト全体よりも便利なランが見つかりませんでした。 私の2番目のプログラムは文書全体を調べ、テーブルを見つけます。テーブルがあると、行、セル、およびセル内の段落ごとにテーブルを通過します。docxで順にオブジェクトを処理する

これは私の目標にとって大きなビルディングブロックのようです。私は順番にテキストを集めたいと思う。抽象的には、あたかもキーボード上の右矢印を押した人が動くように点滅するテキストカーソルが命じられているかのように。テキストカーソルがオブジェクト上を移動するにつれて、オブジェクトの#とオブジェクトのタイプを示すいくつかのインデックスによってそれらを格納しています。

私はサブ関数paragraph_readとtable_readを持っているとします。文書にこのオブジェクトの順序があるとします。これらの項目を順番に実行したいと思います。paragraph_read、paragraph_read、table_read、paragraph_read

私のプログラムがカーソルをスワイプするようなオブジェクトによってドキュメントオブジェクト内を移動できるかどうかを知りたいと思います。

ヘルプが大きく改善されました。ありがとう。あなたがどこかに便利なコードにこの機能を追加する必要が

-Chris

+0

について説明し、いくつかの議論と、ここでコードがありますそれは:https://github.com/python-openxml/python-docx/issues/40です。最新バージョンに対応するためにいくつかの更新が行われた場所を最後まで見てください。 – scanny

+0

それはまさに私がやろうとしていることです。ポインタありがとう。 -Chris – Chris

+0

@scannyこのページのコードの理解に問題があります。あなたは私に話すことができますか?それとも何かをするためのヒントを教えてください。 – Chris

答えて

3

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. 
+0

属性エラーが発生しました: 'CT_Document'オブジェクトに '_body'属性がありません – Chris

+0

@Chris申し訳ありませんが、先頭にアンダースコアを付けずに 'body'にする必要があります。私はコードを更新しました。 – scanny

+0

あなたは大きな助けです。それは確かにその変更と一緒に働いた。私はdo_paragraph_thing(block_item、Paragraph)が私の関数のプレースホルダであり、block_itemに格納されているものであると考えました。私はまだプログラム全体の調整に取り組んでいますが、プログラムのこの重要な部分は、ボタンダウンされています。問題のあるボディはほぼフィットしています! :) – Chris

関連する問題