找回密码
 立即注册

QQ登录

只需一步,快速开始

dexteryao 讲师达人认证 悬赏达人认证 SpreadJS 开发认证

超级版主

123

主题

8927

帖子

1万

积分

超级版主

Rank: 8Rank: 8

积分
13536

讲师达人悬赏达人元老葡萄SpreadJS 认证SpreadJS 高级认证微信认证勋章

dexteryao 讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于:2022-11-21 11:07  /   查看:1269  /  回复:0
本帖最后由 dexteryao 于 2022-11-30 14:03 编辑

由于浏览器安全性策略,使用Javascript代码操作系统剪切板有这诸多限制,在非浏览器复制粘贴事件中,无法直接获取和设置剪切板的内容。SpreadJS右键菜单(Content Menu)中的复制粘贴是普通的click行为,因此也是无法操作系统剪切板的,使用右键菜单只能做SpreadJS当前workbook中的复制粘贴(称之为内部粘贴)。结果就是当您从Excel中复制了数据,在SpreadJS中点击右键粘贴,无法将Excel中的内容复制过来(这种称之为外部粘贴),外部粘贴只能通过键盘c + v来实现。

好消息是部分浏览器开放 Clipboard 接口,在用户授权或者安装插件的情况下,普通事件中的Javascript代码可以通过Clipboard API获取和设置剪切板内容了。

SpreadJS V16 增强了剪切板事件,通过事件中提供的信息,可以实现更多的粘贴复制功能,比如选择性粘贴,结合Clipboard API 实现外部粘贴。

在ClipboardChanging, ClipboardPasting, ClipboardPasted事件中增加了action参数。
GC.Spread.Sheets.ClipboardActionType 是一个枚举项


  1. export enum ClipboardActionType {
  2.     /**
  3.      * Indicates a copy action
  4.      */
  5.     copy = 1,
  6.     /**
  7.      * Indicates a cut action
  8.      */
  9.     cut = 2,
  10.     /**
  11.      * Indicates a reset action, the clipboard is reset at this point
  12.      */
  13.     reset = 3
  14. }
复制代码




当用户通过快捷键或右键菜单进行复制和前切时会触发action为copy和cut的事件,当用户按下esc或者编辑单元格、区域会清除复制数据并处罚action为reset的事件,reset标志着工作表中没有绿色虚线标记的复制区域提示。有了剪切板action在结合其他事件以及浏览器提供的Clipboard API,对于想对复制粘贴行为进行深度定制的用户来说就可以灵活操作了。

实践案例
     1. 实现内部选择性粘贴的精准控制


  1. let clipboardHelper = {}
  2. spread.bind(GC.Spread.Sheets.Events.ClipboardChanging, function (s, e) {
  3.     if(e.action === GC.Spread.Sheets.ClipboardActionType.reset){
  4.         clipboardHelper = {}
  5.     }
  6.     else{
  7.         clipboardHelper.copiedSheet = e.sheet;
  8.         clipboardHelper.copiedRanges = e.ranges;
  9.         clipboardHelper.copiedObjects = e.objects;
  10.         clipboardHelper.isCutting = e.isCutting;
  11.     }
  12. });
复制代码




通过使用clipboardHelper可以实时记录内部剪切板变化情况,根据用户复制内容,以及选择区域精确的给出可粘贴内容

        2. 同步系统剪切板

结合Clipboard API ,将SpreadJS剪切板内容同步系统剪切板。

  1. spread.bind(GC.Spread.Sheets.Events.ClipboardChanging, async function(s, e){
  2.     console.log(s, e);
  3.     const { state } = await navigator.permissions.query({
  4.         name: "clipboard-write"
  5.     });
  6.     console.log(state)
  7.     if(state === "granted"){
  8.         let data = [];
  9.         if(e.action === GC.Spread.Sheets.ClipboardActionType.reset){
  10.             // 清楚剪切板内容
  11.             data.push(new ClipboardItem({ "text/plain": new Blob([""], { type: "text/plain" }) }))
  12.         }
  13.         else if(e.copyData && e.copyData.text){
  14.             // 设置文本到剪切板
  15.             data.push(new ClipboardItem({ "text/plain": new Blob([e.copyData.text], { type: "text/plain" }) }))
  16.         }
  17.         navigator.clipboard.write(data).then(function() {
  18.             /* success */
  19.             console.log("success");
  20.         }, function() {
  21.             /* failure */
  22.             console.log("failure", arguments);
  23.         });
  24.     }
  25. });
复制代码


类似也可以在ClipboardPasting中navigator.clipboard.read读取剪切板信息,结合clipboardHelper 实现内外部的混合粘贴。

0 个回复

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