範圍 & 選區 & 單元格
依任務跳轉到下方章節。本頁集中介紹基礎操作、進階範例、設定與疑難排解;完整 API 定義統一在 Reference 中維護。
範圍 Range
範圍指工作表中的一塊矩形區域,有起始行號、起始列號、長寬或者結束行號、結束列號來確定。
表格中的大部分操作都可以透過範圍 API 來操作,如設定值、獲取值、設定樣式、獲取樣式等。
範圍完整 Facade API 型別定義,請檢視 FRange Facade API
建立範圍
獲得一個範圍需要知道起始行號、起始列號、長寬。
const fWorkbook = univerAPI.getActiveWorkbook()const fWorksheet = fWorkbook.getActiveSheet()// 獲取 A1 單元格的範圍:const fRange = fWorksheet.getRange(0, 0)console.log(fRange, fRange.getA1Notation())// 獲取 A1:B2 的範圍:const fRange2 = fWorksheet.getRange(0, 0, 2, 2)console.log(fRange2, fRange2.getA1Notation())const fWorkbook = univerAPI.getActiveWorkbook()const fWorksheet = fWorkbook.getActiveSheet()// 獲取名稱是 Sheet1 的工作表的 A1:B2 範圍const fRange1 = fWorksheet.getRange('Sheet1!A1:B2')console.log(fRange1, fRange1.getA1Notation())// 獲取單個單元格 A1const fRange2 = fWorksheet.getRange('A1')console.log(fRange2, fRange2.getA1Notation())// 獲取 A1:B2 範圍const fRange3 = fWorksheet.getRange('A1:B2')console.log(fRange3, fRange3.getA1Notation())// 獲取 A 列的範圍const fRange4 = fWorksheet.getRange('A:A')console.log(fRange4, fRange4.getA1Notation())// 獲取第 1 行的範圍const 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()) // 範圍左上角單元格值console.log(fRange.getRawValue()) // 範圍左上角單元格原始值console.log(fRange.getDisplayValue()) // 範圍左上角單元格顯示值console.log(fRange.getCellData()) // 範圍左上角單元格 ICellData 物件const 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()) // 範圍所有單元格值console.log(fRange.getRawValues()) // 範圍所有單元格原始值console.log(fRange.getDisplayValues()) // 範圍所有單元格顯示值console.log(fRange.getCellDataGrid()) // 範圍所有單元格 ICellData 物件console.log(fRange.getValues(true))獲取範圍的所有公式
const fWorkbook = univerAPI.getActiveWorkbook()const fWorksheet = fWorkbook.getActiveSheet()const fRange = fWorksheet.getRange('A1:B2')console.log(fRange.getFormula()) // 範圍左上角單元格公式console.log(fRange.getFormulas()) // 範圍所有單元格公式設定範圍資料
設定單一值
傳入一個值或者單元格物件,將會覆蓋範圍內所有單元格,如果以 = 開頭,將被解釋為公式。
比如,設定 A1:B2 的值為 Hello, Univer:
const fWorkbook = univerAPI.getActiveWorkbook()const fWorksheet = fWorkbook.getActiveSheet()const fRange = fWorksheet.getRange('A1:B2')fRange.setValue('Hello, Univer')將 C1 的值設為 =A1+B1,讓結果與輸入儲存格分開:
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')// 清除範圍的內容和格式資訊。fRange.clear()獲取範圍樣式
const fWorkbook = univerAPI.getActiveWorkbook()const fWorksheet = fWorkbook.getActiveSheet()const fRange = fWorksheet.getRange('A1:B2')console.log(fRange.getCellStyleData()) // 範圍左上角單元格樣式資料console.log(fRange.getCellStyle()) // 範圍左上角單元格樣式console.log(fRange.getCellStyles()) // 範圍所有單元格樣式設定範圍樣式
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)選區 Selection
Univer 表格支援多選區,所以選區是一個範圍陣列,可以透過範圍 API 來操作選區資料。
我們還提供 API 來獲取當前選區、設定選區和監聽選區變化。
選區完整 Facade API 型別定義,請檢視 FSelection Facade API
獲取啟用選區的範圍
const fWorkbook = univerAPI.getActiveWorkbook()const fWorksheet = fWorkbook.getActiveSheet()// 啟用新的選區const fRange = fWorksheet.getRange('A1:B2')fRange.activate()// 獲取啟用選區的範圍const fSelection = fWorksheet.getSelection()console.log(fSelection)const activeRange = fSelection.getActiveRange()console.log(activeRange.getA1Notation()) // A1:B2設定選區
const fWorkbook = univerAPI.getActiveWorkbook()const fWorksheet = fWorkbook.getActiveSheet()// 透過 FRange 設定選區 A1:B2const fRange = fWorksheet.getRange('A1:B2')fRange.activate()// 透過 FWorksheet 設定選區 C1:D2fWorksheet.setActiveSelection(fWorksheet.getRange('C1:D2'))獲取當前啟用的單元格
const fWorkbook = univerAPI.getActiveWorkbook()const fWorksheet = fWorkbook.getActiveSheet()// 啟用選區 A10:B11const fRange = fWorksheet.getRange('A10:B11')fRange.activate()// 獲取當前啟用的單元格let fSelection = fWorksheet.getSelection()const { actualRow, actualColumn } = fSelection.getCurrentCell()console.log(fWorksheet.getRange(actualRow, actualColumn).getA1Notation()) // A10// 更新新的啟用單元格 B11fSelection = fSelection.updatePrimaryCell(fWorksheet.getRange('B11'))const { actualRow: newRow, actualColumn: newColumn } = fSelection.getCurrentCell()console.log(fWorksheet.getRange(newRow, newColumn).getA1Notation()) // B11禁用/啟用/隱藏/顯示選區
禁用後,選區將不會響應。設定選區不可見,與禁用選區不同,選區仍然有效,只是看不到它們。
const fWorkbook = univerAPI.getActiveWorkbook()// 禁用選區fWorkbook.disableSelection()// 啟用選區fWorkbook.enableSelection()// 隱藏選區fWorkbook.transparentSelection()// 顯示選區fWorkbook.showSelection()監聽選區變化
univerAPI.addEvent(univerAPI.Event.SelectionChanged, (params) => { const { worksheet, workbook, selections } = params console.log(params)})單元格 Cell
單元格資料以二維 Map 的形式儲存在工作表中,一二級索引分別代表行號和列號。
以下是一個典型的單元格物件:
const data = { v: 'Hello, Univer', s: 'styleId', t: CellValueType.STRING,}詳細的欄位說明請參考 單元格資訊。
注意事項
- 對單元格的操作可以看作對行高 1 、列寬 1 的範圍進行操作,操作範圍請閱讀 範圍-range。
- 外掛還會將拓展的單元格屬性儲存在
Workbook的resources屬性中,詳細請閱讀 外掛自訂模型。
範圍進階操作
插入單元格
FRange.insertCells 方法可以在此範圍內插入空單元格。工作表中沿指定維度的現有資料將移離插入的範圍。
// 假設當前工作表是空工作表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],]// A1:D5 範圍設定值如下:// 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]]// 沿著列維度在範圍 A1:B2 中插入空單元格,範圍 A1:D5 將變為:// | | 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]]// 再次設定範圍 A1:D5 的值,範圍 A1:D5 將變為:// 1 | 2 | 3 | 4// 2 | 3 | 4 | 5// 3 | 4 | 5 | 6// 4 | 5 | 6 | 7// 5 | 6 | 7 | 8fRange.setValues(values)// 沿著行維度在範圍 A1:B2 中插入空單元格,範圍 A1:D5 將變為:// | | 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 方法可以在範圍內刪除單元格。工作表中沿指定維度的現有資料將向已刪除的範圍移動。
// 假設當前工作表是空工作表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],]// A1:D5 範圍設定值如下:// 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]]// 沿著列維度刪除範圍 A1:B2,範圍 A1:D5 將變為:// 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]]// 再次設定範圍 A1:D5 的值,範圍 A1:D5 將變為:// 1 | 2 | 3 | 4// 2 | 3 | 4 | 5// 3 | 4 | 5 | 6// 4 | 5 | 6 | 7// 5 | 6 | 7 | 8fRange.setValues(values)// 沿著行維度刪除範圍 A1:B2,範圍 A1:D5 將變為:// 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()// 合併 B1:B2const fRange = fWorksheet.getRange('B1:B2')fRange.merge()console.log(fRange.isMerged()) // true// A1:B2 是否合併const fRange2 = fWorksheet.getRange('A1:B2')console.log(fRange2.isMerged()) // falseconsole.log(fRange2.isPartOfMerge()) // true// 取消合併fRange2.breakApart()// 水平合併:fRange2.mergeAcross();// 垂直合併:fRange2.mergeVertically();// 獲取表格中所有合併單元格範圍: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 包含以下值:// A |// 1,2,3 |// 4,,5,6 |const fRange = fWorksheet.getRange('A1:A3')fRange.setValues([['A'], ['1,2,3'], ['4,,5,6']])// 呼叫 splitTextToColumns(true) 後,範圍值將變為:// A | |// 1 | 2 | 3// 4 | 5 | 6fRange.splitTextToColumns(true)// 呼叫 splitTextToColumns(false) 後,範圍值將變為:// A | | |// 1 | 2 | 3 |// 4 | | 5 | 6fRange.splitTextToColumns(false)指定分隔符示例:
const fWorkbook = univerAPI.getActiveWorkbook()const fWorksheet = fWorkbook.getActiveSheet()// A1:A3 包含以下值:// A |// 1;;2;3 |// 1;,2;3 |const fRange = fWorksheet.getRange('A1:A3')fRange.setValues([['A'], ['1;;2;3'], ['1;,2;3']])// 呼叫 splitTextToColumns(false, univerAPI.Enum.SplitDelimiterType.Semicolon|univerAPI.Enum.SplitDelimiterType.Comma) 後,範圍值將變為:// A | | |// 1 | | 2 | 3// 1 | | 2 | 3fRange.splitTextToColumns(false, univerAPI.Enum.SplitDelimiterType.Semicolon | univerAPI.Enum.SplitDelimiterType.Comma)// 呼叫 splitTextToColumns(true, univerAPI.Enum.SplitDelimiterType.Semicolon|univerAPI.Enum.SplitDelimiterType.Comma) 後,範圍值將變為:// 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 包含以下值:// A |// 1#2#3 |// 4##5#6 |const fRange = fWorksheet.getRange('A1:A3')fRange.setValues([['A'], ['1#2#3'], ['4##5#6']])// 呼叫 splitTextToColumns(false, univerAPI.Enum.SplitDelimiterType.Custom, '#') 後,範圍值將變為:// A | | |// 1 | 2 | 3 |// 4 | | 5 | 6fRange.splitTextToColumns(false, univerAPI.Enum.SplitDelimiterType.Custom, '#')// 呼叫 splitTextToColumns(true, univerAPI.Enum.SplitDelimiterType.Custom, '#') 後,範圍值將變為:// 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, }, }), ],})儲存格事件與編輯
以下範例依指標、繪製、編輯與剪貼簿互動組織。完整事件與參數型別見事件 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.單元格 PointerMove 事件
CellPointerMove 事件在滑鼠移動到單元格上時觸發。透過此事件可以獲取當前滑鼠指向的單元格資訊。
univerAPI.addEvent(univerAPI.Event.CellPointerMove, (params) => { // 獲取事件參數 const { worksheet, workbook, row, column } = params console.log('當前單元格位置:', worksheet.getRange(row, column).getA1Notation())})單元格 PointerDown 事件
CellPointerDown 事件在滑鼠按下時觸發。
univerAPI.addEvent(univerAPI.Event.CellPointerDown, (params) => { const { worksheet, workbook, row, column } = params console.log('滑鼠按下的單元格:', worksheet.getRange(row, column).getA1Notation())})單元格 PointerUp 事件
CellPointerUp 事件在滑鼠釋放時觸發。
univerAPI.addEvent(univerAPI.Event.CellPointerUp, (params) => { const { worksheet, workbook, row, column } = params console.log('滑鼠釋放的單元格:', worksheet.getRange(row, column).getA1Notation())})單元格 Hover 事件
CellHover 事件在滑鼠懸停在單元格上時觸發。
univerAPI.addEvent(univerAPI.Event.CellHover, (params) => { const { worksheet, workbook, row, column } = params console.log('懸停的單元格:', worksheet.getRange(row, column).getA1Notation())})單元格 DragOver 事件
DragOver 事件在拖動元素經過單元格時觸發。
univerAPI.addEvent(univerAPI.Event.DragOver, (params) => { const { worksheet, workbook, row, column } = params console.log('拖動經過的單元格:', worksheet.getRange(row, column).getA1Notation())})單元格 Drop 事件
Drop 事件在拖動元素放置到單元格時觸發。
univerAPI.addEvent(univerAPI.Event.Drop, (params) => { const { worksheet, workbook, row, column } = params console.log('放置的單元格:', worksheet.getRange(row, column).getA1Notation())})單元格 Click 事件
CellClicked 事件在點選單元格時觸發。
univerAPI.addEvent(univerAPI.Event.CellClicked, (params) => { const { worksheet, workbook, row, column } = params console.log('點選的單元格:', worksheet.getRange(row, column).getA1Notation())})單元格渲染事件
registerCellCustomRender 用於註冊單元格自訂渲染器。
案例 1:固定位置渲染,新增行不會影響渲染位置
// 固定位置渲染univerAPI.registerCellCustomRender([ { drawWith: (ctx, info, skeleton, spreadsheets) => { const { row, col } = info // 在指定位置(1,1)渲染勾選標記 if (row === 1 && col === 1) { const { primaryWithCoord } = info const { startX, startY } = primaryWithCoord ctx.fillText('✅', startX, startY + 10) } }, },])// 重新整理畫布以應用渲染univerAPI.getActiveWorkbook().getActiveSheet().refreshCanvas()案例 2:按標記渲染,標記位置會隨著行列變化而變化
// 設定標記univerAPI .getActiveWorkbook() .getActiveSheet() .getRange('B2') .setValue({ custom: { key: 'needCheck' } })// 按標記渲染univerAPI.registerCellCustomRender([ { drawWith: (ctx, info, skeleton, spreadsheets) => { const { row, col, data } = info // 在標記的位置渲染勾選標記 if (data?.custom?.key === 'needCheck') { const { primaryWithCoord } = info const { startX, startY } = primaryWithCoord ctx.fillText('✅', startX, startY + 10) } }, },])// 重新整理畫布以應用渲染univerAPI.getActiveWorkbook().getActiveSheet().refreshCanvas()單元格編輯事件
開始編輯
const fWorkbook = univerAPI.getActiveWorkbook()fWorkbook.startEditing()結束編輯
// 傳入 true 表示提交編輯,false 表示取消編輯// 這是一個非同步函式,需要使用 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('單元格編輯前:', params) // 如果想阻止進入編輯狀態 params.cancel = true})SheetEditStarted 事件在單元格開始編輯時觸發。
const disposable = univerAPI.addEvent(univerAPI.Event.SheetEditStarted, (params) => { const { worksheet, workbook, row, column, eventType, keycode } = params console.log(params)})// 移除事件監聽器,使用 `disposable.dispose()`結束編輯事件
BeforeSheetEditEnd 事件在單元格結束編輯前觸發。
const disposable = univerAPI.addEvent(univerAPI.Event.BeforeSheetEditEnd, (params) => { const { worksheet, workbook, row, column, value, eventType, keycode, isConfirm } = params console.log(params) // 取消單元格編輯結束操作 params.cancel = true})// 移除事件監聽器,使用 `disposable.dispose()`SheetEditEnded 事件在單元格結束編輯後觸發。
univerAPI.addEvent(univerAPI.Event.SheetEditEnded, (params) => { const { worksheet, workbook, row, column, eventType, keycode, isConfirm } = params console.log('單元格編輯後:', params)})剪貼簿事件
BeforeClipboardChange
BeforeClipboardChange 事件在剪貼簿內容改變之前觸發。你可以使用此事件在內容改變之前監控或修改剪貼簿內容。
univerAPI.addEvent(univerAPI.Event.BeforeClipboardChange, (params) => { const { text, html } = params console.log('剪貼簿內容:', text, html) // 如果想取消剪貼簿內容的改變 // params.cancel = true;})BeforeClipboardPaste
BeforeClipboardPaste 事件在內容貼上之前觸發。你可以使用此事件在貼上之前監控或修改內容。
univerAPI.addEvent(univerAPI.Event.BeforeClipboardPaste, (params) => { const { text, html } = params console.log('待貼上內容:', text, html) // 如果想取消貼上操作 // params.cancel = true;})ClipboardChanged
ClipboardChanged 事件在剪貼簿內容改變之後觸發。
univerAPI.addEvent(univerAPI.Event.ClipboardChanged, (params) => { const { text, html } = params console.log('新的剪貼簿內容:', text, html)})ClipboardPasted
ClipboardPasted 事件在內容貼上完成後觸發。
univerAPI.addEvent(univerAPI.Event.ClipboardPasted, (params) => { const { text, html } = params console.log('已貼上的內容:', 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.單元格編輯器聚焦時,點選外部按鈕觸發事件,獲取的 snapshot 未包含當前單元格資料
單元格資料會在編輯器失焦(即編輯狀態結束)時同步到 snapshot。因此,在嘗試獲取 snapshot 資料前,應確保單元格已經失去焦點。可以透過如下方式主動結束編輯:
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
使用 Facade API 建立 Workbook 後,立即呼叫其它 API 不生效的情況
部分 API 依賴於介面渲染完成後才能正常工作。如果在 Workbook 建立後立即呼叫相關 API,可能因尚未完成渲染而失效。建議在生命週期的 Rendered 或 Steady 階段再進行相關操作:
const disposable = univerAPI.addEvent(univerAPI.Event.LifeCycleChanged, ({ stage }) => { if (stage === univerAPI.Enum.LifecycleStages.Steady) { // 程式碼... }})// 需要移除事件監聽時,可呼叫 disposable.dispose()參考:生命週期
你覺得這篇文檔如何?