
Microsoft Word remains one of the most popular and widely used applications when it comes to creating and processing documents. When working with Word documents, there often arises a need to compare two or more documents to identify differences, revisions, or updates. To perform this task programmatically, you need a powerful solution that gives you accurate comparison results. So let’s explore how to compare two Word documents in a C++ application.
- C++ Library to Compare Word Documents
- Compare Two Word Documents in C++
- Advanced Comparison Options
- Get a Free License
C++ Library to Compare Word Documents
Aspose.Words for C++ is a feature-rich library that allows developers to create, modify, and manipulate Word documents in various ways. To get started, you’ll need to have the library installed and a C++ development environment set up. You can obtain Aspose.Words for C++ from the official website and follow the installation instructions provided in the documentation.
Compare Word Documents in C++
Aspose.Words for C++ simplifies the comparison process of Word documents. Simply load the documents to be compared, call Document->Compare method, and get the differences between the documents. Here are the steps you need to perform:
- Load the Word documents using the Document class.
- Call Document->Compare method to compare the documents.
- Save the document containing differences using Document->Save() method.
Document->Compare method mimics Microsoft Word’s compare feature and produces document differences as the number of edits and format revisions. The main idea is that if we reject all revisions then we get a document that is equal to the original document. On the contrary, if we accept all revisions then we get the final (comparison target) document.
The following code snippet shows how to compare two Word documents in C++.
For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C | |
// Load Word documents | |
System::SharedPtr<Document> docA = System::MakeObject<Document>(inputDataDir + u"TestFile.doc"); | |
System::SharedPtr<Document> docB = System::MakeObject<Document>(inputDataDir + u"TestFile - Copy.doc"); | |
// DocA now contains changes as revisions. | |
docA->Compare(docB, u"user", System::DateTime::get_Now()); | |
if (docA->get_Revisions()->get_Count() == 0) | |
{ | |
std::cout << "Documents are equal" << std::endl; | |
} | |
else | |
{ | |
std::cout << "Documents are not equal" << std::endl; | |
} |
Advanced Document Comparison Options
You can use some advanced features to customize document comparisons. The CompareOptions class offers various properties for this purpose.
For instance, within Aspose.Words, you can ignore changes made for specific types of objects in the document. You can achieve this by toggling relevant properties, like IgnoreHeadersAndFooters, IgnoreFormatting, IgnoreComments, among others, to “true.”
Additionally, you can use the Granularity property, which enables you to specify whether changes should be tracked on a character or word level. Furthermore, you can decide which version of the document should display the comparison changes. Much like the “Compare documents dialogue box” in Microsoft Word, you can influence the comparison results with Aspose.Words by using the Target property.
The following code snippet demonstrates how to use different options to customize Word document comparison in a C++ application.
For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C | |
// Create the original document | |
System::SharedPtr<Document> docOriginal = System::MakeObject<Document>(); | |
System::SharedPtr<DocumentBuilder> builder = System::MakeObject<DocumentBuilder>(docOriginal); | |
// Insert paragraph text with an endnote | |
builder->Writeln(u"Hello world! This is the first paragraph."); | |
builder->InsertFootnote(FootnoteType::Endnote, u"Original endnote text."); | |
// Insert a table | |
builder->StartTable(); | |
builder->InsertCell(); | |
builder->Write(u"Original cell 1 text"); | |
builder->InsertCell(); | |
builder->Write(u"Original cell 2 text"); | |
builder->EndTable(); | |
// Insert a textbox | |
System::SharedPtr<Shape> textBox = builder->InsertShape(ShapeType::TextBox, 150, 20); | |
builder->MoveTo(textBox->get_FirstParagraph()); | |
builder->Write(u"Original textbox contents"); | |
// Insert a DATE field | |
builder->MoveTo(docOriginal->get_FirstSection()->get_Body()->AppendParagraph(u"")); | |
builder->InsertField(u" DATE "); | |
// Insert a comment | |
auto newComment = System::MakeObject<Comment>(docOriginal, u"John Doe", u"J.D.", System::DateTime::get_Now()); | |
newComment->SetText(u"Original comment."); | |
builder->get_CurrentParagraph()->AppendChild(newComment); | |
// Insert a header | |
builder->MoveToHeaderFooter(Aspose::Words::HeaderFooterType::HeaderPrimary); | |
builder->Writeln(u"Original header contents."); | |
// Create a clone of our document, which we will edit and later compare to the original | |
auto docEdited = System::DynamicCast<Aspose::Words::Document>(System::StaticCast<Node>(docOriginal)->Clone(true)); | |
System::SharedPtr<Paragraph> firstParagraph = docEdited->get_FirstSection()->get_Body()->get_FirstParagraph(); | |
// Change the formatting of the first paragraph, change casing of original characters and add text | |
firstParagraph->get_Runs()->idx_get(0)->set_Text(u"hello world! this is the first paragraph, after editing."); | |
firstParagraph->get_ParagraphFormat()->set_Style(docEdited->get_Styles()->idx_get(Aspose::Words::StyleIdentifier::Heading1)); | |
// Edit the footnote | |
auto footnote = System::DynamicCast<Aspose::Words::Footnote>(docEdited->GetChild(Aspose::Words::NodeType::Footnote, 0, true)); | |
footnote->get_FirstParagraph()->get_Runs()->idx_get(1)->set_Text(u"Edited endnote text."); | |
// Edit the table | |
auto table = System::DynamicCast<Aspose::Words::Tables::Table>(docEdited->GetChild(Aspose::Words::NodeType::Table, 0, true)); | |
table->get_FirstRow()->get_Cells()->idx_get(1)->get_FirstParagraph()->get_Runs()->idx_get(0)->set_Text(u"Edited Cell 2 contents"); | |
// Edit the textbox | |
textBox = System::DynamicCast<Aspose::Words::Drawing::Shape>(docEdited->GetChild(Aspose::Words::NodeType::Shape, 0, true)); | |
textBox->get_FirstParagraph()->get_Runs()->idx_get(0)->set_Text(u"Edited textbox contents"); | |
// Edit the DATE field | |
auto fieldDate = System::DynamicCast<Aspose::Words::Fields::FieldDate>(docEdited->get_Range()->get_Fields()->idx_get(0)); | |
fieldDate->set_UseLunarCalendar(true); | |
// Edit the comment | |
auto comment = System::DynamicCast<Aspose::Words::Comment>(docEdited->GetChild(Aspose::Words::NodeType::Comment, 0, true)); | |
comment->get_FirstParagraph()->get_Runs()->idx_get(0)->set_Text(u"Edited comment."); | |
// Edit the header | |
docEdited->get_FirstSection()->get_HeadersFooters()->idx_get(Aspose::Words::HeaderFooterType::HeaderPrimary)->get_FirstParagraph()->get_Runs()->idx_get(0)->set_Text(u"Edited header contents."); | |
// When we compare documents, the differences of the latter document from the former show up as revisions to the former | |
// Each edit that we've made above will have its own revision, after we run the Compare method | |
// We can compare with a CompareOptions object, which can suppress changes done to certain types of objects within the original document | |
// from registering as revisions after the comparison by setting some of these members to "true" | |
auto compareOptions = System::MakeObject<Aspose::Words::CompareOptions>(); | |
compareOptions->set_IgnoreFormatting(false); | |
compareOptions->set_IgnoreCaseChanges(false); | |
compareOptions->set_IgnoreComments(false); | |
compareOptions->set_IgnoreTables(false); | |
compareOptions->set_IgnoreFields(false); | |
compareOptions->set_IgnoreFootnotes(false); | |
compareOptions->set_IgnoreTextboxes(false); | |
compareOptions->set_IgnoreHeadersAndFooters(false); | |
compareOptions->set_Target(Aspose::Words::ComparisonTargetType::New); | |
// Compare documents | |
docOriginal->Compare(docEdited, u"John Doe", System::DateTime::get_Now(), compareOptions); | |
docOriginal->Save(inputDataDir + u"Document.CompareOptions.docx"); |
Get a Free License
You can get a free temporary license and use the C++ word processing library without evaluation limitations.
Useful Links
The resources, you may need to accomplish your tasks:
- Aspose.Words for C++ Online Documentation - up-to-date documentation containing Programmer’s Guide, Knowledge Base and much more.
- Aspose.Words for C++ Product Page
- Install Aspose.Words for C++ NuGet Package
- Aspose.Words for C++ API Reference Guide - detailing the publicly exposed classes, methods, properties, constants & interfaces.
- Download Examples at GitHub Repository - we have published our code examples on the social coding website GitHub.com. Anyone could explore the code examples for learning purposes.
Conclusion
Comparing Word documents in C++ is a common requirement for many document-processing applications. Aspose.Words for C++ simplifies this task by providing a powerful library that allows you to programmatically compare documents, track changes, and generate comparison documents. This is especially valuable for businesses and developers who need to manage document revisions and collaborate on content.
In this blog post, we’ve explored the process of comparing Word documents using C++. By following the steps outlined above, you can easily integrate this functionality into your C++ applications and streamline the document comparison process with advanced features. You may ask your questions or post your queries about the library on our forum.