Развитие механизма печати штампа ЭП в DIRECTUM

Заказчик: ПАО Корпорация "ВСМПО-АВИСМА"
Исполнитель: Самостоятельно

В 2016 году от нас была заявка в DIRECTUM Awards с механизмом Формирование штампа ЭП

Сейчас хочется рассказать об изменениях, которые он претерпел за 2 года. В прошлой статье мы остановились на том, что реализовали механизм вставки штампа в документы PDF формата и в документы, открываемые в Word и Excel. Однако, сам процесс выбора версии и выбора подписей состоял из нескольких этапов, нескольких диалоговых окон. Со временем захотелось упростить процесс, сократить количество кликов. Кроме того, если в документах, редактируемых в Word или Excel пользователь может перемещать штамп самостоятельно, то в PDF документах штамп вставляется в строго определённое место и только на первой странице. От пользователей неоднократно поступали просьбы "что нибудь сделать", чтобы штамп можно было разместить в "нужном" месте. Да и нормативные документы организации регламентируют размещение штампа в месте, предназначенном для собственноручной подписи.

Шаг за шагом

PDF в картинку

Раз используемые приложения для просмотра PDF документа не позволяют переместить картинку штампа (на самом деле, некоторые позволяют, но у нас в подавляющем большинстве случаев используется Acrobat Reader), то возникла идея вставлять штамп сразу в "нужное" место. А для этого, это место нужно заранее узнать. Отсюда возникла идея показывать пользователю предпросмотр, в котором он может указать место вставки штампа. Осталось понять, как реализовать предпросмотр.

Поиск решений по получению изображения страницы PDF документа привел к утилите ImageMagick. В поддерживаемых форматах заявлена возможность работы с PDF документами. Утилита позволяет получить PNG изображение одной или нескольких страниц PDF документа. Однако, для её работы с PDF требуется установить так же PostScript. В связи с этим отпадает вариант размещать утилиту ImageMagick в расшаренной папке на сервере. 

Транспорт

Утилита размещена на сервере. И запускать её так же следует на сервере. Поэтому, требуется механизм доставки на сервер PDF файла и механизм запуска процесса преобразования PDF в PNG. Для транспорта файла реализован справочник, в текстовый реквизит которого загружается тело PDF файла на клиенте, а на сервере после преобразования, PNG файл записывается в другой текстовый реквизит этой же записи. Так как у документа может быть несколько версий, этот же справочник решено использовать как кеш изображений страниц, а потому текстовые реквизиты для файлов PDF и PNG переехали в табличную часть. 

Для запуска процесса преобразования на сервере реализован web сервис на PHP. Таким образом, процесс получения изображения первой страницы выглядит так: Клиент создает запись справочника "Транспорт файлов". В табличной части создает строчку, указывает в ней номер версии, загружает в текстовый реквизит тело PDF документа. Выполняет HTTP запрос на сервер, в котором так же передает ИД созданной записи справочника и номер строки табличной части. Сервер, обрабатывая HTTP запрос, получает указанную запись справочника, выгружает PDF документ, с помощью ImageMagick получает PNG изображение первой страницы и записывает его во второй текстовый реквизит справочника. Клиент получает ответ и в этот момент уже может показать предпросмотр.

Все окна в одном

Можно приступать к разработке диалога. Но вот незадача, в версии DIRECTUM 5.2.1, используемой на тот момент, был дефект платформы, не позволяющий в компоненте "Диалоги" разместить на растягиваемой форме Web контрол. В связи с этим, "достали с полки" не сильно "запылившийся" справочник диалогов, который мы использовали в разработке до появления компоненты "Диалоги" в DIRECTUM 4.9.1 и ранее.

Форма диалога состоит из 3х Web контролов. 


В web контроле сверху слева производится выбор версии. Для выбора используется JS библиотека Chosen и плагин к ней ChosenImage. 

В web контроле слева снизу производится выбор подписей. Применяется jQuery UI плагин Selectable. При загрузке диалога, а так же при изменении версии документа или при изменении набора выбранных подписей штамп ЭП формируется заново. 

В центральной части отображается предпросмотр первой страницы. Изображение страницы масштабируется в зависимости от размера Web контрола. Поверх изображения страницы размещается изображение штампа. С помощью библиотеки jQuery UI плагинов Draggable и Resizable пользователь может перемещать штамп на странице и менять его размер. Границы страницы ограничивают и диапазон перемещения штампа. При перемещении или изменении размера штампа Web контрол записывает координаты штампа и его масштаб в соответствующие реквизиты на форме диалога. 

Для документов, открываемых в Word или Excel, вместо предпросмотра показывается заглушка.


 

Формирование штампа

При нажатии кнопки "Ок" формируется документ со вставленным штампом и открывается пользователю на просмотр. После чего диалог закрывается. Сам механизм формирования и вставки штампа на тот момент поменялся мало. Файл для вставки штампа теперь берётся не из документа, а из справочника транспорта (из кэша). Штамп тоже на момент нажатия кнопки "Ок" уже сформирован, а потому повторно его формировать нет надобности. Отличия заключаются в том, что при вставке в PDF учитываются координаты и размер штампа.

После закрытия диалога запись справочника "Транспорт файлов" удаляется.

Больше форматов для бога форматов

Охваченные форматы позволяют формировать штамп для большинства возникающих документов. Но, в некоторых случаях всё же возникают и документы других форматов. Tiff, JPEG, и т.д. Реализовывать для них собственные обработчики, расписывать логику предпросмотра слишком трудоемко. Но, можно поступить проще. Выполнить их преобразование в PDF и использовать существующий функционал. Это и было реализовано. В начале процедуры формирования штампа с помощью функции "DCTSGetConvertToPDFSupportedExtensions" получаем список расширений файлов, поддерживаемых для преобразования в PDF. Ориентируясь на этот список, определяем, что версию документа сначала надо преобразовать в PDF, а уже после записывать в справочник транспорта.

Новые проблемы

Эти доработки были совершены в январе - марте 2017 года. Долгое время механизм использовался в таком виде. Закрывал большинство потребностей пользователей, но не все. Иногда возникала необходимость разместить штамп на последней странице в PDF документе. Иногда документ имеет альбомную ориентацию, а после сканирования пользователи забывают развернуть страницы. Потому, при распечатке штампа возникает необходимость поворачивать штамп. Для некоторых документов, открываемых в Word 2010 и старше, штамп стал вставляться не корректно. В этом случае изображение штампа было настолько размыто, что на нём невозможно было различить не то, что буквы, но и строчки, линии, контуры. Попытки решить эту проблему средствами Word к успеху не привели, а потому, было предложено дать возможность преобразовывать в PDF такие документы при печати штампа.

Выбор страницы

В конце 2018 года "дошли руки" и до этих задач. Была реализована возможность выбора страницы. В связи с этим потребовалось переработать структуру справочника "Транспорт файлов". Каждая строчка табличной части теперь не версия документа, а страница одной из версий. Так же, поменялся и механизм вставки штампа. Раньше там жестко была задана первая страница, теперь,номер страницы передаётся в параметре.


Кручу верчу

Неожиданно непростой задачей оказался поворот штампа. Оказалось, что бесплатная версия библиотеки "Debenu pdf library", которая используется DIRECTUM для вставки штампа не имеет возможность вставить изображение с заданным углом поворота. Другое решение - повернуть штамп на этапе формирования в HTML документе. Сделать это возможно, но требуется знать заранее размеры штампа и высчитывать новые размеры повёрнутого штампа.

Проблема была решена с помощью той же библиотеки "ImageMagick". Она умеет поворачивать изображение на заданный угол. С помощью нового механизма DIRECTUM; "Серверные события", на сервер отправляется задание повернуть штамп, клиент дожидается его результата и использует для вставки уже повернутый штамп. 

Работает механизм не быстро. На разворот штампа уходит 3-10 секунд. Но, надобность в этом возникает не часто.

Word в PDF


Для версий документов формата "DOC", "DOCX", "RTF" и "ODT" в диалоге реализована галочка "В PDF". Она появляется только при выборе версии с одним из таких расширений. При её нажатии производится преобразование документа в PDF и получение изображения его страницы. Снимается заглушка и отображается предпросмотр. При нажатии "Ок", открывается PDF документ со штампом.

Результаты применения решения

За время применения функционала пользователи привыкли его использовать. Штампы формируются практически на все виды документов. За декабрь 2018 года механизм формирования штампа был использован 7 150 раз. Из них уникальных документов 5 050.

Помимо этого, на базе этого механизма реализованы и другие модули. Существует модуль выгрузки договорных документов для налоговой службы. Часть договорных документов утверждается ЭП, а потому, для налоговой службы они выгружаются со штампом. Реализован подобный механизм выгрузки счетов на закупку из учетной системы. Реализованы сценарии, используемые другими системами для установки штампов на документы в DIRECTUM не связанные с ЭП. 

Команда

Тарасов М. В. - Программист

Колесов А. Д. - Руководитель бюро.

Номинация: Forum
Утверждено 30 5

Комментарии (5)

Артем Сергеев

Если не секрет каким образом реализовано ожидание клиентом выполнение сценария на сервере (серверное событие). Для отображения документа используется webControl с какими-то js библиотеками? или другая магия?

Михаил Тарасов

При вызове метода Start у серверного события он возвращает ИД этого события.

Написал простенькую функцию, она раз в секунду делает запрос на сервер, проверяет состояние события. При его завершении выходит из цикла. При статусе с ошибкой, копирует текст ошибки и бросает исключение с этим текстом. Всё просто.

Что касается документа, то в статье пытался описать это подробно. Никакой магии, изображение страницы получаю в виде PNG файла с помощью ImageMagick. А уж отображать картинки то любой браузер умеет без всяких библиотек.

Михаил Тарасов: обновлено 25.01.2019 в 22:08
Роман Деменков

"Работает механизм не быстро. На разворот штампа уходит 3-10 секунд. Но, надобность в этом возникает не часто."

Можно попробовать чуть более быстрые варианты, к примеру imaginary:

It uses internally libvips, a powerful and efficient library written in C for image processing which requires a low memory footprint and it's typically 4x faster than using the quickest ImageMagick and GraphicsMagick settings or Go native image package, and in some cases it's even 8x faster processing JPEG images.
Михаил Тарасов

Роман, спасибо. Вариант интересный. Должен работать быстрее хотя бы по тому, что работает в качестве сервиса и его не надо запускать через серверное событие .

Артем Сергеев

Михаил, спасибо за ответ.

Авторизуйтесь, чтобы написать комментарий