すべての費用でテキスト:PPT

しばらく前に、さまざまなデータ形式(PDFまたはDOC)からクリアテキストを取得することについて説明しました。 ある議論では 、PowerPointプレゼンテーションを解析することにより、I核や別のひどいソフトスポット病を獲得することが示唆されました。 まあ、運命の意志で、私はこの「甘い」フォーマットからテキストを取り出さなければなりませんでした。 率直に言って、私 hemoを獲得できませんでしたが、プレゼンテーションを解析するためのクラスが出てきました。

PPT形式についてはあまりない


DOCと同様に、PPTはWCBFF形式(構造化バイナリファイル形式)のアドオンです。これについては、前に書いたMS Wordに関する記事で読むことができます。 テスト中に、古いWCBFFDOCの実装でいくつかのエラー(さらに、テキストを取得しなければならない「壊れた」ファイルが多数見られた)を発見したことに注意してください。

気が散ります。 PowerPointについての話を続けましょう。 DOCとは異なり、以前のようにWordDocument1Table 「ファイル」ではなく、プレゼンテーション固有のCurrent UserPowerPoint Documentます。 プレゼンテーションには、CBFファイルの「ファイルシステム」に両方の「ファイル」が存在する必要があります。 彼らによると、誤った拡張の場合にプレゼンテーションがあると判断できます。

したがって、PPTからのデータの受信を開始するには、小さな「ファイル」レコード(または1つのCurrentUserAtomレコードで構成される「ファイル」) Current User CurrentUserAtom Current User 。 このエントリには、このファイルを最後に編集した人に関する技術情報が含まれていますが、これは最も重要ではありません。 このブロックには、以下で説明する最初のUserEditAtomへのオフセットに関する情報が含まれています。

次に、PPTレコードの読み取り方法を説明します。 プレゼンテーションのエントリには、特別な見出しrhが含まれています。これには、それに関する技術情報が含まれています。 これを行うには、レコードの最初の8バイトを読み取るだけです。 通常、最初の単語には必要な情報が含まれていませんが、次の6バイトが必要です。 オフセット2のWORD( rh.recType )は、次にレコードをどうするかを見つけることができるレコードのタイプを識別します。 オフセット4のLong( recLenrecLenバイトのヘッダーを除くレコードの長さ。 この記録方法は非常に便利で、プレゼンテーションファイルを解析する際の多くのエラーを回避します。

次は? UserEditAtomUserEditAtomます。 このエントリは既にPowerPoint Documentます。 後でこの「ファイル」でのみ作業します。 これと関連するエントリを読み取ることで、 PersistDirectoryオフセットの配列のようなすばらしいものを構築する必要があります。これを使用して、PowerPointドキュメントの主要な構造であるDocumentContainerを探します。 これを行うには、現在のUserEditAtomエントリを読み取り、現在の「ライブ」バージョンのPersistDirectoryへのオフセットoffsetLastEditと次のUserEditAtomへのオフセットoffsetLastEditoffsetLastEditがあります。 したがって、DWORD'e offsetLastEditゼロに遭遇するまでオフセットを受け取り続けます。

すべてのオフセットoffsetPersistDirectoryを受け取った後、このPersistDirectoryを作成する必要があります。 逆の順序でオフセットをPersistDirectoryAtomPersistDirectoryAtomエントリを読み取ります。 これらには、 PersistDirectoryEntryエントリの配列が含まれます。 それぞれには、最初のエントリのpersistId番号と現在のレコードの番号cPersistれます。 この情報の後に、 PersistDirectoryオブジェクトへのオフセットの配列がPersistDirectoryます。 これは、プレゼンテーションのすべてのオブジェクトへのリンクを見つけるための最も重要な配列です。

最後に読んだUserEditAtom戻って、 docPersistIdRefフィールドを見つけましょう。 これは、 PersistDirectory最も重要なDocumentContainerオブジェクトのPersistDirectoryです。 読んで 現在のプレゼンテーションに関する情報のキャリッジと小さなカートを保存します。ヘッダーとフッター、スライドのメモ、そして最も重要なのは、スライドに関するあらゆる種類の情報を含むSlideListWithTextContainerレコードです。

このメインブロックに格納されるレコードのタイプは、 TextBytesAtomSlidePersistAtomTextBytesAtom 3つだけSlidePersistAtom 。 最初の2つでは、すべてが単純です。これは、それぞれスライド上のUnicodeテキストと通常のANSIです。 もう1つは、テキストではなくSlidePersistAtomスライドへのリンクを取得する場合です。 それによると、PPTオブジェクトではないDrawingオブジェクトを読む必要があります( sic! )。 はい、この場合、MS Drawingオブジェクトはスライド内に埋め込まれ、ネストされたレコードのやや不快な構造になります。

この事実を初めて知ったとき、正直に言って、私は怒っていました。 ドキュメントのページでさらに600。 しかし、判明したように、 recTypeはPPTと同じrecType持つ同じrhヘッダー上に構築されます。 これにより、 Drawingオブジェクト内で、すべての同じTextCharsAtomおよびTextBytesAtomTextBytesAtom検索することで、タスクを簡単にし、少しチートすることができました。

実装


GitHubにコメントを付けコードを取得できます 。 まだ少し湿っていますが、近い将来、すべての落とし穴を見つけると思います。 PersistDirectory読み取りがまったく正しくない(?)ため、主なエラーが正確にポップアップします。 誰もが明確化を持っている場合、私は喜んでそれらに耳を傾けます。

文学




すべての費用でテキスト


Source: https://habr.com/ru/post/J76033/


All Articles