четверг, 22 марта 2012 г.

Пара заметок об Open XML

В очередном проекте в очередной раз нужно генерировать отчеты в Excel (ну ладно: наконец-то выпала возможность “попедалить”! Улыбка ). Из имеющихся в распоряжении средств: генерировать html (просто, но слишком коряво), office xml (по-моему до сих пор вполне пристойный вариант) и Open XML aka Office 2007+ – был выбран последний. Аргументы: по отзывам на habrahabr все должно быть просто и быстро, к тому же на выходе мы получаем актуальную версию формата.

Open XML SDK 2.0 “весит” немногим больше 100 Мб – по нынешним временам, конечно, не объем, но все-равно возникает вопрос: “А что туда такого напихали и почему так много?” В комплект входит “Open XML SDK 2.0 Productivity Tool for Offce”, который может по данному файлу сгенерировать код, который сгенерирует точно такой же файл. Вроде бы все просто, но когда начинаешь разбираться в коде, становится грустно.

  1. API – жуть какое неудобное.
    Вроде как обещается, что это высокоуровневое API, упрощающее создание/редактирование документов (цитирую: “The Open XML SDK 2.0 encapsulates many common tasks that developers perform on Open XML packages, so that you can perform complex operations with just a few lines of code.”).
    • Почему тогда изо всех углов торчит XML и API по работе с ним (все эти бесконечные Append, Text, AddNamespaceDeclaration)?
    • Зачем заставлять меня пользоваться специальными типами для всего, что только можно придумать (включая специальный тип UInt32Value)? В результате приходится пользоваться прямо-таки умопомрачительным количеством разнообразных типов.
    • В высокоуровневом API(!) для создания документов нужно не забыть закрыть пакет (о, вы не знали, что документ – это на самом деле пакет?) – иначе на выходе получим “битый” файл.
    • Как бы глупо это не звучало, но строго типизированное API “молча” позволяет вам сгенерировать невалидный документ. Вот так-то. Добиться этого довольно легко – просто попробуйте сохранить в ячейку какую-нибудь строку в обход таблицы SharedStrings. Для того, чтобы понять, как же это делать “по-правильному”, нужно потратить уйму времени и [внимательно] перечитать примеры кода (код, сгенерированный Productivity Tool-ом вам в этом не поможет).
  2. Убогая документация.
    • Есть примеры. Но почему-то код в примерах “ни разу не похож” на то, что генерирует тот самый Productivity Tool. Более того,
    • Описание классов поражают своей информативностью. Для большинства классов все описание – “When the object is serialized as xml, its qualified name is XXX”. В некоторых случаях еще ссылаются на раздел стандарта. Такая документация очень помогает разобраться в том, как мне сделать что-то.

Часть проблем мне удалось побороть, но добавление графиков пока “продолжает сопротивление” (количество всяких параметров/атрибутов и запутанность их значений навевают уныние).

Гораздо приятнее выглядит проект с издевательским (для формата Open XML) именем ClosedXML – поверх стандарта соорудили человеческое API, которое действительно позволяет достигнуть нужного результата буквально парой строк кода.

HTH,

AlexS