近期有几位朋友同时咨询这个需求,本文就这个问题的原理和实现方案在此详细描述一下。
要解释清楚这个问题,需要咱们先了解以下几个前提:
一、JS语言本身访问系统剪贴板的权限
JS语言本身,受语言规则(或是浏览器安全规则)所限,访问、操作系统剪贴板的限制
比较多,具体参考:https://juejin.im/post/5bbb2870e51d450e853050e0
二、SpreadJS无法通过除Ctrl + C / V 之外的方式与本地Excel交互数据。
不难理解,实际上纯JS实现的SpreadJS默认不支持通过右键菜单“复制”、copy命令
或接口实现将内部数据写入系统剪贴板的。那为什么Ctrl + C、Ctrl+V可以实现内外部
数据的相互粘贴呢?这是由于Ctrl+C与Ctrl+V是浏览器留给JS程序的一个“窗口”,而
且这个窗口期很短,且有一些规则限制。
在SpreadJS中,除文件IO接口外,这是与本地数据交互的唯一方式。
三、具体实现
了解了其中原理,我们知道,不想让用户把表格数据导出到本地,除了不给用户提供
IO接口外,只剩下切断与系统剪贴板的交互这一种办法了。
1、禁用SpreadJS所在hostElement的Ctrl+C/V的事件
- // 1、禁用ctrl+c ctrl+v功能
- document.getElementById('ss').onkeydown = function(){
- if (event.ctrlKey && (window.event.keyCode==67 || window.event.keyCode==86)){
- alert("禁止:" + window.event.keyCode);
- return false;
- }
- }
复制代码 SpreadJS默认会监听浏览器的C/V事件,先禁用这里的事件。
2、用自定义copy命令,替换掉默认的copy命令
- // 2、重写copy命令
- spread.commandManager().register("myCopy",
- {
- canUndo: true,
- execute: function (context, options, isUndo) {
- setTimeout(function(){
- options.cmd = "copy";
- spread.commandManager().execute(options);
- options.cmd = "myCopy";
- },10);
- }
- });
-
- // 设置快捷键Ctrl + C
- spread.commandManager().setShortcutKey(
- "copy", null, false, false, false, false
- );
- spread.commandManager().setShortcutKey(
- "myCopy", GC.Spread.Commands.Key.c, true, false, false, false
- );
复制代码 请注意自定义copy命令中setTimeout的使用,这里实际上是为了规避掉访问系统剪贴板的“窗口”
3、用自定义Paste命令,替换掉默认的paste命令
- // 3、重写paste命令
- spread.commandManager().register("myPaste",
- {
- canUndo: true,
- execute: function (context, options, isUndo) {
- //内部粘贴逻辑
- var innerPaste = "paste";
- options.cmd = innerPaste;
- // 设置setTimeout,让开时间窗口,否则SpreadJS会自动粘贴外部内容。
- setTimeout(function(){
- spread.commandManager().execute(options);
- },10);
- }
- });
- // 设置快捷键Ctrl + V
- spread.commandManager().setShortcutKey(
- "paste", null, false, false, false, false
- );
- spread.commandManager().setShortcutKey(
- "myPaste", GC.Spread.Commands.Key.v, true, false, false, false
- );
复制代码
完整的Demo请参考附件【重写CopyPast命令实现内部复制粘贴.html】
|
|