V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
GrapeCityChina
V2EX  ›  推广

在离线填报的场景下,用 SpreadJS 完成权限控制

  •  
  •   GrapeCityChina · 2020-04-03 14:48:21 +08:00 · 786 次点击
    这是一个创建于 1730 天前的主题,其中的信息可能已经有所发展或是发生改变。

    SpreadJS ,作为一款基于 HTML5 的纯前端电子表格控件,兼容 450 种以上的 Excel 公式,可为用户带来亲切的 Excel 使用体验,并可满足企业 IT 部门 Web Excel 组件开发、数据填报、Excel 类报表设计、表格文档协同编辑等业务场景。

    离线填报,作为数据填报的典型应用场景之一,可以让业务人员在生产环境中,随时随地随心的完成填报工作,而不受限于网络。

    离线填报的一般实现流程是:

    1. 输出 HTML 离线报表

    2. 非网络环境下进行数据填报

    3. 联网后,再进行数据提交

    因为涉及到异步操作的过程,需要对离线填报人员做出权限控制,这个时候密码保护就显得尤为重要了。

    SpreadJS 作为一款在线 Excel 编辑控件,目前仅支持工作簿密码保护,暂不支持工作表密码保护功能。不过 SpreadJS 在设计之初,为了保持对 Excel 最大的兼容度,在将 Excel 的工作表导入时,密码相关部分也会保存进 SpreadJS 的 ssjson 中,通过 spread.toJSON() 的序列化之后,我们也可以正常使用密码保护功能,序列化的 Json 文件如下图所示:

    image.png

    上图中红框所示部分就是工作表的密码保护以及设置的密码字符串。

    我们只要将这一部分保留,就可以在我们设计的 Excel 模板上添加对应的工作表保护。

    请注意,由于 Excel 本身会将密码进行一次加密,所以我们无法直接修改 json 中的对应的键值来更改成我们想要的明文密码,所以我们需要预先导入一次我们设置好对应密码的 Excel,用来提取密码的相关信息。

    可以按照下面的演示进行操作:

    1. 首先导入一个空 Excel,给对应的工作表设置对应的密码保护

    image.png

    1. 将该 Excel 导入到 SpreadJS 中,然后通过 spread.toJSON()来获取整个 json,通过代码找到对应的密码保护相关设置:
    var json = spread.toJSON()
    
    var protectOptions = json.sheets.Sheet1.protectionOptions
    

    这里由于 Excel 中默认是在 Sheet1 这个工作簿上设置的密码保护,所以需要用 json.sheets.Sheet1.protectionOptions 来获取对应的 protectOptions 设置,并将其暂时存储在变量中以备后用。

    1. 接下来我们正常设计填报模板。

    填报模板的设计原理是相同的,但设计方法不同,尤其体现在桌面设计器和在线表格编辑器中,这一点需要注意。

    填报模板的设计原理:将临时保存的 protectOptions merge 到最终生成的 ssjson 中。( SpreadJS 的 ExcelIO 导出 Excel 时需要使用 spread 序列化 toJSON 生成的 ssjson,因此通过 js 操作,我们就可以将之前临时保存的 protectOptions merge 进去。)

    由于在设计表单保护时勾选的操作也会更改 protectionOptions,如果单纯替换就会导致设计模板时候设置的表单保护选项丢失,例如:我们在设计模板的时候勾选了调整行列大小,如下所示:

    image.png 此时,protectOptions 中会记录

    image.png

    如果我们将之前临时保存的 protectOptions 直接替换,那么上述设置就会丢失。

    所以这里需要如下操作:

    首先,将目前的 protectOptions 临时保存:

    var tempProtectOptions = json.sheets.Sheet1.protectionOptions
    

    然后,替换为之前带有密码的 protectOptions:

    json.sheets.Sheet1.protectionOptions = protectOptions
    

    之后,将 tempProtectOptions 里面的内容 merge 进去:

    <div>json.sheets.Sheet1.protectionOptions.allowResizeRows = true;</div>
    
    <div>json.sheets.Sheet1.protectionOptions.allowResizeColumns = true;</div>
    

    最后,将调整之后的 ssjson 交给 ExcelIO 进行导出:

    
    <div>
    
     <span style="color: rgb(51, 51, 51); font-family: monospace, monospace; font-size: 16px; white-space: pre; background-color: rgb(248, 248, 248);"> excelio.save(json, </span><span class="hljs-function" style="box-sizing: inherit; color: rgb(51, 51, 51); font-family: monospace, monospace; font-size: 16px; white-space: pre;"><span class="hljs-keyword" style="box-sizing: inherit; font-weight: 700;">function</span> (<span class="hljs-params" style="box-sizing: inherit;">blob</span>) </span><span style="color: rgb(51, 51, 51); font-family: monospace, monospace; font-size: 16px; white-space: pre; background-color: rgb(248, 248, 248);">{
    
     </span><span style="color: rgb(51, 51, 51); font-family: monospace, monospace; font-size: 16px; white-space: pre; background-color: rgb(248, 248, 248);">
    
     },
    
     </span><span class="hljs-function" style="box-sizing: inherit; color: rgb(51, 51, 51); font-family: monospace, monospace; font-size: 16px; white-space: pre;"><span class="hljs-keyword" style="box-sizing: inherit; font-weight: 700;">function</span> (<span class="hljs-params" style="box-sizing: inherit;">e</span>) </span><span style="color: rgb(51, 51, 51); font-family: monospace, monospace; font-size: 16px; white-space: pre; background-color: rgb(248, 248, 248);">{</span><span style="color: rgb(51, 51, 51); font-family: monospace, monospace; font-size: 16px; white-space: pre; background-color: rgb(248, 248, 248);">
    
     </span><span class="hljs-built_in" style="box-sizing: inherit; color: rgb(0, 134, 179); font-family: monospace, monospace; font-size: 16px; white-space: pre;">console</span><span style="color: rgb(51, 51, 51); font-family: monospace, monospace; font-size: 16px; white-space: pre; background-color: rgb(248, 248, 248);">.log(e);
    
     });
    
     </span>
    
    </div>
    
    

    此时,导出的 Excel 中就会带有密码了,密码就是之前导入 Excel 中设置的密码,这样在离线填报时候就可以控制填报人员的操作权限了,填报人员也无法对有密码保护的文件进行修改。

    以上,就是 SpreadJS 在离线填报的场景下,实现密码权限控制的方法,您可以在SpreadJS 的在线表格编辑器 完成密码设置,并导入 Excel 中查看效果。

    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1974 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 16:14 · PVG 00:14 · LAX 08:14 · JFK 11:14
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.