跟踪文档中的更改
跟踪更改(也称为审阅)的功能允许您跟踪您或其他用户对内容和格式所做的更改。 此带有Aspose.Words的跟踪更改功能支持Microsoft Word中的跟踪更改。 使用此功能,您可以访问文档中的各个修订版并对其应用不同的属性。
启用"跟踪更改"功能后,文档的所有插入、删除和修改元素都将以可视化方式突出显示,其中包含有关更改对象、更改时间和更改内容的信息。 携带有关更改内容的信息的对象称为"跟踪更改"。 例如,假设您要查看文档并进行重要更改–这可能意味着您需要进行修订。 此外,您可能需要插入注释来讨论一些更改。 这就是跟踪文档更改的作用所在。
本文介绍如何管理和跟踪多个审阅者在同一文档上创建的更改,以及跟踪更改的属性。
什么是修订
在深入研究修订之前,让我们解释修订的含义。 revision是在文档的一个节点中发生的更改,而由RevisionGroup类表示的修订组是在文档的许多节点中发生的一组顺序修订。 修订是跟踪更改的工具。
修订在跟踪更改功能和比较文档功能中使用,其中修订显示为比较的结果。 因此,“跟踪更改"功能中的修订会显示更改的对象和内容。
Aspose.Words支持不同的修订类型,以及在Microsoft Word中,如插入,删除,FormatChange,StyleDefinitionChange和移动。 所有修订类型都用RevisionType枚举表示。
启动和停止跟踪更改
编辑文档通常不算作修订,直到您开始跟踪它。 Aspose.Words允许您通过简单的步骤自动跟踪文档中的所有更改。 您可以使用StartTrackRevisions方法轻松启动跟踪更改的过程。 如果您需要停止跟踪更改的过程,以便将来的任何编辑都不被视为修订,则需要使用StopTrackRevisions方法。
StartTrackingRevisions
方法不会更改TrackRevisions属性的状态,也不会将其值用于修订跟踪。 此外,如果节点在跟踪文档内从一个位置移动到另一个位置,则将创建移动修订,包括从移动和移动到范围。
在文档中的跟踪更改过程结束时,您甚至可以接受所有修订或拒绝它们以将文档恢复为原始形式。 这可以通过使用AcceptAllRevisions或RejectAll方法来实现。 此外,您可以使用Accept或Reject方法分别接受或拒绝每个修订。
从您开始流程到停止流程的那一刻,所有更改都将被跟踪一次迭代。 不同迭代之间的联系表示为以下场景:您完成跟踪过程,然后进行一些更改,并重新开始跟踪更改。 在这种情况下,您未接受或拒绝的所有更改将再次显示。
AcceptAllRevisions
方法类似于Microsoft Word中的"接受所有更改"。
下面的代码示例演示如何处理跟踪更改:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java | |
Document doc = new Document(); | |
Body body = doc.getFirstSection().getBody(); | |
Paragraph para = body.getFirstParagraph(); | |
// Add text to the first paragraph, then add two more paragraphs. | |
para.appendChild(new Run(doc, "Paragraph 1. ")); | |
body.appendParagraph("Paragraph 2. "); | |
body.appendParagraph("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.startTrackRevisions("John Doe", new Date()); | |
// This paragraph is a revision and will have the according "IsInsertRevision" flag set. | |
para = body.appendParagraph("Paragraph 4. "); | |
if(para.isInsertRevision()) | |
System.out.println("isInsertRevision:" + para.isInsertRevision()); | |
// Get the document's paragraph collection and remove a paragraph. | |
ParagraphCollection paragraphs = body.getParagraphs(); | |
if(4 == paragraphs.getCount()) | |
System.out.println("count:" + paragraphs.getCount()); | |
para = paragraphs.get(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. | |
if(4 == paragraphs.getCount()) | |
System.out.println("count:" + paragraphs.getCount()); | |
if(para.isDeleteRevision()) | |
System.out.println("isDeleteRevision:" + para.isDeleteRevision()); | |
// The delete revision paragraph is removed once we accept changes. | |
doc.acceptAllRevisions(); | |
if(3 == paragraphs.getCount()) | |
System.out.println("count:" + paragraphs.getCount()); | |
// Stopping the tracking of revisions makes this text appear as normal text. | |
// Revisions are not counted when the document is changed. | |
doc.stopTrackRevisions(); | |
// Save the document. | |
doc.save(dataDir + "Document.Revisions.docx"); |
下面的代码示例演示在跟踪文档中移动节点时如何生成修订:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java | |
// Generate document contents. | |
Document doc = new Document(); | |
DocumentBuilder builder = new 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 body = doc.getFirstSection().getBody(); | |
System.out.println("Paragraph count:" + body.getParagraphs().getCount()); | |
// Start tracking revisions. | |
doc.startTrackRevisions("Author", new Date()); | |
// Generate revisions when moving a node from one location to another. | |
Node node = body.getParagraphs().get(3); | |
Node endNode = body.getParagraphs().get(5).getNextSibling(); | |
Node referenceNode = body.getParagraphs().get(0); | |
while (node != endNode) | |
{ | |
Node nextNode = node.getNextSibling(); | |
body.insertBefore(node, referenceNode); | |
node = nextNode; | |
} | |
// Stop the process of tracking revisions. | |
doc.stopTrackRevisions(); | |
// There are 3 additional paragraphs in the move-from range. | |
System.out.println("Paragraph count: " + body.getParagraphs().getCount()); | |
doc.save(dataDir + "out.docx"); |
将更改管理并存储为修订
使用以前的跟踪更改功能,您可以了解在文档中进行了哪些更改以及谁进行了这些更改。 使用TrackRevisions功能时,您强制将文档中的任何更改存储为修订版本。
Aspose.Words允许您使用HasRevision属性检查文档是否有修订。 如果您不需要通过StartTrackRevisions和StopTrackRevisions方法自动跟踪文档中的更改,那么您可以使用TrackRevisions
属性检查在Microsoft Word中编辑文档并存储为修订版本时是否跟踪了更改。
TrackRevisions
功能进行修订而不是真正的DOM更改。 但修订本身是分开的。 例如,如果删除任何段落,Aspose.Words将其作为修订,将其标记为删除,而不是删除它。
此外,Aspose.Words允许您使用IsDeleteRevision, IsFormatRevision, IsInsertRevision, IsMoveFromRevision, 和IsMoveToRevision属性。
TrackRevisions
属性之间没有连接。 此外,无论跟踪更改功能如何,您都可以接受/拒绝修订。
下面的代码示例演示如何使用修订应用不同的属性:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java | |
// Open a blank document. | |
Document doc = new Document(); | |
// Insert an inline shape without tracking revisions. | |
Shape shape = new Shape(doc, ShapeType.CUBE); | |
shape.setWrapType(WrapType.INLINE); | |
shape.setWidth(100.0); | |
shape.setHeight(100.0); | |
doc.getFirstSection().getBody().getFirstParagraph().appendChild(shape); | |
// Start tracking revisions and then insert another shape. | |
doc.startTrackRevisions("John Doe"); | |
shape = new Shape(doc, ShapeType.SUN); | |
shape.setWrapType(WrapType.INLINE); | |
shape.setWidth(100.0); | |
shape.setHeight(100.0); | |
doc.getFirstSection().getBody().getFirstParagraph().appendChild(shape); | |
// Get the document's shape collection which includes just the two shapes we added. | |
Node[] shapes = doc.getChildNodes(NodeType.SHAPE, true).toArray(); | |
if(2 == shapes.length) | |
System.out.println("Shapes Count:" + shapes.length); | |
// Remove the first shape. | |
shapes[0].remove(); | |
Shape sh = (Shape) shapes[0]; | |
// Because we removed that shape while changes were being tracked, the shape counts as a delete revision. | |
if(ShapeType.CUBE == sh.getShapeType()) | |
System.out.println("Shape is CUBE"); | |
if(sh.isDeleteRevision()) | |
System.out.println("isDeleteRevision:" + sh.isDeleteRevision()); | |
// And we inserted another shape while tracking changes, so that shape will count as an insert revision. | |
sh = (Shape) shapes[1]; | |
if(ShapeType.SUN == sh.getShapeType()) | |
System.out.println("Shape is SUN"); | |
if(sh.isInsertRevision()) | |
System.out.println("IsInsertRevision:" + sh.isInsertRevision()); | |
// 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 = new Document(dataDir + "Revision shape.docx"); | |
Node[] nc = doc.getChildNodes(NodeType.SHAPE, true).toArray(); | |
if(4 == nc.length) | |
System.out.println("Shapes Count:" + nc.length); | |
Shape mvr = (Shape) nc[0]; | |
// This is the move to revision, also the shape at its arrival destination. | |
if(mvr.isMoveFromRevision()) | |
System.out.println("isMoveFromRevision:" + mvr.isMoveFromRevision()); | |
if(mvr.isMoveToRevision()) | |
System.out.println("isMoveToRevision:" + mvr.isMoveToRevision()); | |
mvr = (Shape) nc[1]; | |
// This is the move from revision, which is the shape at its original location. | |
if(mvr.isMoveFromRevision()) | |
System.out.println("isMoveFromRevision:" + mvr.isMoveFromRevision()); | |
if(mvr.isMoveToRevision()) | |
System.out.println("isMoveToRevision:" + mvr.isMoveToRevision()); |