パッケージからドキュメント パーツのコンテンツを取得する
このトピックでは、Open XML SDK for Office のクラスを使用して、プログラムによって Wordprocessing ドキュメント内のドキュメント パーツの内容を取得する方法について説明します。
パッケージとドキュメント パーツ
Open XML ドキュメントはパッケージとして格納され、その形式は ISO/IEC 29500 によって定義されます。 パッケージには、それらの間のリレーションシップを持つ複数のパーツを含めることができます。 パーツ間の関係によって、ドキュメントのカテゴリが制御されます。 ドキュメントは、パッケージリレーションシップアイテムにメインドキュメントパーツとの関係が含まれている場合、ワープロドキュメントとして定義できます。 パッケージリレーションシップ項目にプレゼンテーション パーツとのリレーションシップが含まれている場合は、プレゼンテーション ドキュメントとして定義できます。 パッケージリレーションシップアイテムにブックパーツとのリレーションシップが含まれている場合は、スプレッドシートドキュメントとして定義されます。 このハウツー トピックでは、ワープロ ドキュメント パッケージを使用します。
WordprocessingDocument オブジェクトの取得
コードは、文字列と、ファイルを読み取り/書き込みモードで開くかどうかを指定するブール値を受け取るWordprocessingDocument クラスのオーバーロードされたOpen メソッド (Visual Basic .NET Shared メソッドまたは C# 静的メソッド) のいずれかにファイル名を渡すことで、パッケージ ファイルを開くことから始まります。 この場合、ブール値は、誤った変更を避けるために、ファイルを読み取り専用モードで開く必要があることを指定 false
。
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(document, false))
v3.0.0 以降では、using ステートメントに依存することを優先して、Close() メソッドが削除されました。
これにより、閉じかっこに達したときに、 Dispose() メソッドが自動的に呼び出されます。 using ステートメントに続くブロックは、using ステートメントで作成または名前付けされたオブジェクトのスコープを確立します。 Open XML SDK の WordprocessingDocument クラスは、IDisposable実装の一部としてオブジェクトを自動的に保存および閉じます。また、ブロックを終了するとDispose()が自動的に呼び出されるため、using
ステートメントを使用する限り、明示的にSave()またはDispose()を呼び出す必要はありません。
WordProcessingML ドキュメントの構造
WordProcessingML
ドキュメントの基本的なドキュメント構造は、document
要素とbody
要素で構成され、その後に段落を表す p
などの 1 つ以上のブロック レベル要素が続きます。 段落には、1 つ以上の r
要素が含まれています。
r
は、書式設定などのプロパティの共通セットを持つテキストの領域である run を表します。 実行には、1 つ以上の t
要素が含まれています。
t
要素には、テキストの範囲が含まれています。 次のコード例は、"テキストの例" というテキストを含むドキュメントの WordprocessingML
マークアップを示しています。
<w:document xmlns:w="http://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
要素に対応する厳密に型指定されたクラスを使用して、ドキュメント構造とコンテンツを作成できます。 これらのクラスは、 名前空間にあります。 次の表に、 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/IEC 29500: 2016
次の XML スキーマ フラグメントは、この要素のコンテンツを定義します。
<complexType name="CT_Comments">
<sequence>
<element name="comment" type="CT_Comment" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
</complexType>
サンプル コードの動作のしくみ
読み取りのためにソース ファイルを開いた後、MainDocumentPart
をインスタンス化してmainPart
オブジェクトを作成します。 その後、ドキュメントの WordprocessingCommentsPart
部分への参照を作成できます。
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>();
その後、 StreamReader
オブジェクトを使用して、ドキュメントの WordprocessingCommentsPart
部分の内容を読み取り、その内容を返すことができます。
using (StreamReader streamReader = new StreamReader(WordprocessingCommentsPart.GetStream()))
{
comments = streamReader.ReadToEnd();
}
}
return comments;
サンプル コード
次のコードは、WordProcessing
ドキュメント パッケージに含まれるWordprocessingCommentsPart
パーツの内容を取得します。 プログラムを実行するには、次の例に示すように、 GetCommentsFromDocument
メソッドを呼び出します。
string document = args[0];
GetCommentsFromDocument(document);
以下は、C# および Visual Basic の完全なコード例です。
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;
}