请选择 进入手机版 | 继续访问电脑版
 找回密码
 立即注册

QQ登录

只需一步,快速开始

Winny
超级版主   /  发表于:2025-3-28 12:30  /   查看:71  /  回复:0
本帖最后由 Winny 于 2025-3-28 13:46 编辑

需求背景:在填报项目中,经常会遇到不同客户需要编辑同一个表的不同区域,在SpreadJS V18以前,通过表单保护结合单元格tag就可以实现,具体可以参考示例贴:
SpreadJS特定区域数据保护。这个方案的优势在于功能设置上与Excel中的能力完全相同,可以兼容导入导出。但缺点在于设计过于复杂,需要两步执行。
SpreadJS V18中,推出了allowEditInCell API,通过一行代码即可实现控制哪些区域单元格可以编辑。本文将该功能和用户结合,实现一个简单的编辑权限控制。

实现方案:
1. 自定义右键菜单,在右键菜单中弹出用户组织
  1. function customeMenu(designer) {
  2.                 // 自定义右键菜单
  3.                 let config = JSON.parse(JSON.stringify(GC.Spread.Sheets.Designer.DefaultConfig))

  4.                 let selectEditUser = {
  5.                     "text": "选择编辑人",
  6.                     commandName: "selectEditUser",
  7.                     execute: (context) => {
  8.                         // context代表的是designer对象
  9.                         let modal = document.getElementById("modal")
  10.                         modal.style.display = "flex"
  11.                     }
  12.                 }
  13.                 // 追加自定义命令
  14.                 config.contextMenu.unshift("selectEditUser")
  15.                 config.commandMap = {
  16.                     selectEditUser
  17.                 }

  18.                 return config
  19.             }
复制代码

2. 选中目标区域,设计填写范围
在这里,我们对不同角色的用户,将其能编辑的范围写入了名称管理器中。
  1.   document.getElementById("confirmEditUser").onclick = () => {
  2.                 let modal = document.getElementById("modal")
  3.                 // 获取当前选中的radio
  4.                 let selected = document.querySelector('input[name="user"]:checked')
  5.                 if (!selected) {
  6.                     alert("尚未分配用户")
  7.                 } else {
  8.                     let user = selected.value
  9.                     //获取当前激活的sheet中选中的区域,这里为方便,只拿第一个选中区域
  10.                     let spread = designer.getWorkbook()
  11.                     let sheet = spread.getActiveSheet()
  12.                     let selection = sheet.getSelections()[0]
  13.                     let rangeString = GC.Spread.Sheets.rangeToFormula(selection, 0, 0, GC.Spread.Sheets.CalcEngine.RangeReferenceRelative.allRelative)
  14.                     // 名称管理不允许重名,如果已经添加过提示需要更新,而不是添加
  15.                     if (sheet.getCustomName(user)) {
  16.                         let isUpdate = confirm("该用户已经设置过编辑区域,是否需要更新?")
  17.                         if (isUpdate) {
  18.                             sheet.removeCustomName(user)
  19.                             sheet.addCustomName(user, rangeString, 0, 0, `${user}编辑区域`);
  20.                             alert("更新成功")
  21.                             modal.style.display = "none"
  22.                         } else {
  23.                             alert("取消更新")
  24.                         }
  25.                     } else {
  26.                         sheet.addCustomName(user, rangeString, 0, 0, `${selected.name}编辑区域`);
  27.                         alert("添加成功")
  28.                         modal.style.display = "none"
  29.                     }
  30.                 }
  31.             }
复制代码
3. 切换用户,根据名称管理器区域信息,设置编辑条件。
  1. select.addEventListener('change', function () {
  2.                     const selectedOption = this.options[this.selectedIndex];
  3.                     /***
  4.                      切换用前,先保存上个用户编辑记录,对于管理员多有单元格可以编辑,
  5.                      其它权限用户根据配置的区域走
  6.                     **/
  7.                     let spread = designer.getWorkbook()
  8.                     let sheet = spread.getActiveSheet()   // demo只处理了一个sheet,实际业务根据sheet数量循环去处理即可
  9.                     sheet.suspendPaint()
  10.                     if (selectedOption.dataset.editRange === 'all') {
  11.                         designer.setConfig(customeConfig)
  12.                         sheet.getRange(0,0,sheet.getRowCount(),sheet.getColumnCount()).allowEditInCell(true)
  13.                     } else {
  14.                         designer.setConfig(JSON.parse(JSON.stringify(GC.Spread.Sheets.Designer.DefaultConfig)))
  15.                         let editRange = selectedOption.dataset.editRange
  16.                         let customeName = sheet.getCustomName(editRange)
  17.                         if (customeName) {
  18.                             let customeRef = customeName.getExpression()
  19.                             let { row, column, endRow, endColumn } = customeRef
  20.                             sheet.getRange(0,0,sheet.getRowCount(),sheet.getColumnCount()).allowEditInCell(false)
  21.                             sheet.getRange(row, column, endRow - row+1, endColumn - column+1).allowEditInCell(true)
  22.                         } else {
  23.                             sheet.getRange(0,0,sheet.getRowCount(),sheet.getColumnCount()).allowEditInCell(false)
  24.                         }
  25.                     }
  26.                     sheet.resumePaint()
  27.                 });
复制代码


详细的示例工程和操作教程,参考附件文件。



编辑权限设置.zip

2.54 MB, 下载次数: 5

0 个回复

您需要登录后才可以回帖 登录 | 立即注册
返回顶部