Вмъкване и добавяне на документи

Понякога е необходимо да се комбинират няколко документа в един. Можете да направите това ръчно или можете да използвате Aspose.Words вмъкване или добавяне на функция.

Операцията Вмъкване ви позволява да вмъкнете съдържанието на предварително създадени документи В нов или съществуващ.

На свой ред функцията за добавяне ви позволява да добавите документ само в края на друг документ.

Тази статия обяснява как да вмъквате или добавяте документ към друг документ по различни начини и описва общите свойства, които можете да приложите, докато вмъквате или добавяте документи.

Вмъкване на документ

Както бе споменато по-горе, в Aspose.Words документ е представен като дърво от възли, а операцията по вмъкване на един документ в друг е копиране на възли от първото дърво на документа във второто.

Можете да вмъквате документи в различни местоположения по различни начини. Например можете да вмъкнете документ чрез операция за заместване, поле за обединяване по време на операция за обединяване или чрез отметка.

Можете също да използвате метода InsertDocument, който е подобен на вмъкване на документ в Microsoft Word, За да вмъкнете цял документ в текущата позиция на курсора без предишно импортиране.

Следващият пример за код показва как да вмъкнете документ, като използвате метода InsertDocument:

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

Следващите подраздели описват опциите, по време на които можете да вмъкнете един документ в друг.

Вмъкване на документ по време на операция търсене и замяна

Можете да вмъквате документи, докато извършвате операции за търсене и заместване. Например един документ може да съдържа параграфи с текст [INTRODUCTION] и [CONCLUSION]. Но в окончателния документ трябва да замените тези абзаци със съдържанието, получено от друг външен документ. За да постигнете това, ще трябва да създадете манипулатор за заместващото събитие.

Следващият пример за код показва как да създадете манипулатор за заместващото събитие, за да го използвате по-късно в процеса на вмъкване:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git.
class InsertDocumentAtReplaceHandler : public IReplacingCallback
{
private:
ReplaceAction Replacing(SharedPtr<ReplacingArgs> args) override
{
auto subDoc = MakeObject<Document>(MyDir + u"Document insertion 2.docx");
// Insert a document after the paragraph, containing the match text.
auto para = System::ExplicitCast<Paragraph>(args->get_MatchNode()->get_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-C.git.
auto mainDoc = MakeObject<Document>(MyDir + u"Document insertion 1.docx");
// Set find and replace options.
auto options = MakeObject<FindReplaceOptions>();
options->set_Direction(FindReplaceDirection::Backward);
options->set_ReplacingCallback(MakeObject<CloneAndCombineDocuments::InsertDocumentAtReplaceHandler>());
// Call the replace method.
mainDoc->get_Range()->Replace(MakeObject<System::Text::RegularExpressions::Regex>(u"\\[MY_DOCUMENT\\]"), u"", options);
mainDoc->Save(ArtifactsDir + u"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-C.git.
class InsertDocumentAtMailMergeHandler : public IFieldMergingCallback
{
private:
void FieldMerging(SharedPtr<FieldMergingArgs> args) override
{
if (args->get_DocumentFieldName() == u"Document_1")
{
// Use document builder to navigate to the merge field with the specified name.
auto builder = MakeObject<DocumentBuilder>(args->get_Document());
builder->MoveToMergeField(args->get_DocumentFieldName());
// The name of the document to load and insert is stored in the field value.
auto subDoc = MakeObject<Document>(System::ObjectExt::Unbox<String>(args->get_FieldValue()));
InsertDocument(builder->get_CurrentParagraph(), subDoc);
// The paragraph that contained the merge field might be empty now, and you probably want to delete it.
if (!builder->get_CurrentParagraph()->get_HasChildNodes())
{
builder->get_CurrentParagraph()->Remove();
}
// Indicate to the mail merge engine that we have inserted what we wanted.
args->set_Text(nullptr);
}
}
void ImageFieldMerging(SharedPtr<ImageFieldMergingArgs> args) override
{
ASPOSE_UNUSED(args);
// Do nothing.
}
};

Следващият пример за код показва как да вмъкнете документ в полето за обединяване с помощта на създадения манипулатор:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git.
auto mainDoc = MakeObject<Document>(MyDir + u"Document insertion 1.docx");
mainDoc->get_MailMerge()->set_FieldMergingCallback(MakeObject<CloneAndCombineDocuments::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->get_MailMerge()->Execute(MakeArray<String>({u"Document_1"}),
MakeArray<SharedPtr<System::Object>>({System::ObjectExt::Box<String>(MyDir + u"Document insertion 2.docx")}));
mainDoc->Save(ArtifactsDir + u"CloneAndCombineDocuments.InsertDocumentAtMailMerge.doc");

Вмъкване на документ в Отметка

Можете да импортирате текстов файл в документ и да го вмъкнете веднага след отметка, която сте дефинирали в документа. За да направите това, създайте маркиран абзац, в който искате да бъде вмъкнат документът.

Следващият пример за кодиране показва как да вмъкнете съдържанието на един документ в отметка в друг документ:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git.
auto mainDoc = MakeObject<Document>(MyDir + u"Document insertion 1.docx");
auto subDoc = MakeObject<Document>(MyDir + u"Document insertion 2.docx");
SharedPtr<Bookmark> bookmark = mainDoc->get_Range()->get_Bookmarks()->idx_get(u"insertionPlace");
InsertDocument(bookmark->get_BookmarkStart()->get_ParentNode(), subDoc);
mainDoc->Save(ArtifactsDir + u"CloneAndCombineDocuments.InsertDocumentAtBookmark.docx");

Добавяне на документ

Може да имате случай на използване, в който трябва да включите допълнителни страници от документ до края на съществуващ документ. За да направите това, просто трябва да извикате метода AppendDocument, за да добавите документ в края на друг.

Следният пример за код показва как да добавите документ към края на друг документ:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git.
auto dstDoc = MakeObject<Document>();
dstDoc->get_FirstSection()->get_Body()->AppendParagraph(u"Destination document text. ");
auto srcDoc = MakeObject<Document>();
srcDoc->get_FirstSection()->get_Body()->AppendParagraph(u"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 + u"JoinAndAppendDocuments.KeepSourceFormatting.docx");

Импортиране и вмъкване на възли ръчно

Aspose.Words Позволява ви да вмъквате и добавяте документи автоматично без никакви предишни изисквания за импортиране. Ако обаче трябва да вмъкнете или добавите конкретен възел на вашия документ, като например раздел или абзац, първо трябва да импортирате този възел ръчно.

Когато трябва да вмъкнете или добавите един раздел или абзац към друг, по същество трябва да импортирате възлите от дървото с възли на първия документ във второто, като използвате метода ImportNode. След импортиране на вашите възли, трябва да използвате метода InsertAfter / InsertBefore, за да вмъкнете нов възел след/преди референтния възел. Това ви позволява да персонализирате процеса на вмъкване, като импортирате възли от документ и го вмъквате на определени позиции.

Можете също да използвате метода AppendChild, за да добавите нов зададен възел в края на списъка на дъщерни възли, например ако искате да добавите съдържание на ниво абзац, вместо на ниво секция.

Следващият пример за код показва как ръчно да импортирате възли и да ги вмъквате след конкретен възел, като използвате метода InsertAfter:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.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>
static void InsertDocument(SharedPtr<Node> insertionDestination, SharedPtr<Document> docToInsert)
{
if (insertionDestination->get_NodeType() == NodeType::Paragraph || insertionDestination->get_NodeType() == NodeType::Table)
{
SharedPtr<CompositeNode> destinationParent = insertionDestination->get_ParentNode();
auto importer = MakeObject<NodeImporter>(docToInsert, insertionDestination->get_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.
for (const auto& srcSection : System::IterateOver(docToInsert->get_Sections()->LINQ_OfType<SharedPtr<Section>>()))
{
for (const auto& srcNode : System::IterateOver(srcSection->get_Body()))
{
if (srcNode->get_NodeType() == NodeType::Paragraph)
{
auto para = System::ExplicitCast<Paragraph>(srcNode);
if (para->get_IsEndOfSection() && !para->get_HasChildNodes())
{
continue;
}
}
SharedPtr<Node> newNode = importer->ImportNode(srcNode, true);
destinationParent->InsertAfter(newNode, insertionDestination);
insertionDestination = newNode;
}
}
}
else
{
throw System::ArgumentException(u"The destination node should be either a paragraph or table.");
}
}

Съдържанието се импортира в раздела местоназначение документ по раздел, което означава, че настройките, като например настройка на страници и горни или долни колонтитули, се запазват по време на импортирането. Също така е полезно да се отбележи, че можете да дефинирате настройки за форматиране, когато вмъквате или добавяте документ, за да зададете как да се свържат два документа.

Общи свойства за вмъкване и добавяне на документи

InsertDocument и AppendDocument методите приемат ImportFormatMode и ImportFormatOptions като входни параметри. ImportFormatMode ви позволява да контролирате как се обединява форматирането на документи, когато импортирате съдържание от един документ в друг, като изберете различни режими на форматиране, като например UseDestinationStyles, KeepSourceFormatting и KeepDifferentStyles. ImportFormatOptions ви позволява да изберете различни опции за импортиране, като напримерIgnoreHeaderFooter, IgnoreTextBoxes, KeepSourceNumbering, MergePastedLists, и SmartStyleBehavior.

Aspose.Words Позволява ви да регулирате визуализацията на получения документ, когато два документа се добавят заедно в операция вмъкване или Добавяне, като използвате свойствата Section и PageSetup. PageSetup собственост съдържа всички атрибути на раздел като SectionStart, RestartPageNumbering, PageStartingNumber, Orientation, и други. Най-често използваният случай е да зададете свойството SectionStart, за да определите дали добавеното съдържание ще се показва на същата страница или ще се раздели на нова.

Следващият пример за код показва как да добавите един документ към друг, като същевременно не разделяте съдържанието на две страници:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git.
auto srcDoc = MakeObject<Document>(MyDir + u"Document source.docx");
auto dstDoc = MakeObject<Document>(MyDir + u"Northwind traders.docx");
// Set the source document to continue straight after the end of the destination document.
srcDoc->get_FirstSection()->get_PageSetup()->set_SectionStart(SectionStart::Continuous);
// Restart the page numbering on the start of the source document.
srcDoc->get_FirstSection()->get_PageSetup()->set_RestartPageNumbering(true);
srcDoc->get_FirstSection()->get_PageSetup()->set_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->get_FirstSection()->get_PageSetup()->set_PageWidth(dstDoc->get_LastSection()->get_PageSetup()->get_PageWidth());
srcDoc->get_FirstSection()->get_PageSetup()->set_PageHeight(dstDoc->get_LastSection()->get_PageSetup()->get_PageHeight());
srcDoc->get_FirstSection()->get_PageSetup()->set_Orientation(dstDoc->get_LastSection()->get_PageSetup()->get_Orientation());
// Iterate through all sections in the source document.
for (const auto& para : System::IterateOver<Paragraph>(srcDoc->GetChildNodes(NodeType::Paragraph, true)))
{
para->get_ParagraphFormat()->set_KeepWithNext(true);
}
dstDoc->AppendDocument(srcDoc, ImportFormatMode::KeepSourceFormatting);
dstDoc->Save(ArtifactsDir + u"JoinAndAppendDocuments.DifferentPageSetup.docx");