本帖最后由 Winny 于 2023-10-7 17:45 编辑
需求背景:在填报、报表场景中,客户需要将多个工作簿的个别工作表添加到别的工作簿当中,实现合并部分工作表到其它工作簿的需求。
实现方案:正常来说,只需要简单的工作表级别的toJSON()和fromJSON()即可。但是Excel文件比较特殊,会包含公式、样式、图表、图形透视表等多种元素,且元素中的命名也有一定要求。主要包含以下几点:
(1)同一个工作簿中,工作表名称、图表、表格名称不允许重复。
(2)工作表中的公式单元格可能会依赖其它工作表,该依赖工作表不一定会存在于目标合并文件中。
(3)Excel中包含命名样式,如果被合并的工作表中用到之前工作簿上的命名样式,而目标合并文件上并不存在这一命名样式,会导致样式无法正常显示。
接下来,针对上述集中情况,出具具体的解决方法。
(1)同一个工作簿中,工作表名称、图表、表格名称不允许重复。
这个解决方法比较简单,只需要依次遍历需要合并的工作表中的相关元素,重命名加上一个独一无二的标志即可。当然,这一点还是需要研发和业务精心设计,去确定一个独一无二的标志。
(2)工作表中的公式单元格可能会依赖其它工作表,该依赖工作表不一定会存在于目标合并文件中。
SpreadJS提供获取单元格公式的相关API,需要去判断公式中是否有别的工作表引用,如果有的话,在合并时,需要根据业务需求,去决定删除公式还是同时合并公式依赖的工作表。注意,被依赖的工作表有可能也存在其它表依赖,这块需要递归查找。
(3)Excel中包含命名样式,如果被合并的工作表中用到之前工作簿上的命名样式,而目标合并文件上并不存在这一命名样式,会导致样式无法正常显示。
Excel中的命名样式,分为文件级别和工作表级别。如果是工作表级别,其实不需要太多额外处理,直接toJSON即可。但如果是文件级别的命名样式,这时就需要额外处理了。我们可以将要合并的工作表所在的工作簿上的命名样式,全部再添加到工作表级别。具体代码实现可以点击这里,跳转查看实现原理。
但是它的弊端其实也比较明显,大部分客户的文件,可能都是一些在excel中制作的历史文件,有的可能被多个人修改,里边存在的命名样式达到几百个,但是并不是每一个命名样式当前工作表会用到,这导致会有一定的数据冗余,甚至会造成一些性能问题。
总结:以上是SpreadJS上合并追加sheet的实现细节,需要注意的是,目前SpreadJS官方并没有直接支持外部sheet的追加合并,因此所有的方案,都会有一些未知的风险。在这里,我们还是比较推荐使用GCExcel来实现文件的合并,因为GCExcel直接支持了跨工作簿的工作表复制及移动,实现起来更加省心噢~
|
|