Сравнение документов

Сравнение документов - это процесс, который идентифицирует изменения между двумя документами и содержит изменения в виде ревизий. Этот процесс сравнивает любые два документа, включая версии одного конкретного документа, после чего изменения между обоими документами будут показаны как ревизии в первом документе.

Метод сравнения достигается путем сравнения слов на уровне символов или на уровне слова. Если слово содержит изменение хотя бы в одном символе, в результате разница будет отображаться как изменение всего слова, а не символа. Этот процесс сравнения является обычной задачей в юридической и финансовой отраслях.

Вместо ручного поиска различий между документами или их версиями, вы можете использовать Aspose.Words для сравнения документов и получения изменений в форматировании, верхнем и нижнем колонтитулах, таблицах и многом другом.

В этой статье объясняется, как сравнивать документы и как задать дополнительные свойства для сравнения.

Ограничения и поддерживаемые форматы файлов

Сравнение документов - очень сложная функция. Существуют различные комбинации элементов контента, которые необходимо проанализировать, чтобы выявить все различия. Причина этой сложности заключается в том, что алгоритм Aspose.Words стремится получить те же результаты сравнения, что и алгоритм Microsoft Word.

Общее ограничение для двух сравниваемых документов заключается в том, что они не должны иметь изменений перед вызовом метода compare, поскольку это ограничение существует в Microsoft Word.

Сравнение двух документов

Когда вы сравниваете документы, отличия последнего документа от первого отображаются в виде изменений по сравнению с первым. Когда вы изменяете документ, после выполнения метода сравнения каждая правка будет иметь свою собственную редакцию.

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, и другие, установив для них значение “true”.

Кроме того, 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");