Стандартная поставка системы DIRECTUM содержит полезный механизм "Конструктор документов". При минимуме разработки он формирует типовые и не очень документы из заранее подготовленных т.н. макетов. Макеты представляют собой документы с обозначенными местами для вставки текста. Как это работает: путём нехитрых манипуляций разрабатывается обобщённый макет - шаблон будущих документов. В нужном месте автоматизируемого процесса на основе полученных нужных данных (например, у пользователя в мастере действий) и заранее подготовленного макета прикладная функция GenerateDocument() формирует готовый документ.
Как раз об оптимизации логики формирования документов из макетов и поговорим дальше.
В функции при помощи COM-объекта Word.Application (ну или Excel.Application) происходят манипуляции с макетом, наполнение его нужными данными. При создании объекта Word.Application происходит запуск процесса WINWORD.EXE, в память загружается документ и происходит обработка.Так вот формирование документа из стандартного макета протокола совещания таким способом на моём рабочем ПК занимает около 5 секунд. А в подавляющем большинстве случаев использования, по требованиям процесса, в прикладных вычислениях по соседству с генерацией выполняются другие затратные по времени операции: создание документа из файла, создание, заполнение и отправка задачи. Кроме этого требуется выполнять поиски, перебирать детальные разделы, делать вынужденные преобразования и т.д., создающие "фон" на свои полсекунды-секунду.
Как быть? Оптимизировать вычисления.
Но есть действия, время и оптимальность выполнения которых не всегда зависит от прикладной разработки. Так, на скорость создания документа на сервере повлияет "ширина канала" до сервера (передаётся тело документа). А для эффективной работы с содержимым документов при формировании документов из макетов приходится использовать тяжёлые офисные COM-объекты - наш случай.
Что-нибудь ещё кроме времени выполнения функции GenerateDocument()? Да. Формирование документов может выполняться на стороне службы workflow и сервере веб-доступа. В некоторых ситуациях операции генерации документов - массовые, сталкивался лично на одном из проектов. И имеют место быть:
Это вызывает дополнительное беспокойство администратора.
Идея оптимизации пришла в голову давно и состоит в следующем: т.к. файлы .docx, по сути, zip-архивы с xml-файлами по формату Office Open XML - работать с документом как с xml-файлом. OpenXML SDK позволяет разработчику с удобством работать с OpenXML, в частности с .docx. Да и работать с xml приятнее в .net, чем используя MSXML. Как для знакомства с форматом OpenXML, так и для глубокого изучения рекомендую сайт openxmldeveloper.org. Там масса полезной информации о формате, примеры кода на разных языках, разбор типовых случаев работы с документами.
Результатом реализации идеи стала COM-библиотека DocXConstructor.dll с простым интерфейсом:
Библиотека использует .NET Framevork v.3.5 и OpenXML SDK и повторяет логику работы функции GenerateDocument().
Но есть исключения-ограничения:
В дополнение к самой библиотеке я написал функцию GenerateDocumentFasterWithMoreEnergy() для работы с DocXConstructor.dll. Функция формирует из макетов только .docx документы или генерирует исключение. Чтобы опробовать работу оптимизированного формирования документов из макетов вместо вызова GenerateDocument(), предварительно проверив расширение файла, вызывайте GenerateDocumentFasterWithMoreEnergy(), по параметрам они идентичны.
На компьютерах, где документы будут генерироваться из макета по-новому (на сервере workflow и/или на рабочих местах пользователей) распакуйте архив в нужное вам место и запустите register.bat для регистрации библиотеки из папки DocXConstructor. Чтобы разрегистрировать библиотеку запустите unregister.bat. Функция GenerateDocumentFasterWithMoreEnergy() в виде пакета разработки доступна в папке dev архива.
Установленный и настроенный Microsoft Office для работы DocXConstructor.dll не требуется. Это полезно там, где используются отличные от Microsoft Office офисные пакеты.
Исправление пожеланий к решению возможно, но не гарантируется.
Прошу в комментариях оставить мнение о полезности решения. Планируете ли использовать это решение на своих проектах?
Спасибо за внимание.
Интересная статья. А почему не поддерживается генерация .xlsx?
Еще заметила за OpenXML SDK такой грешок: иногда генерируемый документ отличается от шаблона (в моем случае у некоторых элементов списка пропали маркеры). Вы с таким не сталкивались?
>> А почему не поддерживается генерация .xlsx?
на мой взгляд генерация именно из макетов в excel мало используется. Решил не тратить на это время. Ограничений в техническом смысле нет, доделывается быстро.
>> иногда генерируемый документ отличается от шаблона (в моем случае у некоторых элементов списка пропали маркеры). Вы с таким не сталкивались?
Сталкивался с обратным, что при манипуляциях с документом как с xml-документов всё остаётся всё точно как в макетах, в т.ч. стили (а маркеры это стиль). Я сталкивался с тем, что иногда сбивается стиль при подстановках значений макропеременных через Word.Application (но не нашёл закономерности).
Стандратный маркер помечается на уровне xml в параграфе. Его можно потерять при манипуляциях со структурой документа, в частности, при копировании. Это самая вероятная причина, считаю.
Считаю что давно пора уходить от использования Com-объектов ворда в сторону OpenXML, да и от "старых" форматов надо полностью избавляться. Нужно допилить Excel и включать в стандартную :)
Авторизуйтесь, чтобы написать комментарий