Понимание двоичного формата файла xls - PullRequest
4 голосов
/ 17 марта 2012

Я пытаюсь прочитать содержимое xls-файла без использования каких-либо библиотек xls, но у меня возникают проблемы при этом.

Я пытаюсь использовать информацию, которую нашел здесь . В нем есть небольшая пошаговая инструкция о том, как читать файл. Также используя эту xls-файл-спецификацию .

Я не уверен, правильно ли я делаю этот шаг:

3, Откройте поток Workbook и отсканируйте первый экземпляр BOF-записи. Это начало подпотока Globals.

В соответствии со спецификацией файла или этой страницей со списком номеров записей , я должен искать 2057 (0809h), но весь файл нигде не содержит эту запись (также используя hexa-редактор при попытке найти его). Но затем я читаю эту часть на странице 20 в спецификации:

Поменять байтами файлы Excel BIFF можно переносить через Операционные системы MS-DOS / Windows и Apple Macintosh и другие. к поддерживает транспортабельность, Excel записывает BIFF-файлы, где младший порядок байт слова появляется первым в файле, за ним следует старший символ байт.

Если я правильно понимаю (не уверен, что понимаю), используются слова с прямым порядком байтов, так что я ищу на самом деле 2312 (0908h). Это создает впечатление правильности, так как он обнаруживается очень рано в каждом файле, который я пробую.

Итак, перейдем к следующему шагу:

4, Считать подпоток Globals, загрузить записи BoundSheet8 и SST в память. Для получения дополнительной информации см. Globals.

Я ищу 133 (8500h), и он найден вскоре после BOF, хорошо. Но проблема заключается в двух следующих шагах:

5, Из записи BoundSheet8, которая соответствует подпотоку, который вы хотите открыть, прочитайте первые 4 байта, которые содержат lbPlyPos FilePointer. 6. Перейдите к смещению в потоке, указанном в lbPlyPos FilePointer. Это запись BOF для рабочего листа.

Итак, следующие 4 байта - это указатель, указывающий на позицию в файле, к которой я должен перейти. Но чтение этих байтов в любом порядке дает мне число, которое больше, чем весь файл. А также, эта часть смущает меня: «Это запись BOF для рабочего листа». Разве это не то, что я нашел на более раннем этапе? Хм ...

Извините за мою бессвязную работу. И я надеюсь, что в этом есть смысл, и что кто-то захочет мне немного помочь.

Обновление: Хорошо, я получил немного дальше с этим. Меня это несколько смущает, но кажется, что каждая запись также читается как "big endian", то есть последняя переменная в записи - это та, которая расположена в файле как можно раньше. Хотя я не знаю, относится ли это к значениям с переменной длиной? Итак, глядя на this , значения переменной длины перечислены как последние в записи. Но очевидно, что они не могут быть первыми в файле, потому что не было бы способа узнать, сколько байтов нужно прочитать, если эта информация последует за ней? В любом случае, если я проигнорирую это значение и пропущу 2 байта для dt и A / unused и прочитаю следующие 4 байта в качестве uint, в моем случае получится 1130 Добавление этого к позиции первой BOF дает мне точное положение листа 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 , но это не имеет смысла ...очень признателен, если кто-то может помочь мне с этим.

Ответы [ 2 ]

0 голосов
/ 19 сентября 2013

Запись BOF - это не только первые два байта. Следующие два байта «10 00» сообщают вам длину остальной части записи (это означает 0x0010 или 16 байтов). Однако после отсчета 16 байтов там нет записи индекса. (Из списка идентификаторов записей идентификатор индексной записи должен быть 523, то есть 0x020b, который будет отображаться как «0b 02».)

Вы должны смотреть не на тот BOF. Вы, должно быть, либо не нашли указатель lbPlyPos, либо неправильно следовали ему.

Таким образом, следующие 4 байта - это указатель, указывающий на позицию в файле, к которому я должен перейти. Но чтение этих байтов в любом порядке дает мне число, которое больше, чем весь файл

Убедитесь, что вы пропускаете два байта, которые дают вам размер записи.

0 голосов
/ 19 марта 2012

Что касается записи BOF, я могу сказать, что она относится к началу файла и находится в начале каждого подпотока, содержащегося в файле Excel.Учитывая, что у вас обычно есть 3 листа, все листы имеют листы кода VBA, а книга содержит кодовый лист, который вы просматриваете в 8 записях BOF.

...