背景:
1. 区域快照引用了区域后,对区域快照重置了宽度,且引用区域范围随着插入行发生了变化。同步引用区域插入行时发现区域快照尺寸不变,导致其内部行高受到压缩,如图1所示。如何能够使得重置尺寸后的区域快照随着引用区域插入行而同步变化高度,保持内部行高不变。
图1. 引用区域插入行后区域快照同步扩展但尺寸不变
2. 在解决了背景1问题后,用户使用区域快照作为sheet中的一部分数据视图,其所在区域的下一行单元格又是另一个数据视图区域。区域快照随着引用区域插入行扩展时,发现其原始区域下一行的数据被扩展后的快照遮盖住了,如图2所示。如何能够使得区域快照尺寸变化的同时保持其原始区域下一行数据紧随其后可见?
图2. 引用区域插入行后区域快照同步扩展但遮住原始区域下一行单元格
问题原帖:
1. https://gcdn.grapecity.com.cn/showtopic-229932-1-1.html
2. https://gcdn.grapecity.com.cn/showtopic-230494-1-1.html
关于上述两个问题背景,我们在Microsoft Excel测验发现与此一致,即SpreadJS与Microsoft Excel保持了一致的设计。那么,无论用户是否具备操作Microsoft Excel的使用习惯和经验,都不能将此视之为功能问题,而是一个与用户需求场景强相关的业务需求。经过一番调研和分析,确认根据SpreadJS区域快照当前的公开API能够自定义实现这样的需求。那我们话不多说,切入正题。
先说区域快照,其本身作为一个静态引用同步了引用区域中的数据,当引用区域内部扩展行或修改单元格数据时,区域快照均会同步更新自身状态,使得其与引用区域保持一定程度的一致性。
也正是基于这样的功能特性,用户选择将其作为一部分数据视图与普通单元格组合在一起构建更不寻常的电子表格,用以满足一些特定场合的数据展示需求。
比如,某sheet(下文称作ViewSheet,即用以展示数据的sheet)集成了同工作簿内多个其他sheet中的部分数据,通过区域快照形成一个组合式视图。在创建区域快照时,为了便于展示数据或其他关于美观的需要,通过拖拽的方式重置了区域快照的宽或高或兼而有之。同时,在紧邻区域快照所占据的单元格范围的下一行自定义了一些用以展示的其他数据内容。
那么,当引用区域中插入新行后,当然希望重置了尺寸的区域快照能同步扩展,即不仅从内部插入行,而且在原有尺寸基础上等比例扩大;同时,也需要与其所处位置周边的数据保持相对位置关系,即下一行也能同步下移。
接着分析下围绕这个需求应该如何来实现。SpreadJS将区域快照抽象为CameraShape对象,基于区域快照引用其他单元格区域这一事实,CameraShape对象即需要记录引用区域、放置位置、尺寸等。有了这些属性,我们设想在引用区域插入行时能够根据插入行数计算区域快照应该增加的高度,以及区域快照原始区域下一行应该下移的行数,即以原始区域下一行为基行需要插入的行数。此外,需要建立引用区域与区域快照之间的映射关系,这样便能在引用区域插入行时快速找到引用其的区域快照。考虑到用户的实际需求场景可能包含众多sheet和区域快照,如果在映射关系中直接存储CameraShape,可能有点儿消耗内存空间,继续抽丝剥茧筛选下关键信息。
既然引用区域和快照区域可能在不同sheet,SpreadJS又可以根据sheet名称获取Worksheet对象,同样可以根据区域快照名称获取CameraShape对象,那么就简化为建立引用区域所在sheet名称和区域快照名称之间的映射关系。考虑到,计算扩展高度和以区域快照原始区域下一行为基行插入行保持相对关系这两点,映射关系中原本记录区域快照名称的一边需要添加区域快照原始行高、区域快照原始区域下一行索引、区域快照所在sheet名称等三项信息。至此,映射关系示意图如图3所示。
图3. 映射关系示意图
基于上述基础事实,详述实现方案如下:
1. 对Workbook中的各引用区域和区域快照建立映射关系。
2. 对Workbook注册RowChanged监听事件,监听插入行动作。
3. RowChanged事件被出发时,根据其所在sheet名称从映射关系中查询是否有区域快照信息,如果没有即结束流程。如果有区域快照,则遍历其对应的区域快照信息组。
4. 在遍历区域快照信息组的过程中,根据区域快照名称查询CameraShape对象,因为具体信息被保存在CameraShape中。通过CalcEngine:formulaToRanges()获取CameraShape引用区域的行列范围,以此判断插入动作的基行是否被包含在内。如果在内,则以区域快照原始区域下一行为基行,在区域快照所在sheet中插入引用区域中插入的相同行数,以此保持扩展后区域快照与其下一行的相对位置关系。
5. 根据区域快照原始行高与插入行数计算区域快照高度的扩充值,之后在现有高度上增加即可。
6. 更新当前映射关系信息中区域快照下一行的索引值。
上述方案实现如图4所示,sheet1中A1: D4为引用区域,区域快照位于sheet2中单元格C3起始的位置,其下一行索引为7,单元格C7填充了数据12345且整行设置黄色背景用以标识。sheet1中A1: D4范围内插入新行后,可见sheet2中区域快照内部行高未被压缩,同步引用区域插入了新行,区域快照高度扩展,且“12345”所在单元格由C7变为C8,即以行索引为基行插入了行。
图4. 区域快照同步
附上demo,以供参考。
|