Диапазоны, выделения и ячейки
Перейдите к разделу по своей задаче. Базовые операции, расширенные примеры, настройки и устранение проблем остаются на этой странице; полные контракты API поддерживаются в Reference.
- Диапазон
- Выделение
- Расширенные операции с диапазонами
- Навигация на границах листа
- События и редактирование ячеек
- Устранение проблем редактирования
Диапазон
Диапазон — это прямоугольная область на листе, заданная начальной строкой, начальным столбцом, высотой и шириной либо конечной строкой и конечным столбцом.
Большинство операций с электронной таблицей можно выполнять через Range API: задавать и получать значения, задавать и получать стили и т. д.
Полное описание Facade API для диапазонов см. в разделе FRange FacadeAPI.
Создание диапазона
Чтобы получить диапазон, необходимо знать начальную строку, начальный столбец, высоту и ширину.
const fWorkbook = univerAPI.getActiveWorkbook()const fWorksheet = fWorkbook.getActiveSheet()// Create a range of A1 cell:const fRange = fWorksheet.getRange(0, 0)console.log(fRange, fRange.getA1Notation())// Creates a range of A1:B2:const fRange2 = fWorksheet.getRange(0, 0, 2, 2)console.log(fRange2, fRange2.getA1Notation())const fWorkbook = univerAPI.getActiveWorkbook()const fWorksheet = fWorkbook.getActiveSheet()// Get the A1:B2 range on named Sheet1const fRange1 = fWorksheet.getRange('Sheet1!A1:B2')console.log(fRange1, fRange1.getA1Notation())// Get a single cell A1const fRange2 = fWorksheet.getRange('A1')console.log(fRange2, fRange2.getA1Notation())// Get the A1:B2 rangeconst fRange3 = fWorksheet.getRange('A1:B2')console.log(fRange3, fRange3.getA1Notation())// Get the range of column Aconst fRange4 = fWorksheet.getRange('A:A')console.log(fRange4, fRange4.getA1Notation())// Get the range of row 1const fRange5 = fWorksheet.getRange('1:1')console.log(fRange5, fRange5.getA1Notation())Получение данных диапазона
Получение значения первой ячейки диапазона
const fWorkbook = univerAPI.getActiveWorkbook()if (!fWorkbook) throw new Error('No active workbook')const fWorksheet = fWorkbook.getActiveSheet()const fRange = fWorksheet.getRange('A1:B2')console.log(fRange.getValue()) // The value of the top-left cell in the rangeconsole.log(fRange.getRawValue()) // The raw value of the top-left cell in the rangeconsole.log(fRange.getDisplayValue()) // The displayed value of the top-left cell in the rangeconsole.log(fRange.getCellData()) // The cell data of the top-left cell in the rangeconst value = fRange.getValue(true)console.log(value)if (value !== null && typeof value === 'object') { console.log(value.toPlainText())}Используйте getValue(true), чтобы сохранить объект форматированного текста. Пустая ячейка возвращает null / undefined, обычная — строку, число или логическое значение. Вызывайте toPlainText() только для объекта форматированного текста.
Получение значений всех ячеек диапазона
const fWorkbook = univerAPI.getActiveWorkbook()if (!fWorkbook) throw new Error('No active workbook')const fWorksheet = fWorkbook.getActiveSheet()const fRange = fWorksheet.getRange('A1:B2')console.log(fRange.getValues()) // The values of all cells in the rangeconsole.log(fRange.getRawValues()) // The raw values of all cells in the rangeconsole.log(fRange.getDisplayValues()) // The displayed values of all cells in the rangeconsole.log(fRange.getCellDataGrid()) // The cell data of all cells in the rangeconsole.log(fRange.getValues(true))Получение всех формул диапазона
const fWorkbook = univerAPI.getActiveWorkbook()const fWorksheet = fWorkbook.getActiveSheet()const fRange = fWorksheet.getRange('A1:B2')console.log(fRange.getFormula()) // The formula of the top-left cell in the rangeconsole.log(fRange.getFormulas()) // The formulas of all cells in the rangeЗадание значения диапазона
Задание одного значения
Если передать значение или объект ячейки, оно будет записано во все ячейки диапазона. Если значение начинается с =, оно будет интерпретировано как формула.
Например, чтобы задать для диапазона A1:B2 значение Hello, Univer:
const fWorkbook = univerAPI.getActiveWorkbook()const fWorksheet = fWorkbook.getActiveSheet()const fRange = fWorksheet.getRange('A1:B2')fRange.setValue('Hello, Univer')Запишите =A1+B1 в C1, чтобы результат находился вне исходных ячеек:
const fWorkbook = univerAPI.getActiveWorkbook()if (!fWorkbook) throw new Error('No active workbook')const fWorksheet = fWorkbook.getActiveSheet()const fRange = fWorksheet.getRange('C1')fRange.setValue('=A1+B1')Чтобы задать объект ячейки в качестве значения диапазона A1:B2:
const fWorkbook = univerAPI.getActiveWorkbook()const fWorksheet = fWorkbook.getActiveSheet()const fRange = fWorksheet.getRange('A1:B2')fRange.setValue({ v: 'Hello, Univer', custom: { key: 'value', },})Если требуется задать значение только для верхней левой ячейки диапазона, используйте метод FRange.setValueForCell:
fRange.setValueForCell('Hello, Univer')Задание нескольких значений с помощью массива
Высота и ширина массива должны совпадать с высотой и шириной диапазона.
Можно передавать значения ячеек или объекты ячеек.
const fWorkbook = univerAPI.getActiveWorkbook()const fWorksheet = fWorkbook.getActiveSheet()const fRange = fWorksheet.getRange('A1:B2')fRange.setValues([ ['A1', 'B1'], ['A2', 'B2'],])fRange.setValues([ [{ v: 'A1' }, { v: 'B1' }], [{ v: 'A2' }, { v: 'B2' }],])Задание нескольких значений с помощью объекта
Если передать объект, его индекс первого уровня обозначает номер строки, а индекс второго уровня — номер столбца. При этом высота и ширина диапазона могут не совпадать с размерами объекта.
const fWorkbook = univerAPI.getActiveWorkbook()const fWorksheet = fWorkbook.getActiveSheet()const fRange = fWorksheet.getRange('A1:B2')fRange.setValues({ 0: { 0: 'A1', 1: 'B1', }, 1: { 0: 'A2', 1: 'B2', },})Очистка данных диапазона
- Метод
FRange.clearочищает содержимое и сведения о форматировании диапазона. - Метод
FRange.clearContentочищает содержимое диапазона. - Метод
FRange.clearFormatочищает сведения о форматировании диапазона.
const fWorkbook = univerAPI.getActiveWorkbook()const fWorkSheet = fWorkbook.getActiveSheet()const fRange = fWorkSheet.getRange('A1:D10')// Clears content and formatting information of the range.fRange.clear()Получение стиля диапазона
const fWorkbook = univerAPI.getActiveWorkbook()const fWorksheet = fWorkbook.getActiveSheet()const fRange = fWorksheet.getRange('A1:B2')console.log(fRange.getCellStyleData()) // The style data of the top-left cell in the rangeconsole.log(fRange.getCellStyle()) // The style of the top-left cell in the rangeconsole.log(fRange.getCellStyles()) // The styles of all cells in the rangeЗадание стиля диапазона
const fWorkbook = univerAPI.getActiveWorkbook()const fWorksheet = fWorkbook.getActiveSheet()const fRange = fWorksheet.getRange('A1:B2')fRange .setValues([ [1, 2], [3, 4], ]) .setFontWeight('bold') .setFontLine('underline') .setFontFamily('Arial') .setFontSize(24) .setFontColor('red')Очистка стиля диапазона
const fWorkbook = univerAPI.getActiveWorkbook()const fWorksheet = fWorkbook.getActiveSheet()const fRange = fWorksheet.getRange('A1:B2')fRange.setFontWeight(null).setFontLine(null).setFontFamily(null).setFontSize(null).setFontColor(null)Выделение
Univer Sheets поддерживает несколько областей выделения: выделение представляет собой массив диапазонов, данными которого можно управлять через Range API.
Также доступны API для получения и задания текущего выделения и отслеживания его изменений.
Полное описание Facade API для выделений см. в разделе FSelection FacadeAPI.
Получение активного выделения
const fWorkbook = univerAPI.getActiveWorkbook()const fWorksheet = fWorkbook.getActiveSheet()// Activate the new selection of A1:B2const fRange = fWorksheet.getRange('A1:B2')fRange.activate()// Get the current active selectionconst fSelection = fWorksheet.getSelection()console.log(fSelection)const activeRange = fSelection.getActiveRange()console.log(activeRange.getA1Notation()) // A1:B2Задание выделения
const fWorkbook = univerAPI.getActiveWorkbook()const fWorksheet = fWorkbook.getActiveSheet()// Set the selection to A1:B2 by FRangeconst fRange = fWorksheet.getRange('A1:B2')fRange.activate()// Set the selection to C1:D2 by FWorksheetfWorksheet.setActiveSelection(fWorksheet.getRange('C1:D2'))Получение текущей ячейки
const fWorkbook = univerAPI.getActiveWorkbook()const fWorksheet = fWorkbook.getActiveSheet()// Activate the new selection of A10:B11const fRange = fWorksheet.getRange('A10:B11')fRange.activate()// Get the current active celllet fSelection = fWorksheet.getSelection()const { actualRow, actualColumn } = fSelection.getCurrentCell()console.log(fWorksheet.getRange(actualRow, actualColumn).getA1Notation()) // A10// Update the new active cell to B11fSelection = fSelection.updatePrimaryCell(fWorksheet.getRange('B11'))const { actualRow: newRow, actualColumn: newColumn } = fSelection.getCurrentCell()console.log(fWorksheet.getRange(newRow, newColumn).getA1Notation()) // B11Отключение, включение, скрытие и отображение выделения
После отключения выделение перестаёт реагировать на действия. Метод transparentSelection делает выделение невидимым; в отличие от disableSelection, оно продолжает работать, но не отображается.
const fWorkbook = univerAPI.getActiveWorkbook()// Disable selectionfWorkbook.disableSelection()// Enable selectionfWorkbook.enableSelection()// Hide selectionfWorkbook.transparentSelection()// Show selectionfWorkbook.showSelection()Отслеживание изменений выделения
univerAPI.addEvent(univerAPI.Event.SelectionChanged, (params) => { const { worksheet, workbook, selections } = params console.log(params)})Ячейка
Данные ячеек хранятся на листе в двумерной структуре Map, где первый индекс обозначает номер строки, а второй — номер столбца.
Типичный объект ячейки выглядит так:
const data = { v: 'Hello, Univer', s: 'styleId', t: CellValueType.STRING,}Подробное описание полей см. в разделе Настройка данных ячейки.
Полезно знать
- Операции с ячейкой можно рассматривать как операции с диапазоном высотой в одну строку и шириной в один столбец. Подробнее см. в разделе Диапазон.
- Плагин Univer API также сохраняет расширенные атрибуты ячеек в свойстве
resourcesобъектаWorkbook. Подробнее см. в разделе Пользовательская модель плагина.
Расширенные операции с диапазонами
Вставка ячеек
Метод FRange.insertCells вставляет в диапазон пустые ячейки. Существующие данные на листе сдвигаются по указанному измерению в сторону от вставленного диапазона.
// Assume the active sheet empty sheet.const fWorkbook = univerAPI.getActiveWorkbook()const fWorksheet = fWorkbook.getActiveSheet()const values = [ [1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6], [4, 5, 6, 7], [5, 6, 7, 8],]// Set the range A1:D5 with some values, the range A1:D5 will be:// 1 | 2 | 3 | 4// 2 | 3 | 4 | 5// 3 | 4 | 5 | 6// 4 | 5 | 6 | 7// 5 | 6 | 7 | 8const fRange = fWorksheet.getRange('A1:D5')fRange.setValues(values)console.log(fWorksheet.getRange('A1:D5').getValues()) // [[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6], [4, 5, 6, 7], [5, 6, 7, 8]]// Insert the empty cells into the range A1:B2 along the columns dimension, the range A1:D5 will be:// | | 1 | 2// | | 2 | 3// 3 | 4 | 5 | 6// 4 | 5 | 6 | 7// 5 | 6 | 7 | 8const fRange2 = fWorksheet.getRange('A1:B2')fRange2.insertCells(univerAPI.Enum.Dimension.COLUMNS)console.log(fWorksheet.getRange('A1:D5').getValues()) // [[null, null, 1, 2], [null, null, 2, 3], [3, 4, 5, 6], [4, 5, 6, 7], [5, 6, 7, 8]]// Set the range A1:D5 values again, the range A1:D5 will be:// 1 | 2 | 3 | 4// 2 | 3 | 4 | 5// 3 | 4 | 5 | 6// 4 | 5 | 6 | 7// 5 | 6 | 7 | 8fRange.setValues(values)// Insert the empty cells into the range A1:B2 along the rows dimension, the range A1:D5 will be:// | | 3 | 4// | | 4 | 5// 1 | 2 | 5 | 6// 2 | 3 | 6 | 7// 3 | 4 | 7 | 8const fRange3 = fWorksheet.getRange('A1:B2')fRange3.insertCells(univerAPI.Enum.Dimension.ROWS)console.log(fWorksheet.getRange('A1:D5').getValues()) // [[null, null, 3, 4], [null, null, 4, 5], [1, 2, 5, 6], [2, 3, 6, 7], [3, 4, 7, 8]]Удаление ячеек
Метод FRange.deleteCells удаляет ячейки диапазона. Существующие данные на листе сдвигаются по указанному измерению в сторону удалённого диапазона.
// Assume the active sheet empty sheet.const fWorkbook = univerAPI.getActiveWorkbook()const fWorksheet = fWorkbook.getActiveSheet()const values = [ [1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6], [4, 5, 6, 7], [5, 6, 7, 8],]// Set the range A1:D5 with some values, the range A1:D5 will be:// 1 | 2 | 3 | 4// 2 | 3 | 4 | 5// 3 | 4 | 5 | 6// 4 | 5 | 6 | 7// 5 | 6 | 7 | 8const fRange = fWorksheet.getRange('A1:D5')fRange.setValues(values)console.log(fWorksheet.getRange('A1:D5').getValues()) // [[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6], [4, 5, 6, 7], [5, 6, 7, 8]]// Delete the range A1:B2 along the columns dimension, the range A1:D5 will be:// 3 | 4 | |// 4 | 5 | |// 3 | 4 | 5 | 6// 4 | 5 | 6 | 7// 5 | 6 | 7 | 8const fRange2 = fWorksheet.getRange('A1:B2')fRange2.deleteCells(univerAPI.Enum.Dimension.COLUMNS)console.log(fWorksheet.getRange('A1:D5').getValues()) // [[3, 4, null, null], [4, 5, null, null], [3, 4, 5, 6], [4, 5, 6, 7], [5, 6, 7, 8]]// Set the range A1:D5 values again, the range A1:D5 will be:// 1 | 2 | 3 | 4// 2 | 3 | 4 | 5// 3 | 4 | 5 | 6// 4 | 5 | 6 | 7// 5 | 6 | 7 | 8fRange.setValues(values)// Delete the range A1:B2 along the rows dimension, the range A1:D5 will be:// 3 | 4 | 3 | 4// 4 | 5 | 4 | 5// 5 | 6 | 5 | 6// | | 6 | 7// | | 7 | 8const fRange3 = fWorksheet.getRange('A1:B2')fRange3.deleteCells(univerAPI.Enum.Dimension.ROWS)console.log(fWorksheet.getRange('A1:D5').getValues()) // [[3, 4, 3, 4], [4, 5, 4, 5], [5, 6, 5, 6], [null, null, 6, 7], [null, null, 7, 8]]Объединение ячеек
const fWorkbook = univerAPI.getActiveWorkbook()const fWorksheet = fWorkbook.getActiveSheet()// Merge B1:B2const fRange = fWorksheet.getRange('B1:B2')fRange.merge()console.log(fRange.isMerged()) // true// A1:B2 is mergedconst fRange2 = fWorksheet.getRange('A1:B2')console.log(fRange2.isMerged()) // falseconsole.log(fRange2.isPartOfMerge()) // true// Break apart the merged rangefRange2.breakApart()// merge horizontally: fRange2.mergeAcross();// merge vertically: fRange2.mergeVertically();// Get all merged ranges in the worksheet: fWorksheet.getMergedRanges();Выделение диапазона цветом
Метод FRange.highlight выделяет диапазон указанным стилем с заданной основной ячейкой.
const fWorkbook = univerAPI.getActiveWorkbook()const fWorksheet = fWorkbook.getActiveSheet()// Highlight the range C3:E5 with default styleconst fRange = fWorksheet.getRange('C3:E5')fRange.highlight()// Highlight the range C7:E9 with custom style and primary cell D8const fRange2 = fWorksheet.getRange('C7:E9')const primaryCell = fWorksheet.getRange('D8').getRange()const disposable = fRange2.highlight( { stroke: 'red', fill: 'yellow', }, { ...primaryCell, actualRow: primaryCell.startRow, actualColumn: primaryCell.startColumn, },)// Remove the range C7:E9 highlight after 5 secondssetTimeout(() => { disposable.dispose()}, 5000)Разбиение текста по столбцам
Метод FRange.splitTextToColumns разбивает текст в диапазоне по столбцам согласно указанному разделителю.
Пример с разделителем по умолчанию:
const fWorkbook = univerAPI.getActiveWorkbook()const fWorksheet = fWorkbook.getActiveSheet()// A1:A3 has following values:// A |// 1,2,3 |// 4,,5,6 |const fRange = fWorksheet.getRange('A1:A3')fRange.setValues([['A'], ['1,2,3'], ['4,,5,6']])// After calling splitTextToColumns(true), the range will be:// A | |// 1 | 2 | 3// 4 | 5 | 6fRange.splitTextToColumns(true)// After calling splitTextToColumns(false), the range will be:// A | | |// 1 | 2 | 3 |// 4 | | 5 | 6fRange.splitTextToColumns(false)Пример с указанным разделителем:
const fWorkbook = univerAPI.getActiveWorkbook()const fWorksheet = fWorkbook.getActiveSheet()// A1:A3 has following values:// A |// 1;;2;3 |// 1;,2;3 |const fRange = fWorksheet.getRange('A1:A3')fRange.setValues([['A'], ['1;;2;3'], ['1;,2;3']])// After calling splitTextToColumns(false, univerAPI.Enum.SplitDelimiterType.Semicolon|univerAPI.Enum.SplitDelimiterType.Comma), the range will be:// A | | |// 1 | | 2 | 3// 1 | | 2 | 3fRange.splitTextToColumns(false, univerAPI.Enum.SplitDelimiterType.Semicolon | univerAPI.Enum.SplitDelimiterType.Comma)// After calling splitTextToColumns(true, univerAPI.Enum.SplitDelimiterType.Semicolon|univerAPI.Enum.SplitDelimiterType.Comma), the range will be:// A | |// 1 | 2 | 3// 1 | 2 | 3fRange.splitTextToColumns(true, univerAPI.Enum.SplitDelimiterType.Semicolon | univerAPI.Enum.SplitDelimiterType.Comma)Пример с пользовательским разделителем:
const fWorkbook = univerAPI.getActiveWorkbook()const fWorksheet = fWorkbook.getActiveSheet()// A1:A3 has following values:// A |// 1#2#3 |// 4##5#6 |const fRange = fWorksheet.getRange('A1:A3')fRange.setValues([['A'], ['1#2#3'], ['4##5#6']])// After calling splitTextToColumns(false, univerAPI.Enum.SplitDelimiterType.Custom, '#'), the range will be:// A | | |// 1 | 2 | 3 |// 4 | | 5 | 6fRange.splitTextToColumns(false, univerAPI.Enum.SplitDelimiterType.Custom, '#')// After calling splitTextToColumns(true, univerAPI.Enum.SplitDelimiterType.Custom, '#'), the range will be:// A | |// 1 | 2 | 3// 4 | 5 | 6fRange.splitTextToColumns(true, univerAPI.Enum.SplitDelimiterType.Custom, '#')Получение координат диапазона
const fWorkbook = univerAPI.getActiveWorkbook()const fWorksheet = fWorkbook.getActiveSheet()const fRange = fWorksheet.getRange('A1:B2')console.log(fRange.getCellRect()) // width、heigh、left、right、top、bottom、x、yОдновременное получение сведений об объединении и координат диапазона
const fWorkbook = univerAPI.getActiveWorkbook()const fWorksheet = fWorkbook.getActiveSheet()const fRange = fWorksheet.getRange('A1:B2')console.log(fRange.getCell())Навигация на границах листа
Параметр allowArrowKeyWrapOnSheetBoundary управляет переходом на другую строку или столбец при достижении края листа клавишами со стрелками. По умолчанию он равен true; значение false останавливает переход на границе. Циклическая навигация Enter/Tab внутри выделения не меняется. В пресете укажите параметр в sheets, а в режиме плагинов — непосредственно в UniverSheetsUIPlugin.
univer.registerPlugin(UniverSheetsUIPlugin, { allowArrowKeyWrapOnSheetBoundary: false,})createUniver({ presets: [ UniverSheetsCorePreset({ sheets: { allowArrowKeyWrapOnSheetBoundary: false, }, }), ],})События и редактирование ячеек
Примеры сгруппированы по указателю, отрисовке, редактированию и буферу обмена. Полный список событий и типов параметров см. в Events Reference. В режиме плагинов импортируйте @univerjs/sheets-ui/facade до подписки; предустановка Sheets Core уже включает его. Освобождайте подписки при удалении компонента или страницы.
Пример использования
Для всех событий можно зарегистрировать обработчик с помощью метода addEvent. Базовый формат:
import '@univerjs/sheets-ui/facade'const subscription = univerAPI.addEvent(univerAPI.Event.CellClicked, ({ row, column }) => { console.log(row, column)})// Call subscription.dispose() when the owning component or page is removed.Событие Cell PointerMove
Событие CellPointerMove возникает при перемещении указателя мыши над ячейкой и содержит сведения о ячейке под указателем.
univerAPI.addEvent(univerAPI.Event.CellPointerMove, (params) => { // Get event parameters const { worksheet, workbook, row, column } = params console.log('Current cell position:', worksheet.getRange(row, column).getA1Notation())})Событие Cell PointerDown
Событие CellPointerDown возникает при нажатии кнопки мыши на ячейке.
univerAPI.addEvent(univerAPI.Event.CellPointerDown, (params) => { const { worksheet, workbook, row, column } = params console.log('Mouse down cell:', worksheet.getRange(row, column).getA1Notation())})Событие Cell PointerUp
Событие CellPointerUp возникает при отпускании кнопки мыши на ячейке.
univerAPI.addEvent(univerAPI.Event.CellPointerUp, (params) => { const { worksheet, workbook, row, column } = params console.log('Mouse up cell:', worksheet.getRange(row, column).getA1Notation())})Событие Cell Hover
Событие CellHover возникает при наведении указателя мыши на ячейку.
univerAPI.addEvent(univerAPI.Event.CellHover, (params) => { const { worksheet, workbook, row, column } = params console.log('Hovered cell:', worksheet.getRange(row, column).getA1Notation())})Событие Cell DragOver
Событие DragOver возникает при перетаскивании элемента над ячейкой.
univerAPI.addEvent(univerAPI.Event.DragOver, (params) => { const { worksheet, workbook, row, column } = params console.log('Drag over cell:', worksheet.getRange(row, column).getA1Notation())})Событие Cell Drop
Событие Drop возникает, когда элемент отпускают на ячейке.
univerAPI.addEvent(univerAPI.Event.Drop, (params) => { const { worksheet, workbook, row, column } = params console.log('Drop target cell:', worksheet.getRange(row, column).getA1Notation())})Событие Cell Click
Событие CellClicked возникает при щелчке по ячейке.
univerAPI.addEvent(univerAPI.Event.CellClicked, (params) => { const { worksheet, workbook, row, column } = params console.log('Clicked cell:', worksheet.getRange(row, column).getA1Notation())})Событие отрисовки ячейки
registerCellCustomRender регистрирует пользовательские функции отрисовки ячеек.
Пример 1. Отрисовка в фиксированной позиции: добавление строк не влияет на позицию
// Fixed position renderinguniverAPI.registerCellCustomRender([ { drawWith: (ctx, info, skeleton, spreadsheets) => { const { row, col } = info // Render a checkmark at position (1,1) if (row === 1 && col === 1) { const { primaryWithCoord } = info const { startX, startY } = primaryWithCoord ctx.fillText('✅', startX, startY + 10) } }, },])// Refresh canvas to apply renderinguniverAPI.getActiveWorkbook().getActiveSheet().refreshCanvas()Пример 2. Отрисовка по маркеру: позиция меняется при изменении строк или столбцов
// Set markeruniverAPI .getActiveWorkbook() .getActiveSheet() .getRange('B2') .setValue({ custom: { key: 'needCheck' } })// Render based on markeruniverAPI.registerCellCustomRender([ { drawWith: (ctx, info, skeleton, spreadsheets) => { const { row, col, data } = info // Render checkmark at marked position if (data?.custom?.key === 'needCheck') { const { primaryWithCoord } = info const { startX, startY } = primaryWithCoord ctx.fillText('✅', startX, startY + 10) } }, },])// Refresh canvas to apply renderinguniverAPI.getActiveWorkbook().getActiveSheet().refreshCanvas()События редактирования ячейки
Начало редактирования
const fWorkbook = univerAPI.getActiveWorkbook()fWorkbook.startEditing()Завершение редактирования
// Pass true to commit changes, false to cancel editing// This is an async function, requires awaitconst fWorkbook = univerAPI.getActiveWorkbook()await fWorkbook.endEditingAsync(true)Событие начала редактирования
Событие BeforeSheetEditStart возникает перед началом редактирования ячейки.
univerAPI.addEvent(univerAPI.Event.BeforeSheetEditStart, (params) => { const { worksheet, workbook, row, column, eventType, keycode } = params console.log('Before cell edit:', params) // If you want to prevent entering the editing state params.cancel = true})Событие SheetEditStarted возникает при начале редактирования ячейки.
const disposable = univerAPI.addEvent(univerAPI.Event.SheetEditStarted, (params) => { const { worksheet, workbook, row, column, eventType, keycode } = params console.log(params)})// Remove the event listener, use `disposable.dispose()`Событие завершения редактирования
Событие BeforeSheetEditEnd возникает перед завершением редактирования ячейки.
const disposable = univerAPI.addEvent(univerAPI.Event.BeforeSheetEditEnd, (params) => { const { worksheet, workbook, row, column, value, eventType, keycode, isConfirm } = params console.log(params) // Cancel the cell edit end operation params.cancel = true})// Remove the event listener, use `disposable.dispose()`Событие SheetEditEnded возникает после завершения редактирования ячейки.
univerAPI.addEvent(univerAPI.Event.SheetEditEnded, (params) => { const { worksheet, workbook, row, column, eventType, keycode, isConfirm } = params console.log('After cell edit:', params)})События буфера обмена
BeforeClipboardChange
Событие BeforeClipboardChange возникает перед изменением содержимого буфера обмена. Оно позволяет проверить или изменить содержимое до изменения.
univerAPI.addEvent(univerAPI.Event.BeforeClipboardChange, (params) => { const { text, html } = params console.log('Clipboard content:', text, html) // If you want to cancel the clipboard change // params.cancel = true;})BeforeClipboardPaste
Событие BeforeClipboardPaste возникает перед вставкой содержимого. Оно позволяет проверить или изменить содержимое до вставки.
univerAPI.addEvent(univerAPI.Event.BeforeClipboardPaste, (params) => { const { text, html } = params console.log('Content to paste:', text, html) // If you want to cancel the paste operation // params.cancel = true;})ClipboardChanged
Событие ClipboardChanged возникает после изменения содержимого буфера обмена.
univerAPI.addEvent(univerAPI.Event.ClipboardChanged, (params) => { const { text, html } = params console.log('New clipboard content:', text, html)})ClipboardPasted
Событие ClipboardPasted возникает после вставки содержимого.
univerAPI.addEvent(univerAPI.Event.ClipboardPasted, (params) => { const { text, html } = params console.log('Pasted content:', text, html)})Устранение проблем редактирования
Как получать данные из редактора ячейки в реальном времени?
Подпишитесь на SheetEditChanging, чтобы читать форматированный текст во время редактирования ячейки. Значение ещё находится в редакторе и сохраняется в листе при завершении редактирования.
import '@univerjs/sheets-ui/facade'const subscription = univerAPI.addEvent(univerAPI.Event.SheetEditChanging, ({ value }) => { console.log(value.toPlainText())})// Call subscription.dispose() when the owning component or page is removed.Почему при щелчке по внешней кнопке снимок не содержит данные ячейки, в которой установлен фокус?
Данные ячейки синхронизируются со снимком, когда редактор ячейки теряет фокус, то есть после завершения редактирования. Поэтому перед получением снимка убедитесь, что ячейка потеряла фокус. Редактирование можно завершить следующим образом:
import '@univerjs/sheets-ui/facade'async function saveWorkbook() { const fWorkbook = univerAPI.getActiveWorkbook() if (!fWorkbook) return await fWorkbook.endEditingAsync(true) const snapshot = fWorkbook.save() console.log(snapshot)}$btn.addEventListener('click', () => { saveWorkbook().catch(console.error)})Источник: https://github.com/dream-num/univer/issues/1314
При создании Workbook через Facade API некоторые API могут не работать сразу, поскольку им требуется полностью отрисованный интерфейс. Рекомендуется выполнять соответствующие операции на этапе жизненного цикла Rendered или Steady.
Многие API работают только после полной отрисовки интерфейса. Если вызвать их сразу после создания Workbook, интерфейс может быть ещё не готов. Рекомендуется выполнять такие операции на этапе жизненного цикла Rendered или Steady:
const disposable = univerAPI.addEvent(univerAPI.Event.LifeCycleChanged, ({ stage }) => { if (stage === univerAPI.Enum.LifecycleStages.Steady) { // code... }})// To remove the event listener, you can call `disposable.dispose()`Источник: Жизненный цикл
Насколько полезно это руководство?