Началось все с того, что в местном филиале одной организации с чрезвычайно централизованной IT-инфраструктурой потребовалось печатать квитанции с местным штрихкодом. Система выстроена с использованием всех современных технологий - 1С 8.3, клиент-сервер, УФ, работа через RemoteApp (фактически на удаленном рабочем столе на ферме терминальных серверов) на серверах за тридевять земель. И прав у пользователей нет ни на что лишнее. Удалось только выпросить админский доступ к базе для просмотра конфигурации и добавления внешних отчетов и печатных форм. Попутно выяснилось, что при печати с RemoteApp на локальный принтер толи винда, толи драйвер ужимает растровые изображения в табличных документах до состояния, что сканеры штрихкодов их не берут. Если к базе подключаться с локального места, без использования терминального сервера - картинка четкая. В данных условиях шрифт на терминальные сервера не поставить, возможности использовать внешние компоненты сильно ограничены. Если в документ вставить векторную картинку (WMF), то на печать она выходит в отличном качестве.
Для решения задачи в данных условиях сделал две обработки по созданию растровых и векторных картинок, и на их базе создал эту обработку.
При печати изображений локально или из терминальной сессии с использованием драйвера конкретного используемого принтера изображения четкие всегда.
При печати из терминальной сессии (или RemoteApp) и использованием универсального драйвера в WinServer2008+ результат такой (картинка отображается в уменьшеном виде):
В первой колонке штрихкоды выведены как растровая картинка. На CODE128, EAN8 и CODABAR хорошо видно размытие изображения драйвером печати. Такой штриход большинство сканеров не возьмут.
К использованию предлагаю три метода формирования штрихкода:
- создание растровой картинки (BMP или PNG)
- создание векторной картинки (WMF)
- непосредственно внедрение в табличный документ набора прямоугольников, создающих штрихкод
Первые два метода возвращают системный объект "Картинка", доступный к использованию в любом месте, третий применим только к табличным документам.
Выяснилось, что если в табличный документ внедрить векторную картинку, то она не отобразится при сохранении документа в PDF. Так же векторные изображения не поддерживаются мобильной платформой.
Все три метода могут выводить штрихкод как сам по себе, так и с подписью, но в силу доступных возможностей подпись может выглядеть не очень удачно.
Так же выяснилось, что 1С использует технологию WISI-FIG (гляжу в книгу вижу фигу), что, в отличии от WISIWIG, не гарантирует что векторное изображение будет корректно показано при предварительном просмотре (казалось бы!).
Поддерживаются типы штрихкодов:
- CODE128 - универсальный код, позволяет кодировать символы с кодами от 0 до 127, содержит скрытую контрольную сумму для контроля считывания, компактно кодирует цифровые последовательности
- CODE39
- CODABAR
- EAN8 - цифровой код фиксированной длины 8 цифр, 7 значащих и контрольная цифра (расчитывается автоматически)
- EAN13 - популярный товарный код, кодирует 13 цифр, 12 значащих и контрольную цифру (расчитывается автоматически)
Обработка экспортирует следующие функции:
//Формирует из заданного текста картину указанного формата
//текст - кодируемый текст
//тип - формат штрихкода из поддерживаемых
//ФорматИзображения - формат картинки типа ФорматКартинки.
//ВключитьТекст(булево) - требуется ли рисовать подпись под кодом
//ЦветФона - объект типа Цвет(абсолютный) для задания фона изображения, по умолчанию белый Цвет(255,255,255)
//ЦветКода - объект типа Цвет(абсолютный) для задания цвета изображения, по умолчанию черный Цвет(0,0,0)
//Ширина - ширина результирующей картинки в пикселях
//Высота - высота результирующей картинки в пикселях
//
//Возвращает объект Картинка
Функция ПолучитьКартинкуЛинейногоШК(текст,тип,ФорматИзображения=Неопределено,ВключитьТекст=Ложь,ЦветФона=Неопределено,ЦветКода=Неопределено,Ширина=Неопределено,Высота=Неопределено) Экспорт
Функция возвращает объект Картинка с указанным штрихкодом. По умолчанию "ширина" подбирается так: по три пикселя на линию единичной ширины плюс отступы слева и справа в 5 линий (7 для EAN8 и EAN13). Высота по умолчанию - 40 пикселей плюс высота текста подписи если есть (для EAN8 и EAN13 - половина высоты подписи).
Для рисования непосредственно на Табличном документе, используются следующие функции (разница в способе задания местоположения штрихкода):
//Вставить в табличный документ штрихкод как набор прямоугольников
//тд - ТабличныйДокумент, в который требуется вставить штрихкод
//область - ОбластьЯчеекТабличногоДокумента, в которой требуется разместить штрихкод
//текст - содержимое штрихкода
//тип - формат штрихкода из поддерживаемых
//ВключитьТекст - добавить к рисунку подпись с текстом
//ЦветФона,ЦветКода - необязательные указания по цвету типа Цвет. По умолчанию белый и черный
//ВысотаТекста - высота области с подписью (используется если ВключитьТекст=Истина)
//РазмерШрифта - размер шрифта, используемого для вывода подписи
Процедура ВставитьВТабличныйДокументЛинейныйШКОбласть(тд,область,текст,тип,ВключитьТекст=Ложь,ЦветФона=Неопределено,ЦветКода=Неопределено,ВысотаТекста=4,РазмерШтрифта=10) Экспортбражения=Неопределено,ВключитьТекст=Ложь,ЦветФона=Неопределено,ЦветКода=Неопределено,Ширина=Неопределено,Высота=Неопределено) Экспорт
//Вставить в табличный документ штрихкод как набор прямоугольников
//тд - ТабличныйДокумент, в который требуется вставить штрихкод
//лево,верх,ширина,высота - размер и положение области в мм, куда требуется вставить штрихкод
//текст - содержимое штрихкода
//тип - формат штрихкода из поддерживаемых
//ВключитьТекст - добавить к рисунку подпись с текстом
//ЦветФона,ЦветКода - необязательные указания по цвету типа Цвет. По умолчанию белый и черный
//ВысотаТекста - высота области с подписью (используется если ВключитьТекст=Истина)
//РазмерШрифта - размер шрифта, используемого для вывода подписи
Процедура ВставитьВТабличныйДокументЛинейныйШККоординаты(тд,лево,верх,ширина,высота,текст,тип,ВключитьТекст=Ложь,ЦветФона=Неопределено,ЦветКода=Неопределено,ВысотаТекста=4,РазмерШтрифта=10) Экспорт
Результаты внедрения
Использование растровой картинки для штрихкода (форматы BMP и PNG) имеет смысл только если нет возможности импользовать внешние компоненты, т.к. формирование растрового изображения, особенно с подписью, занимает заметное время - до пары секунд, а так же при использовании на мобильной платформе.
Использование векторной картинки (WMF) подойдет для любого применения, кроме необходимости сохранения табличного документа в PDF. В этом случае необходимо использовать третий метод - размещение рисунка непосредственно в табличном документе.
Поскольку всё реализовано средствами платформы, данную обработку можно использовать в режиме мобильного приложения, и, вероятно, и Web-приложения (не проверял).
На мобильной платформе 8.3.5.96 (Android) не поддерживаются изображения формата WMF, а табличные рисунки разъезжаются. Растровые рисунки хорошо отображаются.
Данная обработка содержит примеры использования как в режиме обычных, так и управляемых форм. По кнопке "тест-лист" выводится табличный документ с примерами всех штрихкодов всеми методами.
Провел замеры производительности - в течении 20 секунд формировал штрихкоды различными методами.
Результаты замера в режиме толстого клиента:
BMP+подпись: 17шт, 0,85шт/с
BMP: 66шт, 3,3шт/с
WMF: 479шт, 23,95шт/с
Табличный рисунок: 1 744шт, 87,2шт/с
Результаты замера в режиме управляемых форм:
BMP+подпись: 18шт, 0,9шт/с
BMP: 73шт, 3,65шт/с
WMF: 530шт, 26,5шт/с
Табличный рисунок: 98шт, 4,9шт/с
В толстом клиенте самый быстрый способ - вставка ТабличныхРисунков в ТабличныйДокумент. В тонком клиенте он существенно медленнее, наибольшее быстродействие показывает формирование векторного изображения.
В обновленной версии добавлена возможность указать явно ширину линии для растрового изображения (по умолчанию 3, уменьшение приведет к ускорению работы), а так же немного ускорено формирование изображения за счет оптимизации преобразования данные->base64 строка.
При необходимости рассмотрю пожелания по доработке данного модуля, например, добавление форматов линейных штрихкодов.
Если данная обработка помогла, буду признателен за любое "спасибо" на яндекс-кошелек 41001287590231