Web SDK

Комментарии

Комментарии позволяют пользователям оставлять в документах сообщения и ответы, упрощая общение и совместную работу в команде.

Режим плагинов

Установка

Shell
pnpm add @univerjs/thread-comment @univerjs/thread-comment-ui @univerjs/sheets-thread-comment @univerjs/sheets-thread-comment-ui

Использование

TypeScript
import { LocaleType, mergeLocales, Univer } from '@univerjs/core'import { UniverSheetsThreadCommentPlugin } from '@univerjs/sheets-thread-comment'import { UniverSheetsThreadCommentUIPlugin } from '@univerjs/sheets-thread-comment-ui'import SheetsThreadCommentUIEnUS from '@univerjs/sheets-thread-comment-ui/locale/en-US'import { UniverThreadCommentPlugin } from '@univerjs/thread-comment'import { UniverThreadCommentUIPlugin } from '@univerjs/thread-comment-ui'import ThreadCommentUIEnUS from '@univerjs/thread-comment-ui/locale/en-US'import '@univerjs/sheets-thread-comment-ui/lib/index.css'import '@univerjs/thread-comment-ui/lib/index.css'import '@univerjs/sheets-thread-comment/facade'const univer = new Univer({  locale: LocaleType.EN_US,  locales: {    [LocaleType.EN_US]: mergeLocales(      ThreadCommentUIEnUS,       SheetsThreadCommentUIEnUS,     ),  },})univer.registerPlugin(UniverThreadCommentPlugin)univer.registerPlugin(UniverThreadCommentUIPlugin)univer.registerPlugin(UniverSheetsThreadCommentPlugin)univer.registerPlugin(UniverSheetsThreadCommentUIPlugin)

Использование с функцией совместной работы

Если вы используете функцию совместной работы, настройте её следующим образом:

Shell
pnpm add @univerjs-pro/thread-comment-datasource
TypeScript
import { UniverThreadCommentDataSourcePlugin } from '@univerjs-pro/thread-comment-datasource'univer.registerPlugin(UniverThreadCommentDataSourcePlugin)

Поддержка мобильных устройств

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

ПакетНастольная регистрацияМобильная регистрация
@univerjs/sheets-thread-comment-uiUniverSheetsThreadCommentUIPluginUniverSheetsThreadCommentMobileUIPlugin
@univerjs/thread-comment-uiUniverThreadCommentUIPluginUniverThreadCommentMobileUIPlugin

Режим предустановок

Установка

Shell
pnpm add @univerjs/preset-sheets-thread-comment

Использование

TypeScript
import { UniverSheetsCorePreset } from '@univerjs/preset-sheets-core'import UniverPresetSheetsCoreEnUS from '@univerjs/preset-sheets-core/locales/en-US'import { UniverSheetsThreadCommentPreset } from '@univerjs/preset-sheets-thread-comment'import UniverPresetSheetsThreadCommentEnUS from '@univerjs/preset-sheets-thread-comment/locales/en-US'import { createUniver, LocaleType, mergeLocales } from '@univerjs/presets'import '@univerjs/preset-sheets-core/lib/index.css'import '@univerjs/preset-sheets-thread-comment/lib/index.css'const { univerAPI } = createUniver({  locale: LocaleType.EN_US,  locales: {    [LocaleType.EN_US]: mergeLocales(      UniverPresetSheetsCoreEnUS,      UniverPresetSheetsThreadCommentEnUS,     ),  },  presets: [    UniverSheetsCorePreset(),    UniverSheetsThreadCommentPreset(),   ],})

Facade API

Полные определения типов Facade API доступны в разделе FacadeAPI.

Импорт

Примечание о режиме плагинов

Вручную импортировать пакет Facade требуется только в режиме плагинов. В режиме предустановок соответствующий пакет Facade уже включён, поэтому дополнительный импорт не нужен.

TypeScript
import '@univerjs/sheets-thread-comment/facade'

Создание комментария к ячейке

Создать новый конструктор комментария можно с помощью univerAPI.newTheadComment(), который возвращает экземпляр FTheadCommentBuilder. Методы можно вызывать цепочкой, задавая различные свойства комментария.

Ниже перечислены некоторые методы FTheadCommentBuilder:

МетодОписание
setContentЗадаёт содержимое комментария
setPersonIdЗадаёт идентификатор автора комментария
setDateTimeЗадаёт дату и время комментария
setIdЗадаёт идентификатор комментария
setThreadIdЗадаёт идентификатор ветки комментариев
TypeScript
// Create a new commentconst richText = univerAPI.newRichText().insertText('hello univer')const commentBuilder = univerAPI.newTheadComment()  .setContent(richText)console.log(commentBuilder.content.toPlainText())// Add the comment to cell A1const fWorkbook = univerAPI.getActiveWorkbook()const fWorksheet = fWorkbook.getActiveSheet()const cell = fWorksheet.getRange('A1')const result = await cell.addCommentAsync(commentBuilder)

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

Получить комментарии можно следующими методами, возвращающими экземпляр FThreadComment. Затем комментарий можно обновить, удалить или пометить как решённый.

  • FWorkbook.getComments(): получить все комментарии в книге
  • FfWorksheet.getComments(): получить все комментарии на листе
  • FRange.getComment(): получить комментарий верхней левой ячейки диапазона
  • FRange.getComments(): получить все комментарии в диапазоне

Ниже перечислены некоторые методы FThreadComment:

МетодОписание
getIsRootПроверяет, является ли комментарий корневым
getCommentDataВозвращает данные комментария
getRepliesВозвращает список ответов на комментарий
getRangeВозвращает диапазон комментария
getRichTextВозвращает форматированное содержимое комментария
deleteAsyncУдаляет комментарий и ответы на него
updateAsyncОбновляет содержимое комментария
resolveAsyncПомечает комментарий как решённый
replyAsyncОтвечает на комментарий
TypeScript
// Get all comments in the workbookconst fWorkbook = univerAPI.getActiveWorkbook()fWorkbook.getComments()// Get all comments in the active worksheetconst fWorksheet = fWorkbook.getActiveSheet()fWorksheet.getComments()const fRange = fWorksheet.getRange('A1:B2')// Get the comment of cell A1fRange.getComment()// Get all comments in the range A1:B2fRange.getComments()

Очистка комментариев к ячейкам

  • FWorkbook.clearComments(): удалить все комментарии в книге
  • FWorksheet.clearComments(): удалить все комментарии на листе
  • FRange.clearCommentAsync(): удалить комментарий верхней левой ячейки диапазона
  • FRange.clearCommentsAsync(): удалить все комментарии в диапазоне
TypeScript
// Clear all comments in the workbookconst fWorkbook = univerAPI.getActiveWorkbook()await fWorkbook.clearComments()// Clear all comments in the active worksheetconst fWorksheet = fWorkbook.getActiveSheet()await fWorksheet.clearComments()const fRange = fWorksheet.getRange('A1:B2')// Clear the comment of cell A1await fRange.clearCommentAsync()// Clear all comments in the range A1:B2await fRange.clearCommentsAsync()

Получение списка ответов на комментарий

TypeScript
const fWorkbook = univerAPI.getActiveWorkbook()const fWorksheet = fWorkbook.getActiveSheet()// Get all comments in the worksheetconst comments = fWorksheet.getComments()comments.forEach((comment) => {  // If the comment is a root comment, get its replies  if (comment.getIsRoot()) {    const replies = comment.getReplies()    replies.forEach((reply) => {      console.log(reply.getCommentData())    })  }})

Обновление, удаление, завершение и ответы на комментарии

TypeScript
const fWorkbook = univerAPI.getActiveWorkbook()const fWorksheet = fWorkbook.getActiveSheet()// Create a new comment and add it to cell A1const richText = univerAPI.newRichText().insertText('hello univer')const commentBuilder = univerAPI.newTheadComment()  .setContent(richText)  .setId('mock-comment-id')const cell = fWorksheet.getRange('A1')await cell.addCommentAsync(commentBuilder)// Update the comment and reply after 3 secondssetTimeout(async () => {  // Get the comment by ID and update its content  const comment = fWorksheet.getCommentById('mock-comment-id')  const newRichText = univerAPI.newRichText().insertText('Hello Univer AI')  await comment.updateAsync(newRichText)  // Create a new reply comment and set its content  const replyText = univerAPI.newRichText().insertText('Hello Univer AI! GO! GO! GO!')  const reply = univerAPI.newTheadComment().setContent(replyText)  await comment.replyAsync(reply)}, 3000)// Resolve the comment and delete it after 6 secondssetTimeout(async () => {  const comment = fWorksheet.getCommentById('mock-comment-id')  await comment.resolveAsync()  await comment.deleteAsync()}, 6000)

Обработчики событий

Полные определения типов событий доступны в разделе Events.

Модуль комментариев предоставляет события для отслеживания добавления, обновления и удаления комментариев, а также изменения их статуса. Подписаться на любое событие можно с помощью univerAPI.addEvent().

События добавления комментариев

univerAPI.Event.CommentAdded: срабатывает после добавления комментария

TypeScript
const disposable = univerAPI.addEvent(univerAPI.Event.CommentAdded, (params) => {  const { comment, workbook, worksheet, row, col } = params})// Remove the event listener, use `disposable.dispose()`

univerAPI.Event.BeforeCommentAdd: срабатывает перед добавлением комментария

TypeScript
const disposable = univerAPI.addEvent(univerAPI.Event.BeforeCommentAdd, (params) => {  const { comment, workbook, worksheet, row, col } = params  // Cancel the comment addition operation  params.cancel = true})// Remove the event listener, use `disposable.dispose()`

События обновления комментариев

univerAPI.Event.CommentUpdated: срабатывает после обновления комментария

TypeScript
const disposable = univerAPI.addEvent(univerAPI.Event.CommentUpdated, (params) => {  const { comment, workbook, worksheet, row, col } = params})// Remove the event listener, use `disposable.dispose()`

univerAPI.Event.BeforeCommentUpdate: срабатывает перед обновлением комментария

TypeScript
const disposable = univerAPI.addEvent(univerAPI.Event.BeforeCommentUpdate, (params) => {  const { comment, workbook, worksheet, row, col, newContent } = params  // Cancel the comment update operation  params.cancel = true})// Remove the event listener, use `disposable.dispose()`

События удаления комментариев

univerAPI.Event.CommentDeleted: срабатывает после удаления комментария

TypeScript
const disposable = univerAPI.addEvent(univerAPI.Event.CommentDeleted, (params) => {  const { commentId, workbook, worksheet } = params})// Remove the event listener, use `disposable.dispose()`

univerAPI.Event.BeforeCommentDelete: срабатывает перед удалением комментария

TypeScript
const disposable = univerAPI.addEvent(univerAPI.Event.BeforeCommentDelete, (params) => {  const { comment, workbook, worksheet, row, col } = params  // Cancel the comment deletion operation  params.cancel = true})// Remove the event listener, use `disposable.dispose()`

События изменения статуса комментария

univerAPI.Event.CommentResolved: срабатывает после изменения статуса комментария

TypeScript
const disposable = univerAPI.addEvent(univerAPI.Event.CommentResolved, (params) => {  const { comment, row, col, resolved, workbook, worksheet } = params})// Remove the event listener, use `disposable.dispose()`

univerAPI.Event.BeforeCommentResolve: срабатывает перед изменением статуса комментария

TypeScript
const disposable = univerAPI.addEvent(univerAPI.Event.BeforeCommentResolve, (params) => {  const { comment, row, col, resolved, workbook, worksheet } = params  // Cancel the comment resolution operation  params.cancel = true})// Remove the event listener, use `disposable.dispose()`

Все события содержат следующие общие параметры:

  • workbook: текущий экземпляр книги
  • worksheet: текущий экземпляр листа
  • row: индекс строки комментария
  • col: индекс столбца комментария
  • comment: объект комментария (в событиях удаления передаётся только commentId)

Специальные параметры:

  • событие BeforeCommentUpdate содержит newContent: новое содержимое комментария (тип RichTextValue)
  • события CommentResolved и BeforeCommentResolve содержат resolved: статус комментария

Обработчики всех событий с префиксом Before могут вернуть params.cancel = true, чтобы отменить соответствующую операцию.

Общие операции

Импортируйте общую Facade комментариев и Facade продукта. Методы продукта создают стабильные привязки, общая API управляет ответами, изменениями, разрешением и удалением. getComments() читает локальное состояние. listCommentsAsync() синхронизирует уже известные обсуждения через настроенный источник, но не обнаруживает все обсуждения на сервере.

TypeScript
import '@univerjs/thread-comment/facade'const [thread] = univerAPI.getComments({ resolved: false })if (thread) {  await univerAPI.replyCommentAsync({    unitId: thread.unitId,    subUnitId: thread.subUnitId,    threadId: thread.threadId,    content: 'Reviewed.',  })}

Общие обсуждения

Интегрируйте Comment Service и Endpoint через Server SDK, затем после настройки совместного редактирования и лицензии зарегистрируйте UniverThreadCommentDataSourcePlugin из @univerjs-pro/thread-comment-datasource. Источник использует /universer-api/comment/unit/{unitId}/... и /universer-api/user/list: предоставьте эти маршруты в приложении. Сервер должен отдельно проверять права на чтение и запись комментариев, не полагаясь на право редактирования документа.

Насколько полезно это руководство?

© 2026 DreamNum Co., Ltd.