处理意见

Aspose.Words允许用户使用注释-Aspose.Words中的文档中的注释由Comment类表示。 还可以使用CommentRangeStartCommentRangeEnd类指定应与注释关联的文本区域。

添加评论

Aspose.Words允许您以多种方式添加注释:

  1. 使用Comment
  2. 使用CommentRangeStartCommentRangeEnd

下面的代码示例演示如何使用Comment类向段落添加注释:

For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
// The path to the documents directory.
System::String outputDataDir = GetOutputDataDir_WorkingWithComments();
System::SharedPtr<Document> doc = System::MakeObject<Document>();
System::SharedPtr<DocumentBuilder> builder = System::MakeObject<DocumentBuilder>(doc);
builder->Write(u"Some text is added.");
System::SharedPtr<Comment> comment = System::MakeObject<Comment>(doc, u"Awais Hafeez", u"AH", System::DateTime::get_Today());
builder->get_CurrentParagraph()->AppendChild(comment);
comment->get_Paragraphs()->Add(System::MakeObject<Paragraph>(doc));
comment->get_FirstParagraph()->get_Runs()->Add(System::MakeObject<Run>(doc, u"Comment text."));
System::String outputPath = outputDataDir + u"AddComments.doc";
// Save the document.
doc->Save(outputPath);

下面的代码示例演示如何使用文本区域以及CommentRangeStartCommentRangeEnd类向段落添加注释:

For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
// The path to the documents directory.
System::String outputDataDir = GetOutputDataDir_WorkingWithComments();
System::SharedPtr<Document> doc = System::MakeObject<Document>();
System::SharedPtr<Paragraph> para1 = System::MakeObject<Paragraph>(doc);
System::SharedPtr<Run> run1 = System::MakeObject<Run>(doc, u"Some ");
System::SharedPtr<Run> run2 = System::MakeObject<Run>(doc, u"text ");
para1->AppendChild(run1);
para1->AppendChild(run2);
doc->get_FirstSection()->get_Body()->AppendChild(para1);
System::SharedPtr<Paragraph> para2 = System::MakeObject<Paragraph>(doc);
System::SharedPtr<Run> run3 = System::MakeObject<Run>(doc, u"is ");
System::SharedPtr<Run> run4 = System::MakeObject<Run>(doc, u"added ");
para2->AppendChild(run3);
para2->AppendChild(run4);
doc->get_FirstSection()->get_Body()->AppendChild(para2);
System::SharedPtr<Comment> comment = System::MakeObject<Comment>(doc, u"Awais Hafeez", u"AH", System::DateTime::get_Today());
comment->get_Paragraphs()->Add(System::MakeObject<Paragraph>(doc));
comment->get_FirstParagraph()->get_Runs()->Add(System::MakeObject<Run>(doc, u"Comment text."));
System::SharedPtr<CommentRangeStart> commentRangeStart = System::MakeObject<CommentRangeStart>(doc, comment->get_Id());
System::SharedPtr<CommentRangeEnd> commentRangeEnd = System::MakeObject<CommentRangeEnd>(doc, comment->get_Id());
run1->get_ParentNode()->InsertAfter(commentRangeStart, run1);
run3->get_ParentNode()->InsertAfter(commentRangeEnd, run3);
commentRangeEnd->get_ParentNode()->InsertAfter(comment, commentRangeEnd);
System::String outputPath = outputDataDir + u"AnchorComment.doc";
// Save the document.
doc->Save(outputPath);

提取或删除注释

在Word文档中使用注释(除了跟踪更改之外)是审阅文档时的常见做法,特别是当有多个审阅者时。 在某些情况下,您需要从文档中获得的唯一内容是注释。 假设您想生成一个审查结果列表,或者您已经从文档中收集了所有有用的信息,并且您只想删除不必要的评论。 您可能希望查看或删除特定审阅者的注释。

在本示例中,我们将介绍一些简单的方法,既可以从文档中的注释中收集信息,也可以从文档中删除注释。 具体来说,我们将介绍如何:

  • 从文档中提取所有注释或仅提取特定作者的注释。
  • 从文档中或仅从特定作者中删除所有注释。

如何提取或删除注释

此示例中的代码实际上非常简单,所有方法都基于相同的方法。 Word文档中的注释由Aspose.Words文档对象模型中的Comment对象表示。 要收集文档中的所有注释,请使用第一个参数设置为NodeType.CommentGetChildNodes方法。 确保GetChildNodes方法的第二个参数设置为true:这会强制GetChildNodes递归地从所有子节点中进行选择,而不是只收集直接子节点。

为了说明如何从文档中提取和删除注释,我们将执行以下步骤:

  1. 使用Document类打开Word文档
  2. 将文档中的所有注释获取到集合中
  3. 提取评论:
    1. 使用foreach运算符浏览集合
    2. 提取并列出所有评论的作者姓名,日期和时间以及文本
    3. 提取并列出作者姓名,日期和时间以及特定作者撰写的评论文本,在这种情况下,作者’ks'
  4. 删除注释:
    1. 使用for the operator向后遍历集合
    2. 删除评论
  5. 保存更改

如何提取所有评论

GetChildNodes方法非常有用,您可以在每次需要获取任何类型的文档节点列表时使用它。 生成的集合不会立即产生开销,因为只有在枚举或访问其中的项时,才会将节点选择到此集合中。

下面的代码示例演示如何提取文档中所有注释的作者姓名、日期和时间以及文本:

For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
std::vector<System::String> ExtractComments(const System::SharedPtr<Document>& doc)
{
std::vector<System::String> collectedComments;
// Collect all comments in the document
System::SharedPtr<NodeCollection> comments = doc->GetChildNodes(NodeType::Comment, true);
// Look through all comments and gather information about them.
for (System::SharedPtr<Comment> comment : System::IterateOver<System::SharedPtr<Comment>>(comments))
{
collectedComments.push_back(comment->get_Author() + u" " + comment->get_DateTime() + u" " + System::StaticCast<Node>(comment)->ToString(SaveFormat::Text));
}
return collectedComments;
}

如何提取指定作者的评论

在将注释节点选择到集合中后,您所要做的就是提取所需的信息。 在此示例中,作者姓名缩写、日期、时间和注释的纯文本组合成一个字符串;您可以选择以其他方式存储它。

从特定作者提取注释的重载方法几乎相同,它只是在将信息添加到数组之前检查作者的姓名。

下面的代码示例演示如何提取指定作者的作者姓名、日期和时间以及注释的文本:

For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
std::vector<System::String> ExtractComments(const System::SharedPtr<Document>& doc, const System::String& authorName)
{
std::vector<System::String> collectedComments;
// Collect all comments in the document
System::SharedPtr<NodeCollection> comments = doc->GetChildNodes(NodeType::Comment, true);
// Look through all comments and gather information about those written by the authorName author.
for (System::SharedPtr<Comment> comment : System::IterateOver<System::SharedPtr<Comment>>(comments))
{
if (comment->get_Author() == authorName)
{
collectedComments.push_back(comment->get_Author() + u" " + comment->get_DateTime() + u" " + System::StaticCast<Node>(comment)->ToString(SaveFormat::Text));
}
}
return collectedComments;
}

如何删除评论

如果要删除所有注释,则无需逐个删除注释;您可以通过在comments集合上调用NodeCollection.Clear来删除它们。

下面的代码示例演示如何删除文档中的所有注释:

For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
void RemoveComments(const System::SharedPtr<Document>& doc)
{
// Collect all comments in the document
System::SharedPtr<NodeCollection> comments = doc->GetChildNodes(NodeType::Comment, true);
// Remove all comments.
comments->Clear();
}

当您需要有选择地删除注释时,该过程变得更加类似于我们用于注释提取的代码。

下面的代码示例演示如何删除指定作者的注释:

For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
void RemoveComments(const System::SharedPtr<Document>& doc, const System::String& authorName)
{
// Collect all comments in the document
System::SharedPtr<NodeCollection> comments = doc->GetChildNodes(NodeType::Comment, true);
// Look through all comments and remove those written by the authorName author.
for (int32_t i = comments->get_Count() - 1; i >= 0; i--)
{
System::SharedPtr<Comment> comment = System::DynamicCast<Comment>(comments->idx_get(i));
if (comment->get_Author() == authorName)
{
comment->Remove();
}
}
}

这里要强调的要点是使用for运算符。 与简单的提取不同,在这里您要删除注释。 一个合适的技巧是将集合从最后一个注释向后迭代到第一个注释。 这样做的原因如果您从末尾开始并向后移动,则前面项目的索引保持不变,并且您可以工作回到集合中的第一个项目。

下面的代码示例演示注释提取和删除的方法:

For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
// The path to the documents directories.
System::String inputDataDir = GetInputDataDir_WorkingWithComments();
System::String outputDataDir = GetOutputDataDir_WorkingWithComments();
// Open the document.
System::SharedPtr<Document> doc = System::MakeObject<Document>(inputDataDir + u"TestFile.doc");
// Extract the information about the comments of all the authors.
for (System::String const &comment : ExtractComments(doc))
{
std::cout << comment.ToUtf8String();
}
// Remove comments by the "pm" author.
RemoveComments(doc, u"pm");
std::cout << "Comments from \"pm\" are removed!" << std::endl;
// Extract the information about the comments of the "ks" author.
for (System::String const &comment: ExtractComments(doc, u"ks"))
{
std::cout << comment.ToUtf8String();
}
//Read the comment's reply and resolve them.
CommentResolvedandReplies(doc);
// Remove all comments.
RemoveComments(doc);
std::cout << "All comments are removed!" << std::endl;
System::String outputPath = outputDataDir + u"ProcessComments.doc";
// Save the document.
doc->Save(outputPath);

如何删除CommentRangeStart和CommentRangeEnd之间的注释

使用Aspose.Words还可以删除CommentRangeStartCommentRangeEnd节点之间的注释。

下面的代码示例演示如何删除CommentRangeStartCommentRangeEnd之间的文本:

For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
// The path to the documents directories.
System::String inputDataDir = GetInputDataDir_WorkingWithComments();
System::String outputDataDir = GetOutputDataDir_WorkingWithComments();
// Open the document.
System::SharedPtr<Document> doc = System::MakeObject<Document>(inputDataDir + u"TestFile.doc");
System::SharedPtr<CommentRangeStart> commentStart = System::DynamicCast<CommentRangeStart>(doc->GetChild(NodeType::CommentRangeStart, 0, true));
System::SharedPtr<CommentRangeEnd> commentEnd = System::DynamicCast<CommentRangeEnd>(doc->GetChild(NodeType::CommentRangeEnd, 0, true));
System::SharedPtr<Node> currentNode = commentStart;
bool isRemoving = true;
while (currentNode != nullptr && isRemoving)
{
if (currentNode->get_NodeType() == NodeType::CommentRangeEnd)
{
isRemoving = false;
}
System::SharedPtr<Node> nextNode = currentNode->NextPreOrder(doc);
currentNode->Remove();
currentNode = nextNode;
}
System::String outputPath = outputDataDir + u"RemoveRegionText.doc";
// Save the document.
doc->Save(outputPath);

添加和删除评论的回复

AddReply方法将回复添加到此注释。 请注意,由于现有的Microsoft Office限制,文档中仅允许1级别的回复。 如果对现有回复注释调用此方法,则会引发InvalidOperationException类型的异常。

您可以使用RemoveReply方法删除对此注释的指定回复。

下面的代码示例演示如何向注释添加回复并删除注释的回复:

For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
// The path to the documents directories.
System::String inputDataDir = GetInputDataDir_WorkingWithComments();
System::String outputDataDir = GetOutputDataDir_WorkingWithComments();
System::SharedPtr<Document> doc = System::MakeObject<Document>(inputDataDir + u"TestFile.doc");
System::SharedPtr<Comment> comment = System::DynamicCast<Comment>(doc->GetChild(NodeType::Comment, 0, true));
//Remove the reply
comment->RemoveReply(comment->get_Replies()->idx_get(0));
//Add a reply to comment
comment->AddReply(u"John Doe", u"JD", System::DateTime(2017, 9, 25, 12, 15, 0), u"New reply");
System::String outputPath = outputDataDir + u"CommentReply.doc";
// Save the document to disk.
doc->Save(outputPath);

阅读评论的回复

Replies属性返回Comment对象的集合,这些对象是指定注释的直接子项。

下面的代码示例演示如何遍历注释的回复并解析它们:

For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
void CommentResolvedandReplies(const System::SharedPtr<Document>& doc)
{
System::SharedPtr<NodeCollection> comments = doc->GetChildNodes(NodeType::Comment, true);
System::SharedPtr<Comment> parentComment = System::DynamicCast<Comment>(comments->idx_get(0));
for (System::SharedPtr<Comment> childComment : System::IterateOver<System::SharedPtr<Comment>>(parentComment->get_Replies()))
{
// Get comment parent and status.
std::cout << childComment->get_Ancestor()->get_Id() << std::endl << childComment->get_Done() << std::endl;
// And update comment Done mark.
childComment->set_Done(true);
}
}