Wilson.Zhang 发表于 2024-9-30 18:02:43

在 SpreadJS 中对选区控制的深度探索与实践

本帖最后由 Wilson.Zhang 于 2024-9-30 18:09 编辑

探索下在SpreadJS中可否控制选区,比如只允许横向选择或纵向选择,且仅能对被选区域填充。对于这个需求,首先想到的是表单保护,但是呢,如何进一步限制只能选择一行内或一列内的单元格呢?即,当需要横向选择时,以鼠标触及的单元格为原点,仅能向左或向右横向选择,不可以纵向选择,且不可以在其他行选择。同理,在纵向选择时,也仅能沿着原点单元格所在列上下选择,不可以选择其他列,也不可以横向选择。那么,带着问题分析下表单保护特性先。

结合单元格默认的锁定状态,表单保护可以对整张Worksheet形成防护甲,以阻止用户编辑单元格,从根源上保护了数据的原始形态。单元格有默认的锁定状态,也就对应可修改为未锁定状态,如图1所示,未锁定状态的单元格不受表单保护控制。除了控制单元格可否操作外,表单保护也从多方面阻隔用户操作,如图2所示保护属性。


图1. 单元格锁定设置

图2. 表单保护属性
从图2中发现,似乎可以以“选择锁定单元格”和“选择未锁定的单元格”这两项保护属性为突破点,结合单元格可控的锁定/未锁定状态,按需修改单元格状态,在表单保护下形成横向或纵向的可选区。那么,何时触发这样的执行逻辑呢?可以通过SelectionChanging事件监听,基本方案如下:

1. 取消表单保护,让Worksheet任何区域可选,且同时恢复所有单元格的默认锁定状态。
2. 在横向选择时,将当前原点单元格所在行的所有单元格设置为未锁定状态。
3. 在纵向选择时,将当前原点单元格所在列的所有单元格设置为未锁定状态。
4. 开启表单保护的同时,允许选择未锁定的单元格,不允许选择锁定的单元格,其他保护选项可不设置,或按需设置。

假定先对Worksheet做横向选择,再做纵向选择。那么,横向选择时将相关行单元格解锁,在纵向选择时,如果这些单元格的状态仍然是未锁定,即便纵向选择与横向选择之间没有交集,也不合理。因此,在每次监听到SelectionChanging时,都先取消表单保护以使得整张Worksheet中任意单元格可成为选区原点单元格,同时恢复所有单元格锁定状态

限定选区的问题解决了,那么,扩展下填充选区。在只有横向选择或纵向选择的情况下,仅需要填充被选择的区域即可。如果横向选择和纵向选择同时存在,那么,横向选择区域和纵向选择区域的交叉区域有两种。如图3所示,横向选择区域与纵向选择区域交叉形成十字形。十字交叉区域以横向选择区域的起始行为起始行、横向选择区域的跨越行数为跨越行数、纵向选择区域的起始列为起始列、纵向选择区域的跨越列数为跨越列数。另一种情况是横向选择区域所在列和纵向选择区域所在行的扩展区域形成的交叉区域,外形呈矩形状,如图4所示。矩形交叉区域以纵向选择区域的起始行和跨越行数分别为起始行和跨越行数、横向选择区域的起始列和跨越列数分别为起始列和跨越列数。(为了突出横向选择区域和纵向选择区域,为其设置了黄色背景色,为填充区域设置红色背景色以模拟填充。)


图3. 十字形交叉区域

图4. 矩形交叉区域
基本的执行逻辑如上所述,那么,如何触发横向选择或纵向选择或填充区域呢?当然是通过按钮,让用户可交互体验,如图5所示。


图5. 控制选区
探索结束,附上demo,以供参考。根据实际需求场景,可在此demo的代码逻辑基础上扩展或修改以自适应之。

问题原帖:https://gcdn.grapecity.com.cn/showtopic-227147-1-1.html
页: [1]
查看完整版本: 在 SpreadJS 中对选区控制的深度探索与实践