权限控制

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.