标 题:基于最小XLS文件格式的分析
发信人:落幕CC
时 间:2011-03-11
联系方式:247228162@qq.com

详细信息

    第一次发表文章,不对的地方大家多多指正,基于前辈的研究+自己的一点努力,算是弄懂了复合文档的文件格式本篇文章基于最小XLS文件格式的分析,不对之处大家多多指教,废话不多说
  

XLS文件格式

    XLS文件最为一个文件流(FileStream),是由多个子流(SubStream)构成的,下面这张图是将各个SubStream按顺序依次展现出来,这些SubStream都是有若干个整数倍Block(1  block = 512 bytes)组成,所以XLS文件最小也为13,824bytes(即一个表格时)(其实不管是word 还是 ppt 其实都是基于复合文档格式,WPS其实也一样),自己随便建立一个XLS文件,用UltraEdit打开就可以看见,我这里是基于最小的,也就是一个sheet了!

主要组成如下:




其中WorkBook为数据变化区,它会随着文件的内容的增大而增大,但始终保持Block的整数倍。


XLS Header

     最小XLS文件Header





表1
  
    *  00000000h到00000010h  这32个字节基本不变,表示是复合文档,前8个字节
  
D0 CF 11 E0 A1 B1 1A E1表示复合文档标识,后面16个字节全部为0,后面2个字节 3E 00 

代表文件格式修订号,后面2个字节代表文件格式版本号,后面2个字节 FE FF 代表字节

顺序号(高存高低存低)后面连个字节 09 00 代表标准扇区的大小(公式= 2的9次幂

(09 00 十进制=9) = 512 bytes 

    *   00000020h行的 01 00 00 00 表示:BigBlock pointer区占的block个数。表1 中BigBlock pointer区Block个数为:01(十进制)。

   *  00000030h行的 19 00 00 00 表示:指向RootEntry所在Block序号。表1中RootEntry的所在的起始block序号为:25(十进制)。

   *  00000040h行的 FE FF FF FF 表示:指向XLS header扩展区所在Block序号。FE FF FF FF 表示没有XLS header 扩展区

   *  00000040h行的 00 00 00 00 表示:XLS header扩展区所占的block的个数。如果没有XLS header扩展区这里就是00 00 00 00。

   *  00000040h行的 18 00 00 00 表示:指向BigBlock pointer所在Block序号。表1中BigBlock pointer的所在的起始block序号为:24(十进制)。 

   *  00000050h行开始到00 00 01 f0h:4字节组。因为没有XLS header 扩展区,所以连续填充FF FF FF FF

WorkBook
   存放execl表数据信息所有sheet数据都在这里面 ,里面的东西重要(那要看对那些对象,其实是对我不重要,呵呵)

09 08 10 00 00 06 05 00 86 20 CD 07 C9 C0 00  
第1个字, 0×0010, 按照BIFF记录结构,当然是长度了
第2个字,0×0600, BIFF版本,BIFF7总是0×0500, BIFF8/BIFF8X总是0×0600, 
第3个字, 0×0005, 数据类型, 0×0010 表示Sheet, 0×0005 表示Workbook Global第4个字,Build Id 不能是0, 但可以被忽略第5个字,Build Year 不能是0
。 。 。 。 。 。 。 。 。 。 。 。 。 。 。
。 。 。 。 。 。 。 。 。 。 。 。 。 。 。

Summary Information

    属性,路作者,工作表类型等,
   Excel中点击文件>属性的部分内容存在这里(不重要)

Document Summary Information

   文档的属性(不重要)

BigBlock pointer

  *  从01 00 00 00开始,连续,注意最后一个4字节组,也是连续的,但到一个substream结束时 ,FE FF FF FF 为结尾标识 

   *  WorkBook和Summary Information和Document Summary Information中共有几个block,BigBlock pointer就有几个4字节组,BigBlock pointer所占的字节数一定为512的整数倍。

  *    每当一SubStream结束时就加结尾标识FE FF FF FF(数值:-2),不是以block为一个单位,所以在BigBlock pointer里至少要有4个FE FF FF FF(数值:-2),即4个substream结束标识。

  *    在最后一个FE FF FF FF后,跟着是FC FF FF FF FF或FD FF FF FF或两者同时都有。当有XLS Header扩展区时,是两者都有,当无XLS Header扩展区时,只个FD FF FF FF。FD FF FF FF的个数为BigBlock pointer所占的block个数。未用的用FF FF FF FF(数值:-1)填满。

RootEntry
  1.存放文件中RootEntry属性、地址和大小
  2.Workbook属性,地址和大小,占有实际数据的内容
  3.SummaryInformation属性,地址和大小
  4.DocumentSummaryInformation的属性,地址和大小

     *   每个128字节以name(占64字节)的Unicode Strings开始。如“52 00 6F 00 …………6E 00 74 00 72 00 79 00”是“Root Entry”的16进制形式。不足64字节的用00补足64字节。
  *    接下2字节表示name中64字节被使用字节个数,可以反映出name中字符个数(包括null结束符)。如“16 00”表示name被使用字节数为22个,反映出name“Root Entry”有9个字符(包括null结束符)。
  *    再接下来2字节为type。Root Entry:05 01,其余三个为:02 01;之后8个字节是数值-1、数值-1:FF FF FF FF FF FF FF FF。但Summary Information substream为     01 00 00 00 03 00 00 00  
  *   00 00 00 00 00 10 00 00 表示:前四个字节表示指向WorkBook所在Block序号(0),后四个字节表示WorkBook的大小(4096byte)。下面的都一样
  *    每个128字节内容,其偏移量116后的4个字节为每个区块的开始位置,之后的4个字节为每个区块的大小,地址和大小数据会随着内容的变化而变化。
 

分析就到这里吧,第一次发,大虾们多多指教!