找回密码
 立即注册

QQ登录

只需一步,快速开始

KevinChen 讲师达人认证 悬赏达人认证 SpreadJS 开发认证
论坛元老   /  发表于:2020-7-27 16:51  /   查看:3292  /  回复:0
近期有几位朋友同时咨询这个需求,本文就这个问题的原理和实现方案在此详细描述一下。
要解释清楚这个问题,需要咱们先了解以下几个前提:

一、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.   // 1、禁用ctrl+c ctrl+v功能
  2.                 document.getElementById('ss').onkeydown = function(){
  3.                         if (event.ctrlKey && (window.event.keyCode==67 || window.event.keyCode==86)){
  4.                                 alert("禁止:" + window.event.keyCode);
  5.                                 return false;
  6.                         }
  7.                 }
复制代码
SpreadJS默认会监听浏览器的C/V事件,先禁用这里的事件。

2、用自定义copy命令,替换掉默认的copy命令
  1.   // 2、重写copy命令
  2.                 spread.commandManager().register("myCopy",
  3.             {
  4.                 canUndo: true,
  5.                 execute: function (context, options, isUndo) {
  6.                                         setTimeout(function(){
  7.                                                 options.cmd = "copy";
  8.                                                 spread.commandManager().execute(options);
  9.                                                 options.cmd = "myCopy";
  10.                                         },10);
  11.                 }
  12.             });
  13.                        
  14.                 // 设置快捷键Ctrl + C
  15.         spread.commandManager().setShortcutKey(
  16.             "copy", null, false, false, false, false
  17.         );
  18.         spread.commandManager().setShortcutKey(
  19.             "myCopy", GC.Spread.Commands.Key.c, true, false, false, false
  20.         );
复制代码
请注意自定义copy命令中setTimeout的使用,这里实际上是为了规避掉访问系统剪贴板的“窗口”

3、用自定义Paste命令,替换掉默认的paste命令
  1.   // 3、重写paste命令
  2.                 spread.commandManager().register("myPaste",
  3.             {
  4.                 canUndo: true,
  5.                 execute: function (context, options, isUndo) {
  6.                                         //内部粘贴逻辑
  7.                                         var innerPaste = "paste";
  8.                                         options.cmd = innerPaste;
  9.                                         // 设置setTimeout,让开时间窗口,否则SpreadJS会自动粘贴外部内容。
  10.                                         setTimeout(function(){
  11.                                                 spread.commandManager().execute(options);
  12.                                         },10);
  13.                 }
  14.             });
  15.                 // 设置快捷键Ctrl + V
  16.         spread.commandManager().setShortcutKey(
  17.             "paste", null, false, false, false, false
  18.         );
  19.         spread.commandManager().setShortcutKey(
  20.             "myPaste", GC.Spread.Commands.Key.v, true, false, false, false
  21.         );
复制代码


完整的Demo请参考附件【重写CopyPast命令实现内部复制粘贴.html】

重写CopyPast命令实现内部复制粘贴.html

2.98 KB, 下载次数: 80

0 个回复

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