Автор: Джоэл Спольски
Переводчик: Михаил Меркурьев
В оригинале статья называлась Why are the Microsoft Office file formats so complicated? (And some workarounds) и была написана 19 февраля 2008
На прошлой неделе Microsoft опубликовал форматы двоичных файлов Office. Формат Excel 97–2003 занимает в PDF 349 страниц. Постойте, она не совсем полная! В документе есть интересный комментарий:
Итак, файлы Excel 97–2003 — составные документы OLE, которые, по сути, являются файловой системой внутри одного большого файла. Эта система достаточно сложна, чтобы вам пришлось-таки прочитать ещё одну 9-страничную спецификацию. Все эти «спецификации» больше похожи на структуры данных Си, а не на спецификацию в привычном нам смысле. Это целая многоуровневая файловая система.
Если вы решили прочитать эту документацию в надежде за выходные написать импорт документов Word для вашего блог-движка, или вывести ваши личные финансы в виде таблицы Excel — сложность и длина спецификации быстро отобьют у вас эту охоту. Нормальный программист придёт к выводу, что двоичные форматы Office 1) намеренно сделаны сложными и тёмными; 2) такое мог выдумать только сумасшедший киборг; 3) были созданы крайне неумелыми программистами; и 4) невозможно корректно считать и записать.
Смею вас заверить: всё это неверно. Подумаем вместе, и я вам покажу, почему эти форматы стали такими сложными, почему это не говорит о непрофессионализме Microsoft и как обойти всё это.
Они рассчитаны на очень слабые компьютеры. В первых версиях Excel для Windows, 1 мегабайт ОЗУ был обычным объёмом памяти, и 80386 с 20 мегагерцами мог с комфортом гонять Excel. В форматах Microsoft было много оптимизации, которая позволяла быстрее открывать и сохранять файлы.
Они были рассчитаны на широкое использование библиотек. Если вы хотите написать с нуля двоичный импортёр, вам требуется поддерживать такие вещи, как Windows Metafile (для векторных рисунков), составные контейнеры OLE и т. д. Если вы на Windows, всё это тривиально — оно есть в Windows API. Но если вы пишете всё с полнейшего нуля, всё это приходится реализовывать. В Office реализована широкая поддержка составных документов: например, в Word можно вставить таблицу Excel. Настоящий импортёр Word должен сделать что-то умное с внедрённой через OLE таблицей.
Ни о каком взаимообмене не было и речи. Вполне разумное для своего времени предположение: формат должен читаться и записываться только Word’ом. Это значит, что если программисту, который работает над Word’ом, потребовалось менять формат, он должен думать только над двумя вещами: а) формат должен быть быстродействующим; и б) что занимает меньше строк с учётом всех наработок Word’а. Такие идеи, как SGML и HTML — стандартизованные, пригодные для обмена данными форматы — появились лишь тогда, когда Интернет поставил во главу угла обмен документами; двоичные форматы Office разрабатывались за десятилетие до этого. Предполагалось, что если нужен обмен — всегда можно написать импортёр или экспортёр. В действительности, в Word есть формат, пригодный для обмена — RTF, который был там практически с самого начала. RTF полностью поддерживается и сейчас.
Они должны отражать всю сложность Office. Каждая галочка в диалогах, каждое свойство форматирования — всё это должно записываться где-то в файле. В меню «Абзац» есть пункт «Не отрывать от следующего», который переносит абзац на новую страницу так, чтобы он был на одной странице со следующим? Это тоже часть формата. А это значит, что если вам нужно написать точный клон Word’а, который способен корректно читать документы Word’а, вы должны реализовать эту функцию. Если вы создаёте соперника Word’а, который будет загружать его документы, вам потребуется всего минута, чтобы считать этот бит из файла. Но чтобы переделать алгоритм разбиения на страницы так, чтобы он работал с этим битом, нужны недели. Но это нужно: иначе пользователи откроют свои файлы Word’а и увидят «поплывшие» страницы.
Они должны отражать всю историю Office. Многие особенности формата связаны с функциями, которые очень стары, сложны и редко используются. Они всё ещё остались ради обратной совместимости — ведь Microsoft ничего не стоит оставить старый код. Но если вы хотите разбирать и писать эти файлы, вам придётся пройти весь тот путь, который прошли безвестные программисты из Microsoft 15 лет назад. В текущие версии Word’а и Excel’я вложены уже тысячи человеко-лет — и если вы хотите сделать их клон, вам придётся работать тысячи лет. Формат файла — это всего лишь краткое описание того, что программа делает.
Для примера рассмотрим подробно один маленький пример. Файл Excel — это куча записей в формате BIFF. Самая первая запись в этом файле называется 1904.
Спецификация Excel по поводу этой записи крайне немногословна: запись 1904 задаёт, «используется ли система дат с 1904 года». Ой, классический пример бесполезной спецификации. Если бы вы были разработчиком, работающим с форматом Excel’я, вы бы подумали, что Microsoft что-то скрывает. Действительно, чтобы понять это предложение, требуется дополнительная информация, которую я и хочу поведать. Есть два вида файлов Excel: с датами, начинающимися с 1 января 1900 года (вместе с ошибкой, которая считает 1900 год високосным и намеренно оставлена для совместимости с Lotus 1–2–3), и с датами, начинающимися с 1 января 1904 года. Excel поддерживает обе системы: в первой версии для Mac использовалась нумерация с 1904 года, а Excel для Windows должен был импортировать файлы 1–2–3 с нумерацией с 1.01.1900. Думаю, этого хватает, чтобы бросить вас в слёзы. Неважно, в какой точке истории программист сделал глупость — но вот она перед вами.
Широко распространены файлы и с нумерацией 1900, и с нумерацией 1904 — обычно в зависимости от того, создавался он на Windows или на Mac’е. Конвертация из одного формата в другой может привести к ошибкам целостности данных, так что Excel автоматически не меняет типа файлов. И это не просто загрузка одного бита — это значит, что вам придётся переписать всё отображение дат и код разбора, чтобы поддерживать оба формата нумерации. Я думаю, это займёт несколько дней. Далее, если вы работаете над клоном Excel, вы увидите все сложности работы с датами. Когда Excel конвертирует числа в даты? Почему «1/31» [в американской системе дат — прим. перев.] интерпретируется как 31 января этого года, а «1/50» — как 1 января 1950 года? Все эти тонкие особенности поведения нельзя полностью специфицировать, не написав документ, по объёму информации сравнимый с исходными текстами Excel’я [не согласен; это особенности интерфейса, а не формата файла — прим. перев.].
И это только первая из сотен записей BIFF, которые вам придётся поддерживать, и одна из простейших. Многие из них настолько сложны, что способны смутить даже умелого программиста.
Из этого только один вывод. Выпустить формат файлов Office — это полезно и для Microsoft, и для её продукта, но это не делает импорт или сохранение в файлы Office проще. Программы Office безумно сложны и многогранны, и невозможно реализовать только 20% наиболее популярных функций и осчастливить 80% народа. Спецификация двоичных файлов, по сути, сохранит только несколько минут, потраченных на «ковыряние» в чрезвычайно сложной системе.
Да, я обещал обходные пути. Хорошая новость: для большинства видов ПО писать чтение или запись документов Office — неверное решение. Есть две больших альтернативы: заставить Office делать всю грязную работу за вас, либо воспользоваться более простыми форматами.
Заставить Office делать грязную работу за вас. Word и Excel завязаны на сложных объектных моделях, основанных на автоматизации COM, что позволяет программно делать всё, что угодно. Во многих ситуациях проще будет использовать код Office, чем пытаться реализовать его с нуля. Вот несколько примеров.
Такой подход работает для большинства офисных задач, которые могут выполняться на вашем сервере. Например:
Во всех этих случаях есть способы сообщить объектам Officе, что они работают не в интерактивном режиме и перерисовывать экран не требуется. Кстати, если вы хотите идти этим путём, есть несколько ловушек, так что перед тем, как начать, прочитайте базу знаний Microsoft.
Записывать файлы в более простые форматы. Если вам требуется программно создавать документы, читаемые в Office, есть много других форматов, которые Office уверенно откроет, не пропустив ни байта.
В любом случае, если вы действительно собираетесь создать конкурента Office, который будет считывать и записывать все документы Office, у вас впереди тысячи человеко-лет работы. А если нет — считывание и запись двоичных форматов Office будет самым трудоёмким этапом в вашей работе, но без него вполне можно обойтись.
Оригинал статьи: http://local.joelonsoftware.com/wiki/Почему форматы Microsoft Office такие сложные? (И как это обойти)