Chèn Và Nối Thêm Tài liệu
Đôi khi cần phải kết hợp nhiều tài liệu thành một. Bạn có thể thực hiện việc này theo cách thủ công hoặc bạn có thể sử dụng tính năng chèn hoặc nối Aspose.Words.
Thao tác chèn cho phép bạn chèn nội dung của các tài liệu đã tạo trước đó vào một tài liệu mới hoặc hiện có.
Đổi lại, tính năng append cho phép bạn chỉ thêm một tài liệu ở cuối tài liệu khác.
Bài viết này giải thích cách chèn hoặc nối tài liệu vào tài liệu khác theo những cách khác nhau và mô tả các thuộc tính chung mà bạn có thể áp dụng trong khi chèn hoặc nối tài liệu.
Chèn Tài liệu
Như đã đề cập ở trên, trong Aspose.Words một tài liệu được biểu diễn dưới dạng cây của các nút và hoạt động chèn một tài liệu này vào một tài liệu khác là sao chép các nút từ cây tài liệu đầu tiên sang cái thứ hai.
Bạn có thể chèn tài liệu ở nhiều vị trí khác nhau theo nhiều cách khác nhau. Ví dụ: bạn có thể chèn tài liệu thông qua thao tác thay thế, trường hợp nhất trong thao tác hợp nhất hoặc thông qua dấu trang.
Bạn cũng có thể sử dụng phương thức InsertDocument, tương tự như chèn tài liệu vào Microsoft Word, để chèn toàn bộ tài liệu ở vị trí con trỏ hiện tại mà không cần nhập trước đó.
Ví dụ mã sau đây cho thấy cách chèn tài liệu bằng phương thức 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"); |
Các phần phụ sau đây mô tả các tùy chọn trong đó bạn có thể chèn một tài liệu này vào tài liệu khác.
Chèn Tài liệu Trong Quá trình Tìm Và Thay Thế Thao tác
Bạn có thể chèn tài liệu trong khi thực hiện tìm và thay thế các thao tác. Ví dụ, một tài liệu có thể chứa các đoạn văn với văn bản [INTRODUCTION] và [CONCLUSION]. Nhưng trong tài liệu cuối cùng, bạn cần thay thế các đoạn văn đó bằng nội dung thu được từ một tài liệu bên ngoài khác. Để đạt được điều đó, bạn sẽ cần tạo một trình xử lý cho sự kiện thay thế.
Ví dụ mã sau đây cho thấy cách tạo trình xử lý cho sự kiện thay thế để sử dụng nó sau này trong quá trình chèn:
// 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; | |
} | |
}; |
Ví dụ mã sau đây cho thấy cách chèn nội dung của tài liệu này vào tài liệu khác trong quá trình tìm và thay thế hoạt động:
// 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"); |
Chèn Một Tài Liệu Trong Mail Merge Hoạt động
Bạn có thể chèn một tài liệu vào một trường hợp nhất trong một hoạt động mail merge. Ví dụ: mẫu Mail Merge có thể chứa trường hợp nhất như [Tóm tắt]. Nhưng trong tài liệu cuối cùng, bạn cần chèn nội dung thu được từ một tài liệu bên ngoài khác vào trường hợp nhất này. Để đạt được điều đó, bạn sẽ cần tạo một trình xử lý cho sự kiện hợp nhất.
Ví dụ mã sau đây cho thấy cách tạo trình xử lý cho sự kiện hợp nhất để sử dụng nó sau này trong quá trình chèn:
// 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. | |
} | |
}; |
Ví dụ mã sau đây cho thấy cách chèn tài liệu vào trường hợp nhất bằng trình xử lý đã tạo:
// 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"); |
Chèn Tài liệu tại Dấu Trang
Bạn có thể nhập tệp văn bản vào tài liệu và chèn nó ngay sau dấu trang mà bạn đã xác định trong tài liệu. Để thực hiện việc này, hãy tạo một đoạn được đánh dấu trang nơi bạn muốn chèn tài liệu.
Ví dụ mã hóa sau đây cho thấy cách chèn nội dung của một tài liệu vào dấu trang trong một tài liệu khác:
// 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"); |
Nối Thêm Một Tài liệu
Bạn có thể có trường hợp sử dụng trong đó bạn cần bao gồm các trang bổ sung từ tài liệu đến cuối tài liệu hiện có. Để thực hiện việc này, bạn chỉ cần gọi phương thức AppendDocument để thêm tài liệu vào cuối tài liệu khác.
Ví dụ mã sau đây cho thấy cách nối tài liệu vào cuối tài liệu khác:
// 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"); |
Nhập Và Chèn Các Nút theo Cách Thủ công
Aspose.Words cho phép bạn chèn và nối thêm tài liệu tự động mà không cần bất kỳ yêu cầu nhập trước đó. Tuy nhiên, nếu bạn cần chèn hoặc nối thêm một nút cụ thể của tài liệu, chẳng hạn như một phần hoặc một đoạn văn, thì trước tiên bạn cần nhập nút này theo cách thủ công.
Khi bạn cần chèn hoặc nối một phần hoặc đoạn này sang phần khác, về cơ bản bạn cần nhập các nút của cây nút tài liệu đầu tiên vào phần thứ hai bằng phương thức ImportNode. Sau khi nhập các nút của bạn, bạn cần sử dụng phương thức InsertAfter/InsertBefore để chèn một nút mới sau/trước nút tham chiếu. Điều này cho phép bạn tùy chỉnh quá trình chèn bằng cách nhập các nút từ tài liệu và chèn nó vào các vị trí đã cho.
Bạn cũng có thể sử dụng phương thức AppendChild để thêm một nút được chỉ định mới vào cuối danh sách các nút con, ví dụ: nếu bạn muốn nối thêm nội dung ở cấp đoạn thay vì ở cấp phần.
Ví dụ mã sau đây cho thấy cách nhập thủ công các nút và chèn chúng sau một nút cụ thể bằng phương thức 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."); | |
} | |
} |
Nội dung được nhập vào phần tài liệu đích theo từng phần, có nghĩa là các cài đặt, chẳng hạn như thiết lập trang và đầu trang hoặc chân trang, được giữ nguyên trong quá trình nhập. Cũng rất hữu ích khi lưu ý rằng bạn có thể xác định cài đặt định dạng khi chèn hoặc nối thêm tài liệu để chỉ định cách hai tài liệu được nối với nhau.
Các Thuộc tính phổ biến Để Chèn Và Nối Thêm Tài liệu
Cả hai InsertDocument và AppendDocument các phương thức chấp nhận ImportFormatMode và ImportFormatOptions làm tham số đầu vào. ImportFormatMode cho phép bạn kiểm soát cách định dạng tài liệu được hợp nhất khi bạn nhập nội dung từ tài liệu này sang tài liệu khác bằng cách chọn các chế độ định dạng khác nhau như UseDestinationStyles, KeepSourceFormatting và KeepDifferentStyles. ImportFormatOptions cho phép bạn chọn các tùy chọn nhập khác nhau như IgnoreHeaderFooter, IgnoreTextBoxes, KeepSourceNumbering, MergePastedLists, và SmartStyleBehavior.
Aspose.Words cho phép bạn điều chỉnh hình ảnh trực quan của tài liệu kết quả khi hai tài liệu được thêm vào với nhau trong thao tác chèn hoặc nối thêm bằng cách sử dụng thuộc tính Section và PageSetup. Thuộc tính PageSetup chứa tất cả các thuộc tính của một phần như SectionStart, RestartPageNumbering, PageStartingNumber, Orientation, và những người khác. Trường hợp sử dụng phổ biến nhất là đặt thuộc tính SectionStart để xác định xem nội dung được thêm vào sẽ xuất hiện trên cùng một trang hay được chia thành một trang mới.
Ví dụ mã sau đây cho thấy cách nối tài liệu này sang tài liệu khác trong khi vẫn giữ cho nội dung không bị tách trên hai trang:
// 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"); |