【问题标题】:Understanding the binary xls file-format了解二进制 xls 文件格式
【发布时间】:2012-04-02 15:46:40
【问题描述】:

我正在尝试在不使用任何 xls 库的情况下读取 xls 文件的内容,但这样做时遇到了问题。

我正在尝试使用我找到的信息 here。它有一个关于如何读取文件的逐步说明。 也使用这个xls-file-specification

我不确定我是否正确地执行了这一步:

3,打开工作簿流并扫描 BOF 记录的第一个实例。这是 Globals 子流的开始。

根据文件规范或带有list of the record-numbers 的此页面,我应该寻找 2057(0809h) 但整个文件在任何地方都不包含该记录(在尝试查找时也使用六角编辑器它)。 但后来我在规范的第 20 页阅读了这部分内容:

字节交换 Excel BIFF 文件可跨 MS-DOS/Windows 和 Apple Macintosh 操作系统等。到 支持可移植性,Excel 写入 BIFF 文件,其中低位 单词的字节首先出现在文件中,然后是高位 字节。

如果我理解正确(不确定我是否理解)使用了单词的大端,那么我正在寻找的实际上是 2312(0908h)。这给人一种正确的印象,因为它在我尝试的每个文件中都很早就被发现。

然后进行下一步:

4、读取 Globals 子流,将 BoundSheet8 记录和 SST 加载到内存中。有关详细信息,请参阅全局变量。

我在寻找 133(8500h),它在 BOF 之后不久就找到了,很好。但问题在于接下来的两个步骤:

5、从要打开的子流对应的BoundSheet8记录中,读取前4个字节,其中包含lbPlyPos FilePointer。 6、转到由 lbPlyPos FilePointer 指定的流中的偏移量。这是工作表的 BOF 记录。

所以下面的 4 个字节是一个指针,指向我应该去的文件中的一个位置。但是以任何顺序读取这些字节会给我一个大于整个文件的数字。而且,这部分让我感到困惑:“这是工作表的 BOF 记录。”这不是我在前面的步骤中发现的吗?嗯……

对不起,我的胡言乱语。我希望我说得通,并且有人愿意帮助我一点。

更新: 好的,我在这方面已经走得更远了。这让我很困惑,但似乎每条记录也被读取为“大端”,即记录中的最后一个变量是文件中最早定位的变量。虽然我不知道它是否适用于可变长度的值?因此,查看this,可变长度的值被列为记录中的最后一个。但显然它们不能作为文件中的第一个出现,因为如果该信息出现在它之后,就无法知道要读取多少字节? 无论如何,如果我忽略这个值,并跳过 dt 和 A/unused 的 2 个字节,并将以下 4 个字节作为 uint 读取,在我的情况下结果为 1130。将其添加到第一个 BOF 的 pos 中,我得到了 sheet-BOF 的确切位置。这不会是巧合吧?

现在下一个问题出现了。在该 BOF 记录之后,索引记录应该立即跟随。但无论我以何种方式读取字节,它仍然没有意义...... 这是它的样子:

09 08 10 00 00 06 10 00 BB 0D CC 07 00 00 00 00 06 00 00 00 00 02 0E 00 00 00 00 00 1E 00 00 00 00 00 12 00 00 00 3E 02 12 00 B6 06 00 00 00 00 40 00 00 00 00 00 00 00 00 00 00 00 7D 00 0C 00 00 00 00 00 DD 06 0F 00 00 00 00 00 7D 00 0C 00 02 00 02 00 DD 06 0F 00 00 00 00 00 7D 00 0C 00 04 00 04 等...

前 2 个字节是 BOF 记录 09 08 或交换的 0809,即 2057(代表 BOF),所以其余的应该是 INDEX 但没有意义...如果有人我将不胜感激可以帮我解决这个问题。

【问题讨论】:

  • “似乎每条记录也被读取为“大端”,即记录中的最后一个变量是文件中最早定位的变量” - 这不是真的。您应该谈论的是 stream 中的位置,而不是文件中的位置。

标签: excel binaryfiles


【解决方案1】:

关于 BOF 记录,我可以告诉你它指的是文件开头,并且位于 excel 文件包含的每个子流的开头。假设您通常有 3 个工作表,所有工作表都有 VBA 代码表,并且工作簿有一个代码表,您正在查看 8 条 BOF 记录。

【讨论】:

  • 感谢您的回答。我确实认为 BOF 记录可能代表文件的开头以及每张纸。感谢您的确认。
【解决方案2】:

BOF 记录不仅仅是前两个字节。接下来的两个字节“10 00”告诉您记录其余部分的长度(这意味着 0x0010,或 16 个字节)。但是,向前计数 16 个字节后,那里没有索引记录。 (从the list of record ID's来看,Index记录的ID应该是523,也就是0x020b,会显示为“0b 02”。)

您一定看错了 BOF。您一定是没有找到 lbPlyPos 指针或错误地跟随它。

所以下面的 4 个字节是一个指针,指向我应该去的文件中的一个位置。但是以任何顺序读取这些字节都会给我一个大于整个文件的数字

确保您跳过了给出记录大小的两个字节。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-14
    • 2015-12-16
    • 2015-07-06
    • 2011-05-29
    • 2012-02-15
    • 2017-09-21
    • 2016-11-10
    • 2016-12-18
    相关资源
    最近更新 更多