摘 要 :本文通过设计了一种高效的中间存储格式,即带索引的XML文件,能随机存取指定行的单元格,并且压缩存储大量重复的单元格,解决了在线电子表格的数据存储问题.
关 键 词 :在线电子表格;存储;XML;JaScript;单元格
中图分类号:TP391.13 文献标识码:A 文章编号:1007-9599 (2013) 01-0187-02
1.引言
在线电子表格是将应用程序部署在怎么写作器上,用户通过浏览器访问的网络版电子表格软件,其功能类似于桌面版电子表格.由于系统本身功能复杂,要处理的数据量大,而网页所使用的JaScript和HTML语言的性能远远低于桌面版的Ja、C++等语言,使得网络版的开发难度比桌面版更大.
在线电子表格的界面通过网页来显示,一个电子表格文档包含的数据量可能非常大,例如一个512k的ods文档,就有1000*256个单元格填满数据,由于JaScript创建对象的效率低、占内存大,无法将这样大量的数据装载到客户端内存,因此让客户端只加载当前显示的那部分行数据,由于客户端数据不完整,所有编辑操作必须放在服须器端执行.在怎么写作器端执行操作时文档对象不能常驻内存,因为可能有很多文档同时被在线编辑,内存占用将非常大.用关系数据库存储每篇文档也是不合适的,因为电子表格文档的内容是半结构化的,适合用XML文件存储,这就意味着每个操作都要读写文件,对读写效率要求非常高.本文设计了索引文件+数据文件的存储格式来实现随机读写工作表的行数据.
2.文件存储结构设计
一个电子表格文档包含大量数据,由于Web版电子表格每个编辑操作都要读写文件,为了提高读写效率,我们分成多个文件来存储,这样每次只需读写与当前操作相关的数据文件,而不需要为无关的数据耗费开销.目录结构如图所示:
当从本地上传或从怎么写作器打开一个电子表格文档
时,通过生成一个唯一的ID,在存储怎么写作器上创建一个名为book+ID的工作簿文件夹.
2.1 book.xml存储工作簿的信息,包括:风格、默认行高列宽、所有区域命名等,还有若干工作表节点,记录工作表的名称和隐藏属性等.此外,在每个工作表节点下还有公式和图表所引用的单元格地址,之所以把它们放在book.xml中而不是在各自的工作表文件中,是因为它们都可以跨表引用,这意味着对一个工作表中的单元格区域做了修改,需要查找所有工作表中的公式、图表看是否需要修改,为了提高查询效率,把它们集中放在一个文件中.
2.2 charts文件夹下存放图表的信息,每个图表一个xml文件,包括图表的尺寸、坐标、引用的图片地址、标题、图例以及x、y属性.
2.3 sheet+ID文件夹下存放一个工作表的全部内容,ID在创建工作表时由系统生成.
该文件夹包括:
(1)table.xml存储行列的高宽及隐藏属性、合并单元格、筛选器和插入的图片地址等信息.其中行、列节点依序排列,用属性“repeat等于'n'”来记录连续n行(列)有相同的属性,例如:
表示第100列设置了列宽为0.3cm,其他都是默认列宽.
(2)content.txt存储单元格的内容,其格式仍然是xml,但为了能随机读写,不能带最外层的根节点,因此存为.txt.数据按照工作表的行存储,基本结构为"
表示第100行第3列单元格有字符串类型的数据"abc".
一个工作表可能有很多行有数据,如果每次修改一个单元格就要对整个文件全读全写是很费时的.Ja可以随机读写文件,但必须知道从第几字节开始读写,本文设计了索引文件contentIndex.txt来记录content.txt文件中每个
(3)styles.txt存储单元格的样式属性,结构与content.txt相同,将内容和样式分开存储是因为多数操作不会同时修改样式和内容,这样避免了读写无关的数据.同样为styles.txt中的
2.4 history文件夹存放每个操作的历史记录,用于撤销和恢复详细存储格式.Pictures文件夹存放插入到工作表中的图片.
3.怎么写作器端数据模型
从文件中读出的单元格数据要建立一定的数据模型才能进行逻辑操作,由于一次读取的单元格可能很多,如果直接用DOM对象,会内存溢出.我们设计了一套与文件存储结构对应的数据对象,采用SAX(Stream API for XML)解析方式, 它占用内存很小,每次读入一段字符流解析,遇到节点的起始标签、内容和结束标签分别触发相应的事件,调用相应的回调函数,创建我们自定义的数据模型.如图所示: Cell和Style是基本元素,分别存储单元格内容和样式,它们都实现IRepeatItem接口,即都带repeat属性,表示同行的连续n个单元格.Row代表工作表中的行对象,也实现IRepeatItem,一个Row对象可以表示连续n个数据完全相同的行.Row对象含有Cell或Style对象的数组,该数组类型为RepeatList,它的元素必须实现IRepeatItem,RepeatList提供了一系列访问数组元素的方法,包括按行号增加、删除、获取和拆分元素,当选中一片单元格区域进行修改时,可能需要把边界的Row 或Cell/Style对象拆分为两个.RowsList代表连续n行,含有Row对象的数组,它的start属性记录起始行号.
4.前后台数据交互格式
4.1 操作指令
客户端接收到用户的操作后,发送操作指令给怎么写作器进行处理.操作指令为xml格式的字符串,标签名即操作名称,属性包括:工作簿ID,工作表ID,选中的单元格区域和要设置的属性等等.例如:
表示设置第1行第5列到第2行第5列这个矩形区域的字体为"Geia",rooSessionId是每个窗口的唯一ID,用于怎么写作器端分别记录不同窗口的操作历史,以便撤销和恢复.
4.2 返回数据
怎么写作器端处理完操作后返回数据给客户端,格式为JSON(JaScript ObjectNotation),它是一种轻量级的数据交换格式,它与JaScript定义对象的语法相同,可以直接转化为JaScript的对象,解析效率高.返回数据格式的设计必须涵盖工作簿全部信息,且尽量简短,以缩短网络传输时间和解析时间.AJAX的回调函数接收到这个JSON对象后,遍历每个工作表对象,取出各个子对象,包括工作表信息、单元格信息、图表、媒体、合并单元格、筛选器等,交给相应的处理器更新内存数据以及界面元素.