如果想在 V2EX 获得更好的推广效果,欢迎了解 PRO 会员机制:
https://www.v2ex.com/pro/about

如果你经常使用铜币置顶主题,持有 V2EX Solana Token 会在每日签到时获得额外铜币:
https://www.v2ex.com/solana
GrapeCityChina
V2EX  ›  推广

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

  •  
  •   GrapeCityChina · Apr 3, 2020 · 1147 views
    This topic created in 2260 days ago, the information mentioned may be changed or developed.

    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 中查看效果。

    No Comments Yet
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2872 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 44ms · UTC 15:18 · PVG 23:18 · LAX 08:18 · JFK 11:18
    ♥ Do have faith in what you're doing.