ドキュメント パーツのテキストを検索して置換する
このトピックでは、Open XML SDK for Office のクラスを使用して、プログラムによってワープロ ドキュメント内のテキスト値を検索して置き換える方法について説明します。
パッケージとドキュメント パーツ
Open XML ドキュメントはパッケージとして格納され、その形式は ISO/IEC 29500 によって定義されます。 パッケージには、それらの間のリレーションシップを持つ複数のパーツを含めることができます。 パーツ間の関係によって、ドキュメントのカテゴリが制御されます。 ドキュメントは、パッケージリレーションシップアイテムにメインドキュメントパーツとの関係が含まれている場合、ワープロドキュメントとして定義できます。 パッケージリレーションシップ項目にプレゼンテーション パーツとのリレーションシップが含まれている場合は、プレゼンテーション ドキュメントとして定義できます。 パッケージリレーションシップアイテムにブックパーツとのリレーションシップが含まれている場合は、スプレッドシートドキュメントとして定義されます。 このハウツー トピックでは、ワープロ ドキュメント パッケージを使用します。
WordprocessingDocument オブジェクトの取得
サンプル コードでは、次の using
ステートメントに示すように、WordprocessingDocument クラスをインスタンス化してワープロ ファイルを開きます。 同じステートメントで、Open メソッドを使用してdocument
ワープロ ファイルを開き、Boolean パラメーターを true
に設定してドキュメントの編集を有効にします。
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(document, true))
v3.0.0 以降では、using ステートメントに依存することを優先して、Close() メソッドが削除されました。
これにより、閉じかっこに達したときに、 Dispose() メソッドが自動的に呼び出されます。 using ステートメントに続くブロックは、using ステートメントで作成または名前付けされたオブジェクトのスコープを確立します。 Open XML SDK の WordprocessingDocument クラスは、IDisposable実装の一部としてオブジェクトを自動的に保存および閉じます。また、ブロックを終了するとDispose()が自動的に呼び出されるため、using
ステートメントを使用する限り、明示的にSave()またはDispose()を呼び出す必要はありません。
サンプル コード
次の例は、すばやく簡単に検索して置換する方法を示します。 XML ドキュメントを文字列の形式で取得するため、信頼できない可能性があります。 正規表現によっては、誤って XML タグを置換して、ドキュメントが破損してしまうことがあります。 単にドキュメントを検索したいが、コンテンツを置き換えない場合は、 MainDocumentPart.Document.InnerText
を使用できます。
この例では、正規表現を使用して、ワープロ ファイルに格納されているテキスト値 "Hello World!" を "Hi Everyone!" という値に検索して置き換える方法も示します。 メソッド SearchAndReplace
を呼び出すには、次の例を使用できます。
SearchAndReplace(args[0]);
プログラムを実行した後で、ファイルを調べて "Hello world!" というテキストが変更されていることを確認できます。
以下に、C# と Visual Basic による完全なサンプル コードを示します。
static void SearchAndReplace(string document)
{
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(document, true))
{
string? docText = null;
if (wordDoc.MainDocumentPart is null)
{
throw new ArgumentNullException("MainDocumentPart and/or Body is null.");
}
using (StreamReader sr = new StreamReader(wordDoc.MainDocumentPart.GetStream()))
{
docText = sr.ReadToEnd();
}
Regex regexText = new Regex("Hello World!");
docText = regexText.Replace(docText, "Hi Everyone!");
using (StreamWriter sw = new StreamWriter(wordDoc.MainDocumentPart.GetStream(FileMode.Create)))
{
sw.Write(docText);
}
}
}