Отслеживать изменения в документе
Функция отслеживания изменений, также известная как проверка, позволяет отслеживать изменения в содержании и форматировании, внесенные вами или другими пользователями. Эта функция отслеживания изменений с помощью Aspose.Words поддерживает отслеживание изменений с помощью Microsoft Word. С помощью этой функции вы можете получить доступ к отдельным редакциям вашего документа и применить к ним различные свойства.
Когда вы включите функцию отслеживания изменений, все вставленные, удаленные и измененные элементы документа будут визуально выделены с информацией о том, кем, когда и что было изменено. Объекты, которые содержат информацию о том, что было изменено, называются “отслеживаемыми изменениями”. Например, предположим, что вы хотите просмотреть документ и внести в него важные изменения – это может означать, что вам необходимо внести правки. Кроме того, вам может потребоваться вставить комментарии для обсуждения некоторых изменений. Вот где пригодится отслеживание изменений в документах.
В этой статье объясняется, как управлять изменениями, внесенными многими рецензентами в один и тот же документ, и отслеживать их, а также свойства для отслеживания изменений.
Что такое Пересмотр
Прежде чем перейти к рассмотрению изменений, давайте объясним значение изменений. Revision - это изменение, которое происходит в одном узле документа, в то время как группа изменений, представленная классом RevisionGroup, представляет собой группу последовательных изменений, которые происходят во многих узлах документа. По сути, revision - это инструмент для отслеживания изменений.
Изменения используются в функции отслеживания изменений и в функции сравнения документов, где изменения отображаются в результате сравнения. Таким образом, изменения в функции отслеживания изменений показывают, кем и что было изменено.
Aspose.Words поддерживает различные типы редакций, как и в Microsoft Word, такие как вставка, удаление, FormatChange, StyleDefinitionChange и перемещение. Все типы редакций представлены перечислением RevisionType.
Запуск и остановка отслеживания изменений
Редактирование документа обычно не считается доработкой, пока вы не начнете его отслеживать. Aspose.Words позволяет автоматически отслеживать все изменения в вашем документе с помощью простых шагов. Вы можете легко запустить процесс отслеживания изменений, используя метод start_track_revisions. Если вам нужно остановить процесс отслеживания изменений, чтобы любые будущие правки не считались ревизиями, вам нужно будет использовать метод stop_track_revisions.
В конце процесса отслеживания изменений в вашем документе у вас будет возможность даже принять все изменения или отклонить их, чтобы вернуть документ к его первоначальному виду. Этого можно достичь, используя метод accept_all_revisions или reject_all. Кроме того, вы можете принять или отклонить каждую редакцию отдельно, используя метод accept или reject.
Все изменения будут отслеживаться в течение одной итерации с момента запуска процесса до момента его остановки. Связь между различными итерациями представлена в следующем сценарии: вы завершаете процесс отслеживания, затем вносите некоторые изменения и снова начинаете отслеживать изменения. В этом случае все изменения, которые вы не приняли или отклонили, будут отображены снова.
В следующем примере кода показано, как работать с отслеживанием изменений:
# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET | |
doc = aw.Document() | |
body = doc.first_section.body | |
para = body.first_paragraph | |
# Add text to the first paragraph, then add two more paragraphs. | |
para.append_child(aw.Run(doc, "Paragraph 1. ")) | |
body.append_paragraph("Paragraph 2. ") | |
body.append_paragraph("Paragraph 3. ") | |
# We have three paragraphs, none of which registered as any type of revision | |
# If we add/remove any content in the document while tracking revisions, | |
# they will be displayed as such in the document and can be accepted/rejected. | |
doc.start_track_revisions("John Doe", datetime.today()) | |
# This paragraph is a revision and will have the according "IsInsertRevision" flag set. | |
para = body.append_paragraph("Paragraph 4. ") | |
self.assertTrue(para.is_insert_revision) | |
# Get the document's paragraph collection and remove a paragraph. | |
paragraphs = body.paragraphs | |
self.assertEqual(4, paragraphs.count) | |
para = paragraphs[2] | |
para.remove() | |
# Since we are tracking revisions, the paragraph still exists in the document, will have the "IsDeleteRevision" set | |
# and will be displayed as a revision in Microsoft Word, until we accept or reject all revisions. | |
self.assertEqual(4, paragraphs.count) | |
self.assertTrue(para.is_delete_revision) | |
# The delete revision paragraph is removed once we accept changes. | |
doc.accept_all_revisions() | |
self.assertEqual(3, paragraphs.count) | |
# Stopping the tracking of revisions makes this text appear as normal text. | |
# Revisions are not counted when the document is changed. | |
doc.stop_track_revisions() | |
# Save the document. | |
doc.save(docs_base.artifacts_dir + "WorkingWithRevisions.accept_revisions.docx") |
В следующем примере кода показано, как генерируются изменения при перемещении узла в отслеживаемом документе:
# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET | |
doc = aw.Document() | |
builder = aw.DocumentBuilder(doc) | |
builder.writeln("Paragraph 1") | |
builder.writeln("Paragraph 2") | |
builder.writeln("Paragraph 3") | |
builder.writeln("Paragraph 4") | |
builder.writeln("Paragraph 5") | |
builder.writeln("Paragraph 6") | |
body = doc.first_section.body | |
print(f"Paragraph count: {body.paragraphs.count}") | |
# Start tracking revisions. | |
doc.start_track_revisions("Author", datetime(2020, 12, 23, 14, 0, 0)) | |
# Generate revisions when moving a node from one location to another. | |
node = body.paragraphs[3] | |
endNode = body.paragraphs[5].next_sibling | |
referenceNode = body.paragraphs[0] | |
while (node != endNode) : | |
nextNode = node.next_sibling | |
body.insert_before(node, referenceNode) | |
node = nextNode | |
# Stop the process of tracking revisions. | |
doc.stop_track_revisions() | |
# There are 3 additional paragraphs in the move-from range. | |
print("Paragraph count: 0", body.paragraphs.count) | |
doc.save(docs_base.artifacts_dir + "WorkingWithRevisions.move_node_in_tracked_document.docx") |
Управление изменениями и их хранение в виде ревизий
С помощью функции отслеживания предыдущих изменений вы можете понять, какие изменения были внесены в ваш документ и кто внес эти изменения. В то время как с помощью функции track_revisions вы принудительно сохраняете любые изменения в вашем документе в виде ревизий.
Aspose.Words позволяет проверить, есть ли в документе редакция или нет, используя свойство has_revision. Если вам не нужно автоматически отслеживать изменения в вашем документе с помощью методов start_track_revisions и stop_track_revisions, вы можете использовать свойство track_revisions, чтобы проверить, отслеживаются ли изменения при редактировании документа в Microsoft Word и сохраняются ли они в виде изменений.
Функция track_revisions вносит правки вместо реальных изменений DOM. Но сами правки являются отдельными. Например, если вы удаляете какой-либо абзац, Aspose.Words внесите его в качестве правки, пометив как удаленный, вместо того, чтобы удалять его.
Кроме того, Aspose.Words позволяет проверить, был ли объект вставлен, удален или изменено форматирование, используя свойства is_delete_revision, is_format_revision, is_insert_revision, is_move_from_revision, и is_move_to_revision.
В следующем примере кода показано, как применять различные свойства с изменениями:
# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET | |
doc = aw.Document() | |
# Insert an inline shape without tracking revisions. | |
self.assertFalse(doc.track_revisions) | |
shape = aw.drawing.Shape(doc, aw.drawing.ShapeType.CUBE) | |
shape.wrap_type = aw.drawing.WrapType.INLINE | |
shape.width = 100 | |
shape.height = 100 | |
doc.first_section.body.first_paragraph.append_child(shape) | |
# Start tracking revisions and then insert another shape. | |
doc.start_track_revisions("John Doe") | |
shape = aw.drawing.Shape(doc, aw.drawing.ShapeType.SUN) | |
shape.wrap_type = aw.drawing.WrapType.INLINE | |
shape.width = 100.0 | |
shape.height = 100.0 | |
doc.first_section.body.first_paragraph.append_child(shape) | |
# Get the document's shape collection which includes just the two shapes we added. | |
shapes = doc.get_child_nodes(aw.NodeType.SHAPE, True) | |
self.assertEqual(2, shapes.count) | |
# Remove the first shape. | |
shape0 = shapes[0].as_shape() | |
shape0.remove() | |
# Because we removed that shape while changes were being tracked, the shape counts as a delete revision. | |
self.assertEqual(aw.drawing.ShapeType.CUBE, shape0.shape_type) | |
self.assertTrue(shape0.is_delete_revision) | |
# And we inserted another shape while tracking changes, so that shape will count as an insert revision. | |
shape1 = shapes[1].as_shape() | |
self.assertEqual(aw.drawing.ShapeType.SUN, shape1.shape_type) | |
self.assertTrue(shape1.is_insert_revision) | |
# The document has one shape that was moved, but shape move revisions will have two instances of that shape. | |
# One will be the shape at its arrival destination and the other will be the shape at its original location. | |
doc = aw.Document(docs_base.my_dir + "Revision shape.docx") | |
shapes = doc.get_child_nodes(aw.NodeType.SHAPE, True) | |
self.assertEqual(2, shapes.count) | |
# This is the move to revision, also the shape at its arrival destination. | |
shape0 = shapes[0].as_shape() | |
self.assertFalse(shape0.is_move_from_revision) | |
self.assertTrue(shape0.is_move_to_revision) | |
# This is the move from revision, which is the shape at its original location. | |
shape1 = shapes[1].as_shape() | |
self.assertTrue(shape1.is_move_from_revision) | |
self.assertFalse(shape1.is_move_to_revision) |