ドキュメントの挿入と追加

場合によっては、複数の文書を 1 つに結合することが必要になることがあります。これは手動で行うことも、Aspose.Words の挿入または追加機能を使用することもできます。

挿入操作を使用すると、以前に作成したドキュメントのコンテンツを新規または既存のドキュメントに挿入できます。

さらに、追加機能を使用すると、別のドキュメントの末尾にのみドキュメントを追加できます。

この記事では、さまざまな方法でドキュメントを別のドキュメントに挿入または追加する方法について説明し、ドキュメントの挿入または追加中に適用できる共通のプロパティについて説明します。

ドキュメントの挿入

前述したように、Aspose.Words ではドキュメントはノードのツリーとして表現され、あるドキュメントを別のドキュメントに挿入する操作は、最初のドキュメント ツリーから 2 番目のドキュメント ツリーにノードをコピーすることです。

ドキュメントをさまざまな場所にさまざまな方法で挿入できます。たとえば、置換操作、差し込み操作中の差し込みフィールド、またはブックマークを通じてドキュメントを挿入できます。

Microsoft Word にドキュメントを挿入するのと似た InsertDocument または InsertDocumentInline メソッドを使用して、事前にインポートを行わずにドキュメント全体を現在のカーソル位置に挿入することもできます。

次のコード例は、InsertDocument メソッドを使用してドキュメントを挿入する方法を示しています。

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET.git.
Document srcDoc = new Document(MyDir + "Document source.docx");
Document dstDoc = new Document(MyDir + "Northwind traders.docx");
DocumentBuilder builder = new DocumentBuilder(dstDoc);
builder.MoveToDocumentEnd();
builder.InsertBreak(BreakType.PageBreak);
builder.InsertDocument(srcDoc, ImportFormatMode.KeepSourceFormatting);
builder.Document.Save(ArtifactsDir + "JoinAndAppendDocuments.InsertDocument.docx");

次のコード例は、InsertDocumentInline メソッドを使用してドキュメントを挿入する方法を示しています。

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET.git.
DocumentBuilder srcDoc = new DocumentBuilder();
srcDoc.Write("[src content]");
// Create destination document.
DocumentBuilder dstDoc = new DocumentBuilder();
dstDoc.Write("Before ");
dstDoc.InsertNode(new BookmarkStart(dstDoc.Document, "src_place"));
dstDoc.InsertNode(new BookmarkEnd(dstDoc.Document, "src_place"));
dstDoc.Write(" after");
Assert.AreEqual("Before after", dstDoc.Document.GetText().TrimEnd());
// Insert source document into destination inline.
dstDoc.MoveToBookmark("src_place");
dstDoc.InsertDocumentInline(srcDoc.Document, ImportFormatMode.UseDestinationStyles, new ImportFormatOptions());
Assert.AreEqual("Before [src content] after", dstDoc.Document.GetText().TrimEnd());

次のサブセクションでは、あるドキュメントを別のドキュメントに挿入できるオプションについて説明します。

検索と置換操作中にドキュメントを挿入する

検索および置換操作を実行中にドキュメントを挿入できます。たとえば、文書には [はじめに] と [結論] というテキストを含む段落を含めることができます。ただし、最終的な文書では、これらの段落を別の外部文書から取得したコンテンツに置き換える必要があります。これを実現するには、replace イベントのハンドラーを作成する必要があります。

次のコード例は、後の挿入プロセスで使用する置換イベントのハンドラーを作成する方法を示しています。

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET.git.
private class InsertDocumentAtReplaceHandler : IReplacingCallback
{
ReplaceAction IReplacingCallback.Replacing(ReplacingArgs args)
{
Document subDoc = new Document(MyDir + "Document insertion 2.docx");
// Insert a document after the paragraph, containing the match text.
Paragraph para = (Paragraph)args.MatchNode.ParentNode;
InsertDocument(para, subDoc);
// Remove the paragraph with the match text.
para.Remove();
return ReplaceAction.Skip;
}
}

次のコード例は、検索と置換操作中に、あるドキュメントのコンテンツを別のドキュメントに挿入する方法を示しています。

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET.git.
Document mainDoc = new Document(MyDir + "Document insertion 1.docx");
FindReplaceOptions options = new FindReplaceOptions
{
Direction = FindReplaceDirection.Backward,
ReplacingCallback = new InsertDocumentAtReplaceHandler()
};
mainDoc.Range.Replace(new Regex("\\[MY_DOCUMENT\\]"), "", options);
mainDoc.Save(ArtifactsDir + "CloneAndCombineDocuments.InsertDocumentAtReplace.docx");

Mail Merge 操作中にドキュメントを挿入する

mail merge 操作中に文書を差し込みフィールドに挿入できます。たとえば、mail merge テンプレートには、[概要] などの差し込みフィールドを含めることができます。ただし、最終的な文書では、別の外部文書から取得したコンテンツをこの差し込みフィールドに挿入する必要があります。これを実現するには、マージ イベントのハンドラーを作成する必要があります。

次のコード例は、マージ イベントのハンドラーを作成して、後の挿入プロセスで使用する方法を示しています。

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET.git.
private class InsertDocumentAtMailMergeHandler : IFieldMergingCallback
{
// This handler makes special processing for the "Document_1" field.
// The field value contains the path to load the document.
// We load the document and insert it into the current merge field.
void IFieldMergingCallback.FieldMerging(FieldMergingArgs args)
{
if (args.DocumentFieldName == "Document_1")
{
// Use document builder to navigate to the merge field with the specified name.
DocumentBuilder builder = new DocumentBuilder(args.Document);
builder.MoveToMergeField(args.DocumentFieldName);
// The name of the document to load and insert is stored in the field value.
Document subDoc = new Document((string)args.FieldValue);
InsertDocument(builder.CurrentParagraph, subDoc);
// The paragraph that contained the merge field might be empty now, and you probably want to delete it.
if (!builder.CurrentParagraph.HasChildNodes)
builder.CurrentParagraph.Remove();
// Indicate to the mail merge engine that we have inserted what we wanted.
args.Text = null;
}
}
void IFieldMergingCallback.ImageFieldMerging(ImageFieldMergingArgs args)
{
// Do nothing.
}
}

次のコード例は、作成されたハンドラーを使用して差し込みフィールドにドキュメントを挿入する方法を示しています。

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET.git.
Document mainDoc = new Document(MyDir + "Document insertion 1.docx");
mainDoc.MailMerge.FieldMergingCallback = new InsertDocumentAtMailMergeHandler();
// The main document has a merge field in it called "Document_1".
// The corresponding data for this field contains a fully qualified path to the document.
// That should be inserted to this field.
mainDoc.MailMerge.Execute(new[] { "Document_1" }, new object[] { MyDir + "Document insertion 2.docx" });
mainDoc.Save(ArtifactsDir + "CloneAndCombineDocuments.InsertDocumentAtMailMerge.doc");

ブックマーク {#insert-a-document-at-bookmark} にドキュメントを挿入する

テキスト ファイルをドキュメントにインポートし、ドキュメント内で定義したブックマークの直後に挿入できます。これを行うには、ドキュメントを挿入する場所にブックマーク付きの段落を作成します。

次のコーディング例は、あるドキュメントのコンテンツを別のドキュメントのブックマークに挿入する方法を示しています。

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET.git.
Document mainDoc = new Document(MyDir + "Document insertion 1.docx");
Document subDoc = new Document(MyDir + "Document insertion 2.docx");
Bookmark bookmark = mainDoc.Range.Bookmarks["insertionPlace"];
InsertDocument(bookmark.BookmarkStart.ParentNode, subDoc);
mainDoc.Save(ArtifactsDir + "CloneAndCombineDocuments.InsertDocumentAtBookmark.docx");

ドキュメントの追加

ドキュメントから既存のドキュメントの最後まで追加のページを含める必要があるユースケースがあるかもしれません。これを行うには、AppendDocument メソッドを呼び出してドキュメントを別のドキュメントの末尾に追加するだけです。

次のコード例は、ドキュメントを別のドキュメントの末尾に追加する方法を示しています。

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET.git.
Document dstDoc = new Document();
dstDoc.FirstSection.Body.AppendParagraph("Destination document text. ");
Document srcDoc = new Document();
srcDoc.FirstSection.Body.AppendParagraph("Source document text. ");
// Append the source document to the destination document.
// Pass format mode to retain the original formatting of the source document when importing it.
dstDoc.AppendDocument(srcDoc, ImportFormatMode.KeepSourceFormatting);
dstDoc.Save(ArtifactsDir + "JoinAndAppendDocuments.KeepSourceFormatting.docx");

ノードを手動でインポートおよび挿入する

Aspose.Words を使用すると、事前のインポート要件がなくても、ドキュメントを自動的に挿入および追加できます。ただし、ドキュメントの特定のノード (セクションや段落など) を挿入または追加する必要がある場合は、最初にこのノードを手動でインポートする必要があります。

あるセクションまたは段落を別のセクションまたは段落に挿入または追加する必要がある場合は、基本的に、ImportNode メソッドを使用して、最初のドキュメント ノード ツリーのノードを 2 番目のドキュメント ノード ツリーにインポートする必要があります。ノードをインポートした後、InsertAfter / InsertBefore メソッドを使用して、参照ノードの前後に新しいノードを挿入する必要があります。これにより、ドキュメントからノードをインポートし、指定された位置に挿入することで、挿入プロセスをカスタマイズできます。

たとえば、セクション レベルではなく段落レベルでコンテンツを追加する場合など、AppendChild メソッドを使用して、新しい指定したノードを子ノードのリストの末尾に追加することもできます。

次のコード例は、InsertAfter メソッドを使用してノードを手動でインポートし、特定のノードの後に挿入する方法を示しています。

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET.git.
/// <summary>
/// Inserts content of the external document after the specified node.
/// Section breaks and section formatting of the inserted document are ignored.
/// </summary>
/// <param name="insertionDestination">Node in the destination document after which the content
/// Should be inserted. This node should be a block level node (paragraph or table).</param>
/// <param name="docToInsert">The document to insert.</param>
private static void InsertDocument(Node insertionDestination, Document docToInsert)
{
if (insertionDestination.NodeType == NodeType.Paragraph || insertionDestination.NodeType == NodeType.Table)
{
CompositeNode destinationParent = insertionDestination.ParentNode;
NodeImporter importer =
new NodeImporter(docToInsert, insertionDestination.Document, ImportFormatMode.KeepSourceFormatting);
// Loop through all block-level nodes in the section's body,
// then clone and insert every node that is not the last empty paragraph of a section.
foreach (Section srcSection in docToInsert.Sections.OfType<Section>())
foreach (Node srcNode in srcSection.Body)
{
if (srcNode.NodeType == NodeType.Paragraph)
{
Paragraph para = (Paragraph)srcNode;
if (para.IsEndOfSection && !para.HasChildNodes)
continue;
}
Node newNode = importer.ImportNode(srcNode, true);
destinationParent.InsertAfter(newNode, insertionDestination);
insertionDestination = newNode;
}
}
else
{
throw new ArgumentException("The destination node should be either a paragraph or table.");
}
}

コンテンツはセクションごとに宛先ドキュメントにインポートされます。つまり、ページ設定やヘッダーまたはフッターなどの設定はインポート中に保持されます。また、ドキュメントを挿入または追加するときに書式設定を定義して、2 つのドキュメントを結合する方法を指定できることにも注意してください。

ドキュメントの挿入および追加の共通プロパティ

InsertDocument メソッドと AppendDocument メソッドはどちらも、入力パラメータとして ImportFormatModeImportFormatOptions を受け入れます。 ImportFormatMode を使用すると、UseDestinationStylesKeepSourceFormattingKeepDifferentStyles などのさまざまな形式モードを選択することで、あるドキュメントから別のドキュメントにコンテンツをインポートするときにドキュメントの書式設定をどのようにマージするかを制御できます。 ImportFormatOptions では、IgnoreHeaderFooterIgnoreTextBoxesKeepSourceNumberingMergePastedListsSmartStyleBehavior などのさまざまなインポート オプションを選択できます。

Aspose.Words を使用すると、Section プロパティと PageSetup プロパティを使用して、挿入または追加操作で 2 つのドキュメントを一緒に追加するときに、結果として得られるドキュメントの視覚化を調整できます。 PageSetup プロパティには、SectionStartRestartPageNumberingPageStartingNumberOrientation などのセクションのすべての属性が含まれます。最も一般的な使用例は、SectionStart プロパティを設定して、追加されたコンテンツを同じページに表示するか、新しいページに分割して表示するかを定義することです。

次のコード例は、コンテンツが 2 ページに分割されないようにしながら、あるドキュメントを別のドキュメントに追加する方法を示しています。

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET.git.
Document srcDoc = new Document(MyDir + "Document source.docx");
Document dstDoc = new Document(MyDir + "Northwind traders.docx");
// Set the source document to continue straight after the end of the destination document.
srcDoc.FirstSection.PageSetup.SectionStart = SectionStart.Continuous;
// Restart the page numbering on the start of the source document.
srcDoc.FirstSection.PageSetup.RestartPageNumbering = true;
srcDoc.FirstSection.PageSetup.PageStartingNumber = 1;
// To ensure this does not happen when the source document has different page setup settings, make sure the
// settings are identical between the last section of the destination document.
// If there are further continuous sections that follow on in the source document,
// this will need to be repeated for those sections.
srcDoc.FirstSection.PageSetup.PageWidth = dstDoc.LastSection.PageSetup.PageWidth;
srcDoc.FirstSection.PageSetup.PageHeight = dstDoc.LastSection.PageSetup.PageHeight;
srcDoc.FirstSection.PageSetup.Orientation = dstDoc.LastSection.PageSetup.Orientation;
// Iterate through all sections in the source document.
foreach (Paragraph para in srcDoc.GetChildNodes(NodeType.Paragraph, true))
{
para.ParagraphFormat.KeepWithNext = true;
}
dstDoc.AppendDocument(srcDoc, ImportFormatMode.KeepSourceFormatting);
dstDoc.Save(ArtifactsDir + "JoinAndAppendDocuments.DifferentPageSetup.docx");