找回密码
 立即注册

QQ登录

只需一步,快速开始

Clark.Pan 讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于:2023-6-29 18:56  /   查看:1844  /  回复:0
需求:


1.在线表格编辑器中实现批量插入功能(批量插入10行,50行,100行)
2.插入后支持复制之前的样式及公式。
3.插入的操作支持撤销和重做。

实现:

实现批量插入功能:
首先需要对右键菜单做自定制:
我们先做一个批量插入的菜单组:
  1. config.commandMap.batchInsertRowContextMenu = {
  2.   text: '批量插入',
  3.   commandName: "batchInsertRowContextMenu",
  4.   visibleContext: "ClickRowHeader",
  5.   subCommands: [
  6.     "batchInsertRows10",
  7.     "batchInsertRows50",
  8.     "batchInsertRows100"
  9.   ]
  10.                         };
复制代码
该菜单组包含三个菜单,分别为插入10行,50行和100行。
下面构建每个菜单的command:
  1. config.commandMap.batchInsertRows10 = {
  2.   text: '插入 10 行',
  3.   commandName: "batchInsertRows10",
  4.   execute: async (context, propertyName, fontItalicChecked) => {
  5.                                        
  6.   }
  7.                         };

  8.                         config.commandMap.batchInsertRows50 = {
  9.   text: '插入 50 行',
  10.   commandName: "batchInsertRows50",
  11.   execute: async (context, propertyName, fontItalicChecked) => {
  12.                                
  13.   }
  14.                         };

  15.                         config.commandMap.batchInsertRows100 = {
  16.   text: '插入 100 行',
  17.   commandName: "batchInsertRows100",
  18.   execute: async (context, propertyName, fontItalicChecked) => {

  19.   }
  20.                         };
复制代码
这里面的execute为菜单点击之后的执行逻辑,留到与后续需求一起完成。
以上就构建好了菜单的雏形,效果如下:
image.png458231200.png
2.插入后支持复制之前的样式及公式。
SpreadJS只提供了插入功能,但是用户习惯像Excel一样,插入之后复制上一行的样式及公式。这个时候就需要对已有的插入进行改造。
又由于插入的操作需要支持撤销和重做,所以需要封装命令来完成:
创建一个命令,在命令中进行插入,并且通过clipboardPaste命令进行复制(该命令在批量复制操作的情况下性能优于copyto)
  1. config.commandMap["gc.spread.contextMenu.insertRows"] = {
  2.   commandName: "myInsertRows",
  3.   enableContext: "AllowInsertRows && selectFullRows",
  4.   text: "插入",
  5.   visibleContext: "ClickRowHeader && !AllowInsertCopiedCutCells",
  6.   execute: async (context, propertyName) => {
  7.     var commandManager = context.Spread.commandManager();
  8.     commandManager.execute({cmd: "insertRowAndCopyContent", sheetName: context.Spread.getActiveSheet().name(),rowCount:1});       
  9.   }
  10.                         };
复制代码
  1. var commandManager = spread.commandManager();
  2.                         var insertRowAndCopyContent = {
  3.   canUndo: true,
  4.   execute: function (context, options, isUndo) {
  5.     var Commands = GC.Spread.Sheets.Commands;
  6.     options.cmd = "insertRowAndCopyContent";
  7.     if (isUndo) {
  8.       Commands.undoTransaction(context, options);
  9.       return true;
  10.     } else {
  11.       Commands.startTransaction(context, options);
  12.       context.suspendPaint();
  13.       context.suspendEvent();
  14.       var sheet = context.getSheetFromName(options.sheetName);
  15.       var selections = sheet.getSelections();
  16.                                                
  17.       for(var i = 0; i < selections.length; i++){
  18.         var row = selections[i].row;
  19.         sheet.addRows(row,options.rowCount);
  20.         var fromRange = [new GC.Spread.Sheets.Range(row + options.rowCount, 0, 1, sheet.getColumnCount())];
  21.         var toRanges = [new GC.Spread.Sheets.Range(row, 0, options.rowCount, sheet.getColumnCount())];
  22.         spread.commandManager().execute({cmd: "clipboardPaste", sheetName: options.sheetName, fromSheet: sheet, fromRanges: fromRange, pastedRanges: toRanges, isCutting: false, clipboardText: "", pasteOption: GC.Spread.Sheets.ClipboardPasteOptions.formulasAndFormatting});
  23.       }
  24.                                                
  25.       context.resumeEvent();
  26.       context.resumePaint();
  27.       Commands.endTransaction(context, options);
  28.       return true;
  29.     }
  30.   }
  31.                         };
  32.                         var commandManager = spread.commandManager();
  33.                         commandManager.register("insertRowAndCopyContent", insertRowAndCopyContent);
复制代码
这里将rowCount参数提了出来,为了方便批量插入能够公用。同理批量插入的execute也是调用上述的命令指示传入的rowCount参数不同。例如插入10行:
  1. config.commandMap.batchInsertRows10 = {
  2.   text: '插入 10 行',
  3.   commandName: "batchInsertRows10",
  4.   execute: async (context, propertyName, fontItalicChecked) => {
  5.     var commandManager = context.Spread.commandManager();
  6.     commandManager.execute({cmd: "insertRowAndCopyContent", sheetName: context.Spread.getActiveSheet().name(),rowCount:10});       
  7.   }
  8.                         };
复制代码

完整demo见附件:

purejs.zip

2.6 MB, 下载次数: 202

0 个回复

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