はじめに
このガイドでは、.NET 用の Aspose.Words FOSS がメモリ上で Word 文書をどのように表現するか、そしてその表現を構築、ナビゲート、変更するために使用される API について説明します: 逐次的な執筆のための DocumentBuilder、直接構造アクセスのためのノードツリー (Node、CompositeNode、NodeCollection)、すべてのノードタイプを一度に処理するための DocumentVisitor、Range と FindReplaceOptions を使用した検索置換、そして文書の結合やクローン作成のメソッドです。アナウンス投稿 がライブラリ全体を紹介しているのに対し、本稿はドキュメントオブジェクトモデル (DOM) — API の表面で最も大きな領域 — に焦点を当て、その構成要素がどのように組み合わさるかを解説します。
Aspose.Words FOSS for .NET は MIT ライセンスの下でリリースされており、ネイティブ依存はありません;.NET Standard 2.0 を対象としているため、ここで説明する DOM は .NET Framework 4.6.2 以降および .NET 6、8、10 で、Windows、Linux、macOS 上で利用可能です。NuGet でインストールするか、ソースからビルドしてください — 以下の クイックスタート を参照してください。
以下で説明するすべてのタスク — 新規にレポートを作成すること、既存の .docx ファイルを再構築すること、内容を走査して分析すること、または複数の文書を1つにまとめること — は、同じ少数の基本型から始まります: Document、DocumentBuilder、そしてそれらの下にある Node 階層です。
この Document Object Model
DocumentBuilder でドキュメントを構築する
DocumentBuilder はカーソルベースのライターで、Document の上に乗ってコンテンツを順次挿入します。Write(text) と Writeln(text) は現在位置にテキストを追加し、InsertParagraph() と InsertBreak(breakType) は段落およびページ/列/セクションの改ページを追加します。書式設定は状態を保持します: ビルダーの Font、ParagraphFormat、ListFormat、PageSetup プロパティは以降に書き込まれるすべてに適用され、PushFont() / PopFont() は現在のフォント状態を保存・復元するため、手動で一時的なスタイル変更を元に戻す必要がありません。ナビゲーションメソッドはカーソルを既存文書内の任意の位置に再配置します — MoveToDocumentStart()、MoveToDocumentEnd()、MoveToSection(sectionIndex)、MoveToBookmark(bookmarkName)、MoveToParagraph(paragraphIndex, characterIndex)、汎用的な MoveTo(node) — そして DocumentBuilder.CurrentNode、DocumentBuilder.CurrentParagraph、DocumentBuilder.CurrentSection はビルダーが現在どこにいるかを報告します。完全な DOM が不要な読み取り専用テキスト抽出の場合、PlainTextDocument は軽量なパスを提供します: new PlainTextDocument(fileName) は PlainTextDocument.Text プロパティと文書の組み込みおよびカスタムプロパティだけを公開します。
ノードツリー:セクション、段落、ラン、テーブル
Document は、ドキュメント自体を根とした Node オブジェクトのツリーです: 本文テキストの場合は Section → Body → Paragraph → Run、テーブルが出現する場所では Table → Row → Cell が分岐します。CompositeNode はすべてのコンテナノードの基底クラスで、直接走査するための CompositeNode.FirstChild、CompositeNode.LastChild、Node.NextSibling、Node.PreviousSibling を公開し、任意の深さで特定の NodeType(Paragraph、Run、Table など)を持つすべてのノードを収集するための GetChildNodes(nodeType, isDeep)、インデックス検索用の GetChild(nodeType, index, isDeep) を提供します。AppendChild(newChild)、InsertBefore(newChild, refChild)、InsertAfter(newChild, refChild)、RemoveChild(oldChild) はツリーを直接変更します。CompositeNode.SelectNodes(xpath) と SelectSingleNode(xpath) は手作業でツリーを歩く代わりに XPath スタイルの式でノードを選択し、非常に大きなドキュメントの場合、Node.NextPreOrder(rootNode) / PreviousPreOrder(rootNode) は再帰なしでノードを一つずつ順に処理します。
DocumentVisitor: すべてのノードタイプを一度のパスで処理する
サブクラス化 DocumentVisitor は、構造をハードコーディングせずにドキュメントを処理する方法です。これにより、すべての複合ノードタイプに対してペアになった Visit-Start / Visit-End メソッドが定義されます。対象には DocumentVisitor.VisitSectionStart、DocumentVisitor.VisitParagraphStart、DocumentVisitor.VisitTableStart、DocumentVisitor.VisitRowStart、DocumentVisitor.VisitCellStart、DocumentVisitor.VisitBookmarkStart が含まれ(それぞれに対応する End コールバックがあります)、さらに個別のテキストラン用に DocumentVisitor.VisitFieldStart、DocumentVisitor.VisitFieldSeparator、DocumentVisitor.VisitFieldEnd、DocumentVisitor.VisitRun が用意されています。Accept(visitor) を Document、Section、または任意の他のノードに対して呼び出すと、そのノードとその下位すべてに対してビジターを実行します。AcceptStart(visitor) と AcceptEnd(visitor) は単一の複合ノードに対してエントリとエグジットのコールバックのみを呼び出します。各 Visit メソッドは VisitorAction 値を返し、走査の続行方法を制御します — サブツリーへ Continue、SkipThisNode でスキップ、または Stop で完全に停止します。
テキストの検索と置換
Range.Replace(pattern, replacement) は、それが所有する Range(全体の Document、Section、または任意のノードの Range プロパティ)に対して検索文字列または正規表現として受け取れる検索パターンで検索・置換を実行します。Range.Replace(pattern, replacement, options) のオーバーロードは、FindReplaceOptions インスタンスを受け取り、FindReplaceOptions.MatchCase、FindReplaceOptions.FindWholeWordsOnly、検索方向 FindReplaceOptions.Direction(Forward または Backward の FindReplaceDirection 値)、置換テキストに適用される書式設定(FindReplaceOptions.ApplyFont、FindReplaceOptions.ApplyParagraphFormat)、およびどの周囲コンテンツをそのままにするか(FindReplaceOptions.IgnoreFields、FindReplaceOptions.IgnoreFootnotes、FindReplaceOptions.IgnoreFieldCodes および関連する Ignore* フラグ)を制御します。単純な置換以上のマッチごとのロジックが必要な場合は、IReplacingCallback の Replacing(args) メソッドを実装し、その実装を FindReplaceOptions.ReplacingCallback に割り当てます。各マッチは ReplacingArgs を伴ってコールバックされ、コールバックの戻り値(Replace、Skip、または Stop の ReplaceAction 値)がその処理結果を決定します。
ドキュメントの結合とクローン作成
Document.AppendDocument(srcDoc, importFormatMode) は、ある Document の全コンテンツを別の Document の末尾に追加します。その importFormatMode 引数(UseDestinationStyles、KeepSourceFormatting、または KeepDifferentStyles のいずれかの ImportFormatMode 値)は、ソースと宛先間のスタイル競合の解決方法を決定し、Document.AppendDocument(srcDoc, importFormatMode, importFormatOptions) のオーバーロードは ImportFormatOptions(ImportFormatOptions.KeepSourceNumbering、ImportFormatOptions.IgnoreHeaderFooter、ImportFormatOptions.MergePastedLists などのフラグ)を通じてより細かな制御を提供します。末尾ではなく特定の位置に別のドキュメントのコンテンツを挿入するには、DocumentBuilder.InsertDocument(srcDoc, importFormatMode, importFormatOptions) がビルダーの現在のカーソル位置から同等の操作を行い、DocumentBuilder.InsertDocumentInline(srcDoc, importFormatMode, importFormatOptions) は挿入ポイントで段落やセクション区切りを追加せずに同じコンテンツを挿入します。Document.ImportNode(srcNode, isImportChildren) は別のドキュメントから 1 つのノード(必要に応じて子ノードも)をコピーし、現在のドキュメントに追加できるようにします。また、任意のノードで利用可能な Node.Clone(isCloneChildren) メソッドは、同一ドキュメント内で構造を複製し、たとえば Section を繰り返しコンテンツのテンプレートとして再利用することができます。
ブックマークとドキュメント変数
Range.Bookmarks プロパティは、その範囲内の名前付きアンカーの BookmarkCollection を公開します。DocumentBuilder.StartBookmark(bookmarkName) と EndBookmark(bookmarkName) はビルド中にブックマークの範囲をマークします;BookmarkCollection インデクサーである bookmarks[name] は、後で DocumentBuilder.MoveToBookmark(bookmarkName) ナビゲーションや Bookmark.Text の読み取りのためにそれを取得します。別途、Document.Variables — VariableCollection — は、任意の名前/値文字列ペアをドキュメント自体に直接保存し、可視コンテンツを追加せずにドキュメント生成パイプラインを通じて小さな状態情報を運ぶのに便利です。
クイックスタート
Aspose.Words FOSS(.NET 用)は NuGet を通じて利用できます:
dotnet add package Aspose.Words.FOSS代わりにソースからビルドするには:
git clone https://github.com/aspose-words-foss/Aspose.Words-FOSS-for-.NET.git
cd Aspose.Words-FOSS-for-.NET
dotnet build Aspose.Words.sln -c Release
プロジェクト参照が Aspose.Words.csproj に設定されている場合、ドキュメントへの最短パスは本記事全体で使用されているパターンと同じです:Document を作成し、DocumentBuilder でラップし、Write() または Writeln() を呼び出してテキストを追加します — ビルダーの Font と ParagraphFormat プロパティで設定された書式は以降のすべての書き込みに引き継がれます — そして Document.Save(fileName) を呼び出して .docx、.docm、.dotx、.dotm、Flat OPC、Markdown、またはプレーンテキストとして出力します。最初から作成する代わりに既存のファイルを編集する場合は、new Document(fileName) で直接ロードし、MoveToBookmark()、MoveToParagraph()、または MoveTo(node) を使ってビルダーを特定の位置に移動し、そこから書き込みを続けます。
サポートされている形式
| フォーマット | 拡張子 | 読み取り | 書き込み |
|---|---|---|---|
| DOCX | .docx | ✓ | ✓ |
| DOCM | .docm | ✓ | ✓ |
| DOTX | .dotx | ✓ | ✓ |
| DOTM | .dotm | ✓ | ✓ |
| フラット OPC(すべてのバリエーション) | (さまざま) | ✓ | ✓ |
| Markdown | .md | ✓ | ✓ |
| Text | .txt | ✓ | ✓ |
上記で説明したノードツリーは、ドキュメントがどのフォーマットから読み込まれたか、またはどのフォーマットに保存されるかに関係なく同じ方法で利用できます — DOMは内部的にフォーマットに依存しません。このエディションに含まれていないのは、ページレイアウトに依存するものすべてです:PDF、XPS、画像エクスポートはなく、印刷もサポートされていません。そのため、ページ番号などのレイアウト依存フィールドの値は計算されずプレースホルダーとして評価されます。追加のフォーマットコンバータ(DOC、RTF、ODT、HTML、EPUB、MHTML、MOBI、AZW3、そしてWordML)は読み書きできず、メールマージ実行、LINQ Reporting、ドキュメント比較も含まれていません。これらの機能が必要な開発者は、DOMコードを書き直すことなく、商用Aspose.Words for .NET に移行できます。両エディションは同じ基盤となるAPIを共有しているためです。
オープンソース & ライセンス
Aspose.Words FOSS for .NET は MIT ライセンスの下でリリースされており、商用・個人利用ともにロイヤリティや再配布制限なしで無料です。上記で説明した Document、DocumentBuilder、およびノードツリー実装を含むソースは、Aspose.Words FOSS for .NET リポジトリ(GitHub 上)で利用可能です。