パッケージからドキュメント パーツのコンテンツを取得する
このトピックでは、Open XML SDK for Office のクラスを使用して、プログラムによって Wordprocessing ドキュメント内のドキュメント パーツの内容を取得する方法について説明します。
パッケージとドキュメント パーツ
Open XML ドキュメントは、 ISO/IEC 29500-2 で定義された形式のパッケージとして格納されます。 パッケージには、それらの間のリレーションシップを持つ複数のパーツを含めることができます。 パーツ間の関係によって、ドキュメントのカテゴリが制御されます。 ドキュメントは、パッケージリレーションシップアイテムにメインドキュメントパーツとの関係が含まれている場合、ワープロドキュメントとして定義できます。 パッケージリレーションシップ項目にプレゼンテーション パーツとのリレーションシップが含まれている場合は、プレゼンテーション ドキュメントとして定義できます。 パッケージリレーションシップアイテムにブックパーツとのリレーションシップが含まれている場合は、スプレッドシートドキュメントとして定義されます。 このハウツー トピックでは、ワープロ ドキュメント パッケージを使用します。
WordprocessingDocument オブジェクトの取得
コードは、文字列とファイルを読み取り/書き込みモードで開くかどうかを指定するブール値を受け取る WordprocessingDocument クラスのオーバーロードされた Open() メソッド (Visual Basic .NET Shared メソッドまたは C# 静的メソッド) のいずれかにファイル名を渡すことで、パッケージ ファイルを開くことから始まります。 この例では、ブール値は false であり、ファイルを読み取り専用モードで開いて不用意な変更を防いでいます。
// Open a Wordprocessing document for editing.
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(document, false))
{
// Insert other code here.
}
using ステートメントは、一般的な .Create, .Save, .Close シーケンスに代わる手段として推奨されます。 これによって、閉じかっこに達したときに、 Dispose メソッド (Open XML SDK がリソースをクリーンアップするために使用する内部メソッド) が自動的に呼び出されます。 using ステートメントに続くブロックは、作成された、または using ステートメントで指定されたオブジェクト (この場合は wordDoc) のスコープを設定します。 Open XML SDK の WordprocessingDocument クラスは、 System.IDisposable 実装の一部として自動的にオブジェクトを保存して閉じるため、また、 Dispose メソッドがブロックの終わりで自動的に呼び出されるため、using を使用する場合は、 Save および Close を明示的に呼び出す必要はありません。
WordProcessingML ドキュメントの構造
WordProcessingML ドキュメントの基本ドキュメント構造は、 document 要素と body 要素、およびそれに続く 1 つ以上のブロック レベルの要素 (段落を表す p など) で構成されます。 段落には 1 つ以上の r 要素が含まれます。 r はセクションを表し、書式などの共通のプロパティ セットを含むテキストの領域です。 セクションには 1 つ以上の t 要素が含まれます。 t 要素には、さまざまなテキストが含まれます。 次のコード例は、テキスト "Example text." を含むドキュメントの WordprocessingML マークアップを示します。
<w:document xmlns:w="https://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:body>
<w:p>
<w:r>
<w:t>Example text.</w:t>
</w:r>
</w:p>
</w:body>
</w:document>
Open XML SDK を使用すると、 WordprocessingML 要素に対応する厳密に型指定されたクラスを使用して、ドキュメント構造とコンテンツを作成できます。 これらのクラスは、DocumentFormat.OpenXml.Wordprocessing 名前空間にあります。 次の表に、document、body、p、r、t の各要素に対応するクラスのクラス名を示します。
WordprocessingML の要素 | Open XML SDK クラス | 説明 |
---|---|---|
document | Document | メイン ドキュメント パーツのルート要素 |
body | Body | ISO/IEC 29500 仕様で指定されている、段落、表、注釈などのブロック レベル構造のコンテナー |
p | Paragraph | 段落 |
r | Run | セクション |
t | Text | さまざまなテキスト |
WordprocessingML ドキュメントのパーツと要素の全体的な構造の詳細については、「 WordprocessingML ドキュメントの構造」を参照してください。
Comments 要素
このハウツーでは、コメントを操作します。 そのため、<comments> 要素の構造について十分に理解することが役立ちます。 この要素を操作するには、ISO/IEC 29500 の仕様に記載されている次の情報が役立ちます。
この要素は、現在のドキュメントに定義されているすべてのコメントを指定します。 これは、WordprocessingML ドキュメントのコメント 部分のルート要素です。WordprocessingML ドキュメント内のコメント パーツの内容については、次の WordprocessingML フラグメントを検討してください。
<w:comments>
<w:comment … >
…
</w:comment>
</w:comments>
この例では、このドキュメントで指定される単一のコメントが comments 要素に格納されます。
© ISO/IEC29500: 2008.
次の XML スキーマ フラグメントは、この要素のコンテンツを定義します。
<complexType name="CT_Comments">
<sequence>
<element name="comment" type="CT_Comment" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
</complexType>
サンプル コードの動作のしくみ
読み取り用のソース ファイルを開いた後、 MainDocumentPart をインスタンス化して mainPart オブジェクトを作成します。 その後、ドキュメントの WordprocessingCommentsPart パーツへの参照を作成できます。
// To get the contents of a document part.
public static string GetCommentsFromDocument(string document)
{
string comments = null;
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(document, true))
{
MainDocumentPart mainPart = wordDoc.MainDocumentPart;
WordprocessingCommentsPart WordprocessingCommentsPart = mainPart.WordprocessingCommentsPart;
次に、 StreamReader オブジェクトを使用して、ドキュメントの WordprocessingCommentsPart パーツのコンテンツを読み取り、そのコンテンツを返すことができます。
using (StreamReader streamReader = new StreamReader(WordprocessingCommentsPart.GetStream()))
{
comments = streamReader.ReadToEnd();
}
}
return comments;
サンプル コード
以下のコードでは、 WordProcessing ドキュメント パッケージに含まれる WordprocessingCommentsPart パーツのコンテンツを取得します。 このプログラムは、次の例に示すように、 GetCommentsFromDocument メソッドを呼び出すことで実行できます。
string document = @"C:\Users\Public\Documents\MyPkg5.docx";
GetCommentsFromDocument(document);
以下は、C# および Visual Basic の完全なコード例です。
using DocumentFormat.OpenXml.Packaging;
using System;
using System.IO;
GetCommentsFromDocument(args[0]);
// To get the contents of a document part.
static string GetCommentsFromDocument(string document)
{
string? comments = null;
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(document, false))
{
if (wordDoc is null)
{
throw new ArgumentNullException(nameof(wordDoc));
}
MainDocumentPart mainPart = wordDoc.MainDocumentPart ?? wordDoc.AddMainDocumentPart();
WordprocessingCommentsPart WordprocessingCommentsPart = mainPart.WordprocessingCommentsPart ?? mainPart.AddNewPart<WordprocessingCommentsPart>();
using (StreamReader streamReader = new StreamReader(WordprocessingCommentsPart.GetStream()))
{
comments = streamReader.ReadToEnd();
}
}
return comments;
}