比较文件

比较文档是一个识别两个文档之间的更改并将更改包含为修订的过程。 此过程比较任何两个文档,包括一个特定文档的版本,然后两个文档之间的更改将显示为第一个文档中的修订。

比较方法是通过在字符级别或在单词级别比较单词来实现的。 如果一个单词包含至少一个字符的变化,在结果中,差异将显示为整个单词的变化,而不是一个字符。 这个比较过程是法律和金融业的通常任务。

您可以使用Aspose.Words来比较文档并获取格式、页眉/页脚、表格等内容的更改,而不是手动搜索文档之间或不同版本之间的差异。

本文介绍如何比较文档以及如何指定高级比较属性。

限制和支持的文件格式

比较文档是一个非常复杂的功能。 内容组合的不同部分需要分析以识别所有差异。 这种复杂性的原因是因为Aspose.Words旨在获得与Microsoft Word比较算法相同的比较结果。

被比较的两个文档的一般限制是,在调用比较方法之前,它们不能有修订,因为Microsoft Word中存在此限制。

比较两个文档

当您比较文档时,后一个文档与前一个文档的差异显示为对前一个文档的修订。 修改文档时,运行compare方法后,每个编辑都会有自己的修订版本。

Aspose.Words允许您使用Compare方法识别文档差异-这与Microsoft Word文档比较功能类似。 它允许您检查文档或文档版本以查找差异和更改,包括格式修改,如字体更改,间距更改,单词和段落的添加。

作为比较的结果,文档可以被确定为相等或不相等。 术语"相等"文档意味着比较方法不能将更改表示为修订。 这意味着文档文本和文本格式都是相同的。 但文档之间可能存在其他差异。 例如,Microsoft Word仅支持样式的格式修订,不能表示样式插入/删除。 所以文档可以有一组不同的样式,Compare方法仍然不会产生任何修改。

下面的代码示例演示如何检查两个文档是否相等:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java
Document docA = new Document(dataDir + "DocumentA.doc");
Document docB = new Document(dataDir + "DocumentB.doc");
docA.compare(docB, "user", new Date());
if (docA.getRevisions().getCount() == 0)
System.out.println("Documents are equal");
else
System.out.println("Documents are not equal");

下面的代码示例演示如何简单地将Compare方法应用于两个文档:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java
// The source document doc1
Document doc1 = new Document();
DocumentBuilder builder = new DocumentBuilder(doc1);
builder.writeln("This is the original document.");
// The target document doc2
Document doc2 = new Document();
builder = new DocumentBuilder(doc2);
builder.writeln("This is the edited document.");
// If either document has a revision, an exception will be thrown
if (doc1.getRevisions().getCount() == 0 && doc2.getRevisions().getCount() == 0)
doc1.compare(doc2, "authorName", new Date());
// If doc1 and doc2 are different, doc1 now has some revisions after the comparison, which can now be viewed and processed
if (doc1.getRevisions().getCount() == 2)
System.out.println("Documents are equal");
for (Revision r : doc1.getRevisions())
{
System.out.println("Revision type: " + r.getRevisionType() + ", on a node of type " + r.getParentNode().getNodeType() + "");
System.out.println("\tChanged text: " + r.getParentNode().getText() + "");
}
// All the revisions in doc1 are differences between doc1 and doc2, so accepting them on doc1 transforms doc1 into doc2
doc1.getRevisions().acceptAll();
// doc1, when saved, now resembles doc2
doc1.save(dataDir + "Document.Compare.docx");
doc1 = new Document(dataDir + "Document.Compare.docx");
if (doc1.getRevisions().getCount() == 0)
System.out.println("Documents are equal");
if (doc2.getText().trim() == doc1.getText().trim())
System.out.println("Documents are equal");

指定高级比较选项

CompareOptions类有许多不同的属性,您可以在比较文档时应用这些属性。

例如,Aspose.Words允许您忽略在比较操作期间对原始文档中某些类型的对象所做的更改。 您可以为对象类型选择适当的属性,例如IgnoreHeadersAndFooters, IgnoreFormatting, IgnoreComments, 和其他人通过将它们设置为"真"。

此外,Aspose.Words还提供了Granularity属性,您可以使用该属性指定是按字符还是按单词跟踪更改。

另一个常见属性是选择在哪个文档中显示比较更改。 例如,Microsoft Word中的"比较文档对话框"具有"显示更改"选项–这也会影响比较结果。 Aspose.Words提供用于此目的的Target属性。

下面的代码示例演示如何设置高级比较属性:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java
// Create the original document
Document docOriginal = new Document();
DocumentBuilder builder = new DocumentBuilder(docOriginal);
// Insert paragraph text with an endnote
builder.writeln("Hello world! This is the first paragraph.");
builder.insertFootnote(FootnoteType.ENDNOTE, "Original endnote text.");
// Insert a table
builder.startTable();
builder.insertCell();
builder.write("Original cell 1 text");
builder.insertCell();
builder.write("Original cell 2 text");
builder.endTable();
// Insert a textbox
Shape textBox = builder.insertShape(ShapeType.TEXT_BOX, 150, 20);
builder.moveTo(textBox.getFirstParagraph());
builder.write("Original textbox contents");
// Insert a DATE field
builder.moveTo(docOriginal.getFirstSection().getBody().appendParagraph(""));
builder.insertField(" DATE ");
// Insert a comment
Comment newComment = new Comment(docOriginal, "John Doe", "J.D.", new Date());
newComment.setText("Original comment.");
builder.getCurrentParagraph().appendChild(newComment);
// Insert a header
builder.moveToHeaderFooter(HeaderFooterType.HEADER_PRIMARY);
builder.writeln("Original header contents.");
// Create a clone of our document, which we will edit and later compare to the original
Document docEdited = (Document)docOriginal.deepClone(true);
Paragraph firstParagraph = docEdited.getFirstSection().getBody().getFirstParagraph();
// Change the formatting of the first paragraph, change casing of original characters and add text
firstParagraph.getRuns().get(0).setText("hello world! this is the first paragraph, after editing.");
firstParagraph.getParagraphFormat().setStyle(docEdited.getStyles().get(StyleIdentifier.HEADING_1));
// Edit the footnote
Footnote footnote = (Footnote)docEdited.getChild(NodeType.FOOTNOTE, 0, true);
footnote.getFirstParagraph().getRuns().get(1).setText("Edited endnote text.");
// Edit the table
Table table = (Table)docEdited.getChild(NodeType.TABLE, 0, true);
table.getFirstRow().getCells().get(1).getFirstParagraph().getRuns().get(0).setText("Edited Cell 2 contents");
// Edit the textbox
textBox = (Shape)docEdited.getChild(NodeType.SHAPE, 0, true);
textBox.getFirstParagraph().getRuns().get(0).setText("Edited textbox contents");
// Edit the DATE field
FieldDate fieldDate = (FieldDate)docEdited.getRange().getFields().get(0);
fieldDate.setUseLunarCalendar(true);
// Edit the comment
Comment comment = (Comment)docEdited.getChild(NodeType.COMMENT, 0, true);
comment.getFirstParagraph().getRuns().get(0).setText("Edited comment.");
// Edit the header
docEdited.getFirstSection().getHeadersFooters().getByHeaderFooterType(HeaderFooterType.HEADER_PRIMARY).getFirstParagraph().getRuns().get(0).setText("Edited header contents.");
// Apply different comparing options
CompareOptions compareOptions = new CompareOptions();
compareOptions.setIgnoreFormatting(false);
compareOptions.setIgnoreCaseChanges(false);
compareOptions.setIgnoreComments(false);
compareOptions.setIgnoreTables(false);
compareOptions.setIgnoreFields(false);
compareOptions.setIgnoreFootnotes(false);
compareOptions.setIgnoreTextboxes(false);
compareOptions.setIgnoreHeadersAndFooters(false);
compareOptions.setTarget(ComparisonTargetType.NEW);
// compare both documents
docOriginal.compare(docEdited, "John Doe", new Date(), compareOptions);
docOriginal.save(dataDir + "Document.CompareOptions.docx");