Rastrear alterações em um documento
A funcionalidade de rastrear alterações, também conhecida como revisão, permite rastrear alterações no conteúdo e na formatação feitas por você ou por outros usuários. Este recurso de controle de alterações com Aspose.Words suporta alterações de controle em Microsoft Word. Com esta funcionalidade, você pode acessar revisões individuais em seu documento e aplicar propriedades diferentes a elas.
Quando você ativa o recurso de controle de alterações, todos os elementos inseridos, excluídos e modificados do documento serão destacados visualmente com informações sobre quem, quando e o que foi alterado. Os objetos que carregam as informações sobre o que foi alterado são chamados de “rastreamento de alterações”. Por exemplo, suponha que você queira revisar um documento e fazer alterações importantes – isso pode significar que você precisa fazer revisões. Além disso, pode ser necessário inserir comentários para discutir algumas das alterações. É aí que entra o rastreamento de alterações nos documentos.
Este artigo explica como gerenciar e rastrear alterações criadas por vários revisores no mesmo documento, bem como as propriedades para rastrear alterações.
O que é uma revisão
Antes de mergulhar nas revisões, vamos explicar o significado das revisões. Um Revision é uma alteração que ocorre em um nó de um documento, enquanto um grupo de revisões, representado pela classe RevisionGroup, é um grupo de revisões sequenciais que ocorrem em vários nós de um documento. Basicamente, a revisão é uma ferramenta para rastrear alterações.
As revisões são usadas no recurso de controle de alterações e no recurso de comparação de documentos, onde as revisões aparecem como resultado da comparação. Portanto, as revisões no recurso de rastreamento de alterações mostram quem e o que foi alterado.
Aspose.Words oferece suporte a diferentes tipos de revisão, bem como em Microsoft Word, como inserção, exclusão, FormatChange, StyleDefinitionChange e movimentação. Todos os tipos de revisão são representados com a enumeração RevisionType.
Iniciar e parar de monitorar alterações
A edição de um documento geralmente não conta como uma revisão até que você comece a rastreá-lo. Aspose.Words permite rastrear automaticamente todas as alterações em seu documento com etapas simples. Você pode iniciar facilmente o processo de rastreamento de alterações usando o método start_track_revisions. Se precisar interromper o processo de rastreamento de alterações para que quaisquer edições futuras não sejam consideradas revisões, você precisará usar o método stop_track_revisions.
Ao final do processo de rastreamento de alterações em seu documento, você poderá até mesmo aceitar todas as revisões ou rejeitá-las para reverter o documento à sua forma original. Isso pode ser conseguido usando o método accept_all_revisions ou reject_all. Além disso, você pode aceitar ou rejeitar cada revisão separadamente usando o método accept ou reject.
Todas as alterações serão rastreadas em uma iteração, desde o momento em que você inicia o processo até o momento em que o interrompe. A conexão entre diferentes iterações é representada no seguinte cenário: você conclui o processo de rastreamento, depois faz algumas alterações e começa a rastrear as alterações novamente. Neste cenário, todas as alterações que você não aceitou ou rejeitou serão exibidas novamente.
O exemplo de código a seguir mostra como trabalhar com o rastreamento de alterações:
# 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") |
O exemplo de código a seguir mostra como as revisões são geradas quando um nó é movido em um documento controlado:
# 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") |
Gerenciar e armazenar alterações como revisões
Com o recurso de rastreamento de alterações anterior, você pode entender quais alterações foram feitas em seu documento e quem as fez. Enquanto estiver usando o recurso track_revisions, você forçará o armazenamento de quaisquer alterações em seu documento como revisões.
Aspose.Words permite verificar se um documento possui revisão ou não através da propriedade has_revision. Se você não precisar rastrear automaticamente as alterações em seu documento por meio dos métodos start_track_revisions e stop_track_revisions, poderá usar a propriedade track_revisions para verificar se as alterações são rastreadas durante a edição de um documento em Microsoft Word e armazenadas como revisões.
O recurso track_revisions faz revisões em vez de alterações reais no DOM. Mas as próprias revisões são separadas. Por exemplo, se você excluir qualquer parágrafo, o Aspose.Words o tornará uma revisão, marcando-o como exclusão, em vez de excluí-lo.
Além disso, Aspose.Words permite verificar se um objeto foi inserido, excluído ou alterado de formatação usando as propriedades is_delete_revision, is_format_revision, is_insert_revision, is_move_from_revision e is_move_to_revision.
O exemplo de código a seguir mostra como aplicar diferentes propriedades com revisões:
# 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) |