admin 发表于 2019-3-13 14:04:33

SpreadJS 自定义“右键插入”功能

<div class="post-content new-post">
<p>Spread JS
V11开始已有了原生右键菜单,右键菜单中的项可以灵活的自定义(参考<em>扩展上下文菜单</em>)。当现有的菜单不满足我们需求时候,我们可以通过自定义Command的方式拓展功能。</p>
<p>在Excel中我们常用的一个操作是插入行,并希望在插入行后自动复制上一行的样式,合并单元格,那么以这个需求为例,讲解如何重定义现有插入菜单</p>
<ol>
<li><p>定义插入复制样式insertRowsCopyStyle命令。</p>
<p>Command中使用Transaction实现Undo和Redo,exectue时先调用原有“gc.spread.contextMenu.insertRows”命令插入行,然后复制插入行前样式。</p>
<pre class="hljs javascript"><code><code class="lang-js"><span class="hljs-keyword">var</span> insertRowsCopyStyle = {
    <span class="hljs-attr">canUndo</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">name</span>: <span class="hljs-string">"insertRowsCopyStyle"</span>,
    <span class="hljs-attr">execute</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">context, options, isUndo</span>) </span>{
      <span class="hljs-keyword">var</span> Commands = GC.Spread.Sheets.Commands;
      <span class="hljs-keyword">if</span> (isUndo) {
            Commands.undoTransaction(context, options);
            <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
      } <span class="hljs-keyword">else</span> {
            Commands.startTransaction(context, options);
            <span class="hljs-keyword">var</span> sheet = context.getSheetFromName(options.sheetName);
            sheet.suspendPaint();
            options.cmd = <span class="hljs-string">"gc.spread.contextMenu.insertRows"</span>
            context.commandManager().execute(options);
            options.cmd = <span class="hljs-string">"insertRowsCopyStyle"</span>;

            <span class="hljs-keyword">var</span> beforeRowCount = <span class="hljs-number">0</span>;
            <span class="hljs-keyword">if</span> (options.selections &amp;&amp; options.selections.length) {
                <span class="hljs-keyword">var</span> selections = getSortedRowSelections(options.selections)
                <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i &lt; selections.length; i++) {
                  <span class="hljs-keyword">var</span> selection = selections;
                  <span class="hljs-keyword">if</span> (selection.row &gt; <span class="hljs-number">0</span>) {
                        <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> row = selection.row + beforeRowCount; row &lt; selection.row + beforeRowCount + selection.rowCount; row++) {
                            sheet.copyTo(selection.row + beforeRowCount - <span class="hljs-number">1</span>, <span class="hljs-number">-1</span>, row, <span class="hljs-number">-1</span>, <span class="hljs-number">1</span>, <span class="hljs-number">-1</span>, GC.Spread.Sheets.CopyToOptions.style | GC.Spread.Sheets.CopyToOptions.span);
                        }
                  }
                  beforeRowCount += selection.rowCount;
                }
            }
            sheet.resumePaint();

            Commands.endTransaction(context, options);
            <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
      }
    }
};
</code></code></pre>
<p>getSortedRowSelections为对selections按照row Index排序的方法。</p>
<pre class="hljs javascript"><code><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getSortedRowSelections</span>(<span class="hljs-params">selections</span>) </span>{
    <span class="hljs-keyword">var</span> sortedRanges = selections;
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i &lt; sortedRanges.length - <span class="hljs-number">1</span>; i++) {
      <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> j = i + <span class="hljs-number">1</span>; j &lt; sortedRanges.length; j++) {
            <span class="hljs-keyword">if</span> (sortedRanges.row &gt; sortedRanges.row) {
                <span class="hljs-keyword">var</span> temp = sortedRanges;
                sortedRanges = sortedRanges;
                sortedRanges = temp;
            }
      }
    }
    <span class="hljs-keyword">return</span> sortedRanges;
}
</code></code></pre>
</li>
<li><p>注册insertRowsCopyStyle命令</p>
<pre class="hljs cpp"><code><code class="lang-js">spread.commandManager().<span class="hljs-keyword">register</span>(<span class="hljs-string">"insertRowsCopyStyle"</span>, insertRowsCopyStyle);
</code></code></pre>
</li>
<li><p>替换原有插入命令</p>
<pre class="hljs php"><code><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">MyContextMenu</span><span class="hljs-params">()</span> </span>{}
    MyContextMenu.prototype = <span class="hljs-keyword">new</span> GC.Spread.Sheets.ContextMenu.ContextMenu(spread);
    MyContextMenu.prototype.onOpenMenu = <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(menuData, itemsDataForShown, hitInfo, spread)</span> </span>{
      itemsDataForShown.<span class="hljs-keyword">forEach</span>(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(item, index)</span> </span>{
            <span class="hljs-keyword">if</span> (item &amp;&amp; item.name === <span class="hljs-string">"gc.spread.insertRows"</span>) {
                item.command = <span class="hljs-string">"insertRowsCopyStyle"</span>
            }
      });

    };
    <span class="hljs-keyword">var</span> contextMenu = <span class="hljs-keyword">new</span> MyContextMenu();
    spread.contextMenu = contextMenu;
</code></code></pre>
</li>
</ol>
<p>在onOpenMenu
方法中,可以拿到当前点击区域可操作的所有右键菜单内容,对itemsDataForShown进行修改,可以更改最终呈现出来右键菜单的内容。比如删除某一项,或者设置disable=true来禁止。</p>
<p>在线测试地址:<a href="https://runjs.cn/detail/yebbozwj">https://runjs.cn/detail/yebbozwj</a></p>

</div>

小弟弟 发表于 2023-1-3 11:22:30

这个怎么改成插入的时候向下插入呢,并且复制上一行的样式

Lynn.Dou 发表于 2023-1-3 12:18:20

注意到关于此问题您另开了新贴交流,后续技术顾问会在新帖中解答您的疑问:
https://gcdn.grapecity.com.cn/forum.php?mod=viewthread&tid=159776&fromuid=59119

李樱 发表于 2023-2-10 17:26:00

你好,我想请问下,如何在execute这个方法增加传参呢,因为在新增行的时候,针对下拉框联动的数据,还要做些处理,所以想将this或其他参数传到这个execute方法

Ellia.Duan 发表于 2023-2-10 17:42:06

您好,您可以把想要处理的数据存储在tag标签中,
可以参考这篇学习指南:
https://demo.grapecity.com.cn/spreadjs/SpreadJSTutorial/features/cells/tags/tag-basic/purejs
在execute中获取标签数据
页: [1]
查看完整版本: SpreadJS 自定义“右键插入”功能