Робота з коментарями

Aspose.Words дозволяє користувачам працювати з коментарями – коментарі в документі в Aspose.Words представлені класом Comment. Також використовуйте класи CommentRangeStart та CommentRangeEnd, щоб вказати область тексту, яка повинна бути пов’язана з коментарем.

Додати коментар

Aspose.Words дозволяє додавати коментарі кількома способами:

  1. Використання класу Comment
  2. Використання класів CommentRangeStart та CommentRangeEnd

Наступний приклад коду показує, як Додати коментар до абзацу за допомогою класу 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);

Наступний приклад коду показує, як Додати коментар до абзацу, використовуючи область тексту та класи CommentRangeStart та CommentRangeEnd:

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 представлений об’єктом Comment в об’єктній моделі документа Aspose.Words. Щоб зібрати всі коментарі в документі, використовуйте метод GetChildNodes з першим параметром NodeType.Comment. Переконайтеся, що для другого параметра методу GetChildNodes встановлено значення true: це змушує метод GetChildNodes рекурсивно вибирати з усіх дочірніх вузлів, а не збирати лише безпосередні дочірні вузли.

Щоб проілюструвати, як витягувати та видаляти коментарі з документа, ми виконаємо наступні кроки:

  1. Відкрийте документ Word за допомогою класу Document
  2. Зібрати всі коментарі з документа в колекцію
  3. Щоб витягти коментарі:
    1. Переглядайте колекцію за допомогою оператора foreach
    2. Витягніть та вкажіть ім’я автора, дату та час, а також текст усіх коментарів
    3. Витягніть і вкажіть ім’я автора, дату і час, а також текст коментарів, написаних конкретним автором, в даному випадку автором ks
  4. Щоб видалити коментарі:
    1. Пройдіться в зворотному порядку по колекції, використовуючи для оператора
    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;
}

Як видалити коментарі

Якщо ви видаляєте всі коментарі, немає необхідності переміщатися по колекції, видаляючи Коментарі один за одним; ви можете видалити їх, викликавши команду 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, ви також можете видалити коментарі між вузлами CommentRangeStart та CommentRangeEnd.

Наступний приклад коду показує, як видалити текст між CommentRangeStart та CommentRangeEnd:

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);
}
}