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

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-Python-via-.NET
doc = aw.Document()
builder = aw.DocumentBuilder(doc)
builder.write("Some text is added.")
comment = aw.Comment(doc, "Awais Hafeez", "AH", datetime.today())
builder.current_paragraph.append_child(comment)
comment.paragraphs.add(aw.Paragraph(doc))
comment.first_paragraph.runs.add(aw.Run(doc, "Comment text."))
doc.save(docs_base.artifacts_dir + "WorkingWithComments.add_comments.docx")

В следующем примере кода показано, как добавить комментарий к абзацу, используя область текста и классы CommentRangeStart и CommentRangeEnd:

# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET
doc = aw.Document()
para1 = aw.Paragraph(doc)
run1 = aw.Run(doc, "Some ")
run2 = aw.Run(doc, "text ")
para1.append_child(run1)
para1.append_child(run2)
doc.first_section.body.append_child(para1)
para2 = aw.Paragraph(doc)
run3 = aw.Run(doc, "is ")
run4 = aw.Run(doc, "added ")
para2.append_child(run3)
para2.append_child(run4)
doc.first_section.body.append_child(para2)
comment = aw.Comment(doc, "Awais Hafeez", "AH", datetime.today())
comment.paragraphs.add(aw.Paragraph(doc))
comment.first_paragraph.runs.add(aw.Run(doc, "Comment text."))
commentRangeStart = aw.CommentRangeStart(doc, comment.id)
commentRangeEnd = aw.CommentRangeEnd(doc, comment.id)
run1.parent_node.insert_after(commentRangeStart, run1)
run3.parent_node.insert_after(commentRangeEnd, run3)
commentRangeEnd.parent_node.insert_after(comment, commentRangeEnd)
doc.save(docs_base.artifacts_dir + "WorkingWithComments.anchor_comment.doc")

Извлекать или удалять комментарии

Использование комментариев в документе Word (в дополнение к отслеживанию изменений) является обычной практикой при просмотре документов, особенно при наличии нескольких рецензентов. Могут возникнуть ситуации, когда единственное, что вам нужно от документа, - это комментарии. Допустим, вы хотите составить список результатов проверки, или, возможно, вы собрали всю полезную информацию из документа и просто хотите удалить ненужные комментарии. Возможно, вы захотите просмотреть или удалить комментарии конкретного рецензента.

В этом примере мы рассмотрим несколько простых методов как для сбора информации из комментариев в документе, так и для удаления комментариев из документа. В частности, мы рассмотрим, как:

  • Извлеките все комментарии из документа или только те, которые были сделаны конкретным автором.
  • Удалите все комментарии из документа или только от определенного автора.

Как извлечь или удалить комментарии

Код в этом примере на самом деле довольно прост, и все методы основаны на одном и том же подходе. Комментарий в документе Word представлен объектом Comment в объектной модели документа Aspose.Words. Чтобы собрать все комментарии в документе, используйте метод get_child_nodes с первым параметром, равным NodeType.COMMENT. Убедитесь, что для второго параметра метода get_child_nodes установлено значение true: это заставляет метод get_child_nodes рекурсивно выбирать из всех дочерних узлов, а не собирать только непосредственные дочерние узлы.

Чтобы проиллюстрировать, как извлекать и удалять комментарии из документа, мы выполним следующие шаги:

  1. Откройте документ Word с помощью класса Document
  2. Собрать все комментарии из документа в коллекцию
  3. Чтобы извлечь комментарии:
    1. Просматривайте коллекцию с помощью оператора foreach
    2. Извлеките и укажите имя автора, дату и время, а также текст всех комментариев
    3. Извлеките и укажите имя автора, дату и время, а также текст комментариев, написанных конкретным автором, в данном случае автором ks
  4. Чтобы удалить комментарии:
    1. Пройдитесь в обратном направлении по коллекции, используя оператор for
    2. Удалять комментарии
  5. Сохраните изменения

Как извлечь все комментарии

Метод get_child_nodes очень полезен, и вы можете использовать его каждый раз, когда вам нужно получить список узлов документа любого типа. Результирующая коллекция не создает немедленных накладных расходов, поскольку узлы выбираются в эту коллекцию только при перечислении элементов в ней или доступе к ним.

В следующем примере кода показано, как извлечь имя автора, дату и время, а также текст всех комментариев в документе:

# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET
@staticmethod
def extract_comments(doc) :
collectedComments = []
comments = doc.get_child_nodes(aw.NodeType.COMMENT, True)
for node in comments :
comment = node.as_comment()
collectedComments.append(comment.author + " " + comment.date_time.strftime("%Y-%m-%d %H:%M:%S") + " " + comment.to_string(aw.SaveFormat.TEXT))
return collectedComments

Как извлечь комментарии указанного автора

После того, как вы выбрали Comment узлов в коллекции, все, что вам нужно сделать, это извлечь необходимую информацию. В этом примере инициалы автора, дата, время и обычный текст комментария объединены в одну строку; вы могли бы сохранить их каким-либо другим способом.

Перегруженный метод, который извлекает комментарии от конкретного автора, почти такой же, он просто проверяет имя автора перед добавлением информации в массив.

В следующем примере кода показано, как извлечь имя автора, дату и время, а также текст комментариев указанного автора:

# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET
@staticmethod
def extract_comments_by_author(doc, authorName) :
collectedComments = []
comments = doc.get_child_nodes(aw.NodeType.COMMENT, True)
for node in comments :
comment = node.as_comment()
if (comment.author == authorName) :
collectedComments.append(comment.author + " " + comment.date_time.strftime("%Y-%m-%d %H:%M:%S") + " " + comment.to_string(aw.SaveFormat.TEXT))
return collectedComments

Как удалить комментарии

Если вы удаляете все комментарии, нет необходимости перемещаться по коллекции, удаляя комментарии один за другим; вы можете удалить их, вызвав команду clear в коллекции комментариев.

В следующем примере кода показано, как удалить все комментарии в документе:

# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET
@staticmethod
def remove_comments(doc) :
comments = doc.get_child_nodes(aw.NodeType.COMMENT, True)
comments.clear()

Когда вам нужно выборочно удалить комментарии, процесс становится более похожим на код, который мы использовали для извлечения комментариев.

В следующем примере кода показано, как удалить комментарии указанного автора:

# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET
@staticmethod
def remove_comments_by_author(doc, authorName) :
comments = doc.get_child_nodes(aw.NodeType.COMMENT, True)
# Look through all comments and remove those written by the authorName.
for i in range(comments.count, 0) :
print(i)
comment = comments[i].as_comment()
if (comment.author == authorName) :
comment.remove()

Главное, на что следует обратить внимание, - это использование оператора for. В отличие от простого извлечения, здесь вы хотите удалить комментарий. Подходящий прием - выполнить итерацию коллекции в обратном порядке от последнего Comment к первому. Причина этого в том, что если вы начнете с конца и будете двигаться в обратном направлении, индекс предыдущих элементов останется неизменным, и вы сможете вернуться к первому элементу в коллекции.

В следующем примере кода показаны методы извлечения и удаления комментариев:

# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET
doc = aw.Document(docs_base.my_dir + "Comments.docx")
# Extract the information about the comments of all the authors.
for comment in self.extract_comments(doc) :
print(comment)
# Remove comments by the "pm" author.
self.remove_comments_by_author(doc, "pm")
print("Comments from \"pm\" are removed!")
# Extract the information about the comments of the "ks" author.
for comment in self.extract_comments_by_author(doc, "ks") :
print(comment)
# Read the comment's reply and resolve them.
self.comment_resolved_and_replies(doc)
# Remove all comments.
self.remove_comments(doc)
print("All comments are removed!")
doc.save(docs_base.artifacts_dir + "WorkingWithComments.process_comments.docx")

Как удалить комментарий между CommentRangeStart и CommentRangeEnd

Используя Aspose.Words, вы также можете удалить комментарии между узлами CommentRangeStart и CommentRangeEnd.

В следующем примере кода показано, как удалить текст между CommentRangeStart и CommentRangeEnd:

# Open the document.
doc = aw.Document(docs_base.my_dir + "Comments.docx")

commentStart = doc.get_child(aw.NodeType.COMMENT_RANGE_START, 0, True).as_comment_range_start()
commentEnd = doc.get_child(aw.NodeType.COMMENT_RANGE_END, 0, True).as_comment_range_end()

currentNode = commentStart
isRemoving = True
while (currentNode != None and isRemoving) :
    if (currentNode.node_type == aw.NodeType.COMMENT_RANGE_END) :
        isRemoving = False

    nextNode = currentNode.next_pre_order(doc)
    currentNode.remove()
    currentNode = nextNode

# Save the document.
doc.save(docs_base.artifacts_dir + "WorkingWithComments.remove_region_text.docx")

Добавить или удалить ответ на комментарий

Метод add_reply добавляет ответ к этому комментарию. Пожалуйста, обратите внимание, что из-за существующих ограничений Microsoft Office в документе разрешен только 1 уровень ответов. При вызове этого метода для существующего комментария к ответу будет создано исключение типа InvalidOperationException.

Вы можете использовать метод remove_reply, чтобы удалить указанный ответ на этот комментарий.

В следующем примере кода показано, как добавить ответ к комментарию и удалить ответ на комментарий:

# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET
doc = aw.Document(docs_base.my_dir + "Comments.docx")
comment = doc.get_child(aw.NodeType.COMMENT, 0, True).as_comment()
comment.remove_reply(comment.replies[0])
comment.add_reply("John Doe", "JD", datetime(2017, 9, 25, 12, 15, 0), "New reply")
doc.save(docs_base.artifacts_dir + "WorkingWithComments.add_remove_comment_reply.docx")

Прочитайте ответ на комментарий

Свойство replies возвращает коллекцию объектов Comment, которые являются непосредственными дочерними элементами указанного комментария.

В следующем примере кода показано, как перебирать ответы на комментарии и разрешать их:

# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET
@staticmethod
def comment_resolved_and_replies(doc) :
comments = doc.get_child_nodes(aw.NodeType.COMMENT, True)
parentComment = comments[0].as_comment()
for child in parentComment.replies :
childComment = child.as_comment()
# Get comment parent and status.
print(childComment.ancestor.id)
print(childComment.done)
# And update comment Done mark.
childComment.done = True