權限控制

Univer 提供權限控制能力,用於限制使用者對工作簿、工作表、選區的操作。當使用者執行無權限動作時,Univer 會中止執行並提示缺失權限。常見場景如:對一片選區設定保護,限制協作者的編輯/檢視/複製等能力。

服務需要持久化保護規則與協作者變更,傳回目前使用者的權限,並傳遞請求失敗。傳回空清單的 mock 不具備持久化能力。協同情境下,後端仍須分別驗證讀取、JOIN 與修改權限,見身分與權限。前端保護與隱藏陰影不能取代伺服器授權。

權限服務整合

依任務跳轉到下方章節。本頁集中介紹基礎操作、進階範例、設定與疑難排解;完整 API 定義統一在 Reference 中維護。

核心概念

  • 作用範圍:權限可以作用在工作簿、工作表、選區三個層級。
  • 權限點位:每個功能對應一個權限點位,修改點位即可控制功能是否可用。
  • 保護規則:工作表和選區在設定權限點位前,需要先建立保護規則。

本地非持久化權限可直接修改權限點位;持久化整合見 權限服務整合

協同編輯場景下,更新權限點位會同步更新服務端狀態:

  • false:該權限點至少需要 owner 角色
  • true:該權限點至少需要 reader 角色

基礎示例

使用 allowedUsers 範例前,請將 user1、user2 替換為權限服務已傳回的真實協作者 ID。

下面按工作簿、工作表、選區三個層級展示最常見的權限設定方式。

工作簿權限程式碼示例

工作簿層級權限透過 Facade API 直接修改權限點位即可。

以編輯權限為例(其他功能只需替換權限點位,參考權限點位列表 - 工作簿):

TypeScript
const fWorkbook = univerAPI.getActiveWorkbook()if (!fWorkbook) throw new Error('No active workbook')const workbookPermission = fWorkbook.getWorkbookPermission()// 設定工作簿不可編輯await workbookPermission.setPoint(univerAPI.Enum.WorkbookPermissionPoint.Edit, false)

要點:

  • 工作簿權限點位可以直接設定,不需要建立保護規則。

工作表權限程式碼示例

工作表和選區相關的權限設定可以透過 Facade API 或命令系統實現。這裡以工作表編輯權限舉例,其他功能只需替換權限點位,參考權限點位列表 - 工作表。

TypeScript
const fWorkbook = univerAPI.getActiveWorkbook()if (!fWorkbook) throw new Error('No active workbook')const fWorksheet = fWorkbook.getActiveSheet()const worksheetPermission = fWorksheet.getWorksheetPermission()// 建立工作表保護, 允許指定使用者編輯const permissionId = await worksheetPermission.protect({  allowedUsers: ['user1', 'user2'],  name: 'My Worksheet Protection',})// 如果需要設定權限點位,必須先建立工作表保護await worksheetPermission.setPoint(univerAPI.Enum.WorksheetPermissionPoint.Edit, false)

刪除工作表權限

TypeScript
const fWorkbook = univerAPI.getActiveWorkbook()if (!fWorkbook) throw new Error('No active workbook')const fWorksheet = fWorkbook.getActiveSheet()const worksheetPermission = fWorksheet.getWorksheetPermission()// 刪除工作表保護await worksheetPermission.unprotect()

自訂選區權限程式碼示例

選區的權限同樣支援 API 和命令模式。這裡以選區編輯權限舉例,其他選區功能只需替換權限點位,參考權限點位列表 - 選區。

TypeScript
const fWorkbook = univerAPI.getActiveWorkbook()if (!fWorkbook) throw new Error('No active workbook')const fWorksheet = fWorkbook.getActiveSheet()const fRange = fWorksheet.getRange('A1:B2')const rangePermission = fRange.getRangePermission()// 設定區域保護權限,允許指定使用者編輯但不允許他人檢視const rule = await rangePermission.protect({  name: 'My protected range',  allowViewByOthers: false,  allowedUsers: ['user1', 'user2'],})console.log(rule)// 如果需要設定權限點位,必須先建立區域保護await rule.setPoint(univerAPI.Enum.RangePermissionPoint.Edit, false)await rule.setPoint(univerAPI.Enum.RangePermissionPoint.View, true)

刪除區域保護權限

TypeScript
const fWorkbook = univerAPI.getActiveWorkbook()if (!fWorkbook) throw new Error('No active workbook')const fWorksheet = fWorkbook.getActiveSheet()const fRange = fWorksheet.getRange('A1:B2')const rangePermission = fRange.getRangePermission()// 刪除區域内所有保護規則await rangePermission.unprotect()// 或刪除區域内指定規則const rules = await rangePermission.listRules()if (rules.length > 0) {  await rules[0].remove()}

常用任務

將活頁簿設為唯讀

TypeScript
const fWorkbook = univerAPI.getActiveWorkbook()if (!fWorkbook) throw new Error('No active workbook')const permission = fWorkbook.getWorkbookPermission()await permission.setMode('viewer')console.log(permission.getSnapshot())

管理保護範圍

TypeScript
const fWorkbook = univerAPI.getActiveWorkbook()if (!fWorkbook) throw new Error('No active workbook')const fWorksheet = fWorkbook.getActiveSheet()const permission = fWorksheet.getWorksheetPermission()const createdRules = await permission.protectRanges([  {    ranges: [fWorksheet.getRange('A1:B2')],    options: { name: 'Public area', allowViewByOthers: true },  },  {    ranges: [fWorksheet.getRange('C3:D4')],    options: { name: 'Private area', allowViewByOthers: false, allowedUsers: ['user1'] },  },])console.log(createdRules)const rules = await permission.listRangeProtectionRules()const firstRule = rules[0]if (firstRule) {  await firstRule.updateRanges([fWorksheet.getRange('A1:B3')])}

排查儲存格權限

TypeScript
const fWorkbook = univerAPI.getActiveWorkbook()if (!fWorkbook) throw new Error('No active workbook')const permission = fWorkbook.getActiveSheet().getWorksheetPermission()console.log(permission.debugCellPermission(0, 0))

權限點位列表

不同的功能權限由不同的權限點位控制,修改點位的值即可控制對應功能。具體點位程式碼請參閱這裡。

如果 workbook 的權限控制和 worksheet / range 有交叉,那麼必須全部為 true 才能使用。例如一個單元格的編輯權限必須 workbook 和 worksheet 的編輯權限都為 true 才能編輯。

工作簿

API 列舉對應權限點位類描述
univerAPI.Enum.WorkbookPermissionPoint.EditWorkbookEditablePermission能否編輯
univerAPI.Enum.WorkbookPermissionPoint.ViewWorkbookViewPermission能否檢視
univerAPI.Enum.WorkbookPermissionPoint.PrintWorkbookPrintPermission能否列印
univerAPI.Enum.WorkbookPermissionPoint.ExportWorkbookExportPermission能否匯出
univerAPI.Enum.WorkbookPermissionPoint.ShareWorkbookSharePermission能否分享
univerAPI.Enum.WorkbookPermissionPoint.CopyContentWorkbookCopyPermission能否複製
univerAPI.Enum.WorkbookPermissionPoint.DuplicateFileWorkbookDuplicatePermission能否複製文件
univerAPI.Enum.WorkbookPermissionPoint.CommentWorkbookCommentPermission能否評論
univerAPI.Enum.WorkbookPermissionPoint.ManageCollaboratorWorkbookManageCollaboratorPermission能否管理協作者
univerAPI.Enum.WorkbookPermissionPoint.CreateSheetWorkbookCreateSheetPermission能否建立工作表
univerAPI.Enum.WorkbookPermissionPoint.DeleteSheetWorkbookDeleteSheetPermission能否刪除工作表
univerAPI.Enum.WorkbookPermissionPoint.RenameSheetWorkbookRenameSheetPermission能否重新命名工作表
univerAPI.Enum.WorkbookPermissionPoint.MoveSheetWorkbookMoveSheetPermission能否移動工作表
univerAPI.Enum.WorkbookPermissionPoint.HideSheetWorkbookHideSheetPermission能否隱藏工作表
univerAPI.Enum.WorkbookPermissionPoint.CopySheetWorkbookCopySheetPermission能否複製工作表
univerAPI.Enum.WorkbookPermissionPoint.ViewHistoryWorkbookViewHistoryPermission能否檢視歷史記錄
univerAPI.Enum.WorkbookPermissionPoint.RecoverHistoryWorkbookRecoverHistoryPermission能否恢復歷史記錄
univerAPI.Enum.WorkbookPermissionPoint.CreateProtectionWorkbookCreateProtectPermission能否建立保護
univerAPI.Enum.WorkbookPermissionPoint.InsertRowWorkbookInsertRowPermission能否插入行
univerAPI.Enum.WorkbookPermissionPoint.InsertColumnWorkbookInsertColumnPermission能否插入列
univerAPI.Enum.WorkbookPermissionPoint.DeleteRowWorkbookDeleteRowPermission能否刪除行
univerAPI.Enum.WorkbookPermissionPoint.DeleteColumnWorkbookDeleteColumnPermission能否刪除列

工作表

API 列舉對應權限點位類描述
univerAPI.Enum.WorksheetPermissionPoint.EditWorksheetEditPermission能否編輯
univerAPI.Enum.WorksheetPermissionPoint.ViewWorksheetViewPermission能否檢視
univerAPI.Enum.WorksheetPermissionPoint.CopyWorksheetCopyPermission能否複製
univerAPI.Enum.WorksheetPermissionPoint.SetCellValueWorksheetSetCellValuePermission能否編輯單元格值
univerAPI.Enum.WorksheetPermissionPoint.SetCellStyleWorksheetSetCellStylePermission能否編輯單元格樣式
univerAPI.Enum.WorksheetPermissionPoint.SetRowStyleWorksheetSetRowStylePermission能否設定行樣式
univerAPI.Enum.WorksheetPermissionPoint.SetColumnStyleWorksheetSetColumnStylePermission能否設定列樣式
univerAPI.Enum.WorksheetPermissionPoint.InsertRowWorksheetInsertRowPermission能否插入行
univerAPI.Enum.WorksheetPermissionPoint.InsertColumnWorksheetInsertColumnPermission能否插入列
univerAPI.Enum.WorksheetPermissionPoint.DeleteRowWorksheetDeleteRowPermission能否刪除行
univerAPI.Enum.WorksheetPermissionPoint.DeleteColumnWorksheetDeleteColumnPermission能否刪除列
univerAPI.Enum.WorksheetPermissionPoint.SortWorksheetSortPermission能否排序
univerAPI.Enum.WorksheetPermissionPoint.FilterWorksheetFilterPermission能否篩選
univerAPI.Enum.WorksheetPermissionPoint.PivotTableWorksheetPivotTablePermission能否使用透視表
univerAPI.Enum.WorksheetPermissionPoint.InsertHyperlinkWorksheetInsertHyperlinkPermission能否使用超連結
univerAPI.Enum.WorksheetPermissionPoint.ManageCollaboratorWorksheetManageCollaboratorPermission能否管理協作者
univerAPI.Enum.WorksheetPermissionPoint.DeleteProtectionWorksheetDeleteProtectionPermission能否刪除保護
univerAPI.Enum.WorksheetPermissionPoint.EditExtraObjectWorksheetEditExtraObjectPermission能否編輯額外物件
univerAPI.Enum.WorksheetPermissionPoint.SelectProtectedCellsWorksheetSelectProtectedCellsPermission能否選取受保護儲存格
univerAPI.Enum.WorksheetPermissionPoint.SelectUnProtectedCellsWorksheetSelectUnProtectedCellsPermission能否選取未受保護儲存格

區域保護

API 列舉對應權限點位類描述
univerAPI.Enum.RangePermissionPoint.EditRangeProtectionPermissionEditPoint能否編輯保護區域
univerAPI.Enum.RangePermissionPoint.ViewRangeProtectionPermissionViewPoint能否檢視保護區域的內容
univerAPI.Enum.RangePermissionPoint.DeleteRangeProtectionPermissionDeleteProtectionPoint能否刪除保護區域
univerAPI.Enum.RangePermissionPoint.ManageCollaboratorRangeProtectionPermissionManageCollaPoint能否管理保護區域的協作者

權限介面設定

權限保護範圍陰影策略

若要區分目前使用者可編輯和不可編輯的保護區域,請使用 non-editable:可編輯的保護區域不顯示陰影,編輯權限遭停用的保護區域保留陰影;不可檢視的保護範圍仍保留遮罩。

此設定控制範圍保護和工作表保護的顯示,不會建立保護規則或修改編輯、檢視權限,也不會在未受保護的區域新增陰影。請先依上文設定保護規則和目前使用者的權限。

策略顯示效果
true / 'always'顯示所有保護區域的陰影(預設)。
'non-editable'隱藏可編輯保護區域的陰影,保留不可編輯區域的陰影。
'non-viewable'僅顯示不可檢視保護區域的陰影。
false / 'none'隱藏全部保護陰影,權限檢查仍然生效。

權限陰影示意

切換策略,比較同一組區域對目前使用者的顯示效果。

未保護

A1:B3

無陰影

已保護 · 可編輯

D1:E3

無陰影

已保護 · 唯讀

G1:H3

顯示陰影

已保護 · 不可檢視

J1:K3

顯示陰影

protectedRangeShadow: 'non-editable'

此示意只改變陰影,不改變權限。即使選擇 none,不可檢視的內容也不會顯示。

初始化時設定:

TypeScript
univer.registerPlugin(UniverSheetsUIPlugin, {  protectedRangeShadow: 'non-editable',})

也可以透過 API 動態修改:

下方 Facade API 會更新目前 Univer 執行個體中既有活頁簿的顯示策略。外掛模式下需先匯入 @univerjs/sheets-ui/facade;Sheets Core 預設已包含此匯入。

TypeScript
// 設定只顯示不可編輯範圍的陰影univerAPI.setProtectedRangeShadowStrategy('non-editable')// 獲取當前的權限保護範圍陰影顯示策略console.log(univerAPI.getProtectedRangeShadowStrategy())// 監聽權限保護範圍陰影顯示策略的變化const subscription = univerAPI.getProtectedRangeShadowStrategy$().subscribe((strategy) => {  console.log('Global strategy changed to:', strategy)  // 更新 UI 或執行其他操作})// 稍後,取消訂閱以進行清理subscription.unsubscribe()

自訂使用者元件

Univer 內建的自訂使用者元件所適配的場景比較有限,如果需要更復雜的自訂元件,可以透過以下方式進行自訂。

可在《自訂元件》檢視如何自訂元件。

TypeScript
univer.registerPlugin(UniverSheetsUIPlugin, {  protectedRangeUserSelector: {    /**     * custom component, should implement the `IPermissionDetailUserPartProps` interface.     */    component: CustomPermissionDetailUserPart,    /**     * The framework of the component. Must be passed correctly.     */    framework: 'react',  },})

在使用者選擇器的變更回呼中呼叫 setSelectUserList()。以下最小 React 範例清空已選使用者:useDependency 在元件內呼叫,服務狀態只在點擊後更新。完整選擇器請依 IPermissionDetailUserPartProps 實作。

TSX
import type { IPermissionDetailUserPartProps } from '@univerjs/sheets-ui'import type { FC } from 'react'import { SheetPermissionUserManagerService } from '@univerjs/sheets-ui'import { useDependency } from '@univerjs/ui'export const CustomPermissionDetailUserPart: FC<IPermissionDetailUserPartProps> = () => {  const service = useDependency(SheetPermissionUserManagerService)  const clearSelection = () => service.setSelectUserList([])  return <button type="button" onClick={clearSelection}>清空已選使用者</button>}

去除權限彈窗

TypeScript
univerAPI.setPermissionDialogVisible(false)

權限服務整合

拓展使用

當你需要在自己的外掛中增加權限校驗時,可以直接操作權限點位。

下面以 WorkbookEditablePermission 為例,其他點位類似:

TypeScript
import { IPermissionService } from '@univerjs/core'import { WorkbookEditablePermission } from '@univerjs/sheets'class YourService {  constructor(@IPermissionService private _permissionService: IPermissionService) {  }  setWorkbookNotEditable() {    this._permissionService.updatePermissionPoint(new WorkbookEditablePermission('unitId').id, false)  }  setWorkbookEditable() {    this._permissionService.updatePermissionPoint(new WorkbookEditablePermission('unitId').id, true)  }}

權限點位列表

第三方外掛如何擴充權限點位

如果你需要自訂權限點位,可以實現 IPermissionPoint 並註冊到權限服務中:

TypeScript
import type { IPermissionPoint } from '@univerjs/core'import { IPermissionService, PermissionStatus } from '@univerjs/core'import { UnitAction, UnitObject } from '@univerjs/protocol'export class CustomPermissionPoint implements IPermissionPoint {  type = UnitObject.Unkonwn // your type  subType = UnitAction.View // your subType  status = PermissionStatus.INIT  value = true // 權限的初始值  id: string  constructor(unitId: string, subUnitId: string, customId: string) {    // 這裡自行拼湊一個 id,id 屬性需要保證在整個 IPermissionService 中是唯一的憑證。    this.id = `${unitId}.${subUnitId}.${customId}`  }}class YourService {  constructor(@IPermissionService private _permissionService: IPermissionService) {    this._init()  }  _init() {    this._permissionService.addPermissionPoint(new CustomPermissionPoint('unitId', 'subUnitId', 'my-id'))  }}// 在其他地方如何使用class ConsumeService {  constructor(@IPermissionService private _permissionService: IPermissionService) {  }  doSomething() {    const point = this._permissionService.getPermissionPoint(new CustomPermissionPoint('unitId', 'subUnitId', 'my-id').id)    console.log(point?.value)  }  bindEvent() {    // 這將獲得一個 Rx 物件,使得你能夠監聽當前權限的變化作出一些改變    const point$ = this._permissionService.getPermissionPoint$(new CustomPermissionPoint('unitId', 'subUnitId', 'my-id').id)    console.log(point$)  }}

第三方權限服務接入(進階用法)

在業務應用中實作 IAuthzIoService,將權限、角色與協作者方法接入後端。以下範例假定 ./authorization-service 已將該實作匯出為 YourAuthzService。請在建立活頁簿前註冊,並保留其他初始化選項與外掛註冊。

TypeScript
import { IAuthzIoService, Univer } from '@univerjs/core'import { YourAuthzService } from './authorization-service'const univer = new Univer({  override: [[IAuthzIoService, { useClass: YourAuthzService }]],})

服務需要持久化保護規則與協作者變更,傳回目前使用者的權限,並傳遞請求失敗。傳回空清單的 mock 不具備持久化能力。協同情境下,後端仍須分別驗證讀取、JOIN 與修改權限,見身分與權限。前端保護與隱藏陰影不能取代伺服器授權。

協作者管理

協作者管理由業務應用程式和權限服務負責。請接入自己的使用者與 ACL 模型,在伺服器端分別檢查讀取、JOIN 和修改權限,見身分與權限。下方前端 API 需要匹配的權限服務實作,不會自動設定伺服器端權限。

  • 獲取協作者列表
TypeScript
const fWorkbook = univerAPI.getActiveWorkbook()if (!fWorkbook) throw new Error('No active workbook')const workbookPermission = fWorkbook.getWorkbookPermission()const collaborators = await workbookPermission.listCollaborators()console.log(collaborators)
  • 新增協作者
TypeScript
const fWorkbook = univerAPI.getActiveWorkbook()if (!fWorkbook) throw new Error('No active workbook')const workbookPermission = fWorkbook.getWorkbookPermission()// 一次新增多個協作者await workbookPermission.setCollaborators([  {    user: { userID: 'user1', name: 'John Doe', avatar: 'https://...' },    role: univerAPI.Enum.UnitRole.Editor,  },  {    user: { userID: 'user2', name: 'Jane Smith', avatar: '' },    role: univerAPI.Enum.UnitRole.Reader,  },])// 新增單個協作者await workbookPermission.addCollaborator(  { userID: 'user1', name: 'John Doe', avatar: 'https://...' },  univerAPI.Enum.UnitRole.Editor,)
  • 更新協作者角色
TypeScript
const fWorkbook = univerAPI.getActiveWorkbook()if (!fWorkbook) throw new Error('No active workbook')const workbookPermission = fWorkbook.getWorkbookPermission()await workbookPermission.updateCollaborator(  { userID: 'user1', name: 'John Doe Updated', avatar: 'https://...' },  univerAPI.Enum.UnitRole.Reader,)
  • 刪除協作者
TypeScript
const fWorkbook = univerAPI.getActiveWorkbook()if (!fWorkbook) throw new Error('No active workbook')const workbookPermission = fWorkbook.getWorkbookPermission()// 刪除多個協作者await workbookPermission.removeCollaborators(['user1', 'user2'])// 刪除單個協作者await workbookPermission.removeCollaborator('user1')

Reference

你覺得這篇文檔如何?

© 2026 DreamNum Co., Ltd.