Как реализовать автоматический перенос строк и межстрочный интервал при печати этикеток на языке принтера (ZPL, TSPL)?

Программист Торговля и дистрибуция
← На главную

Печать этикеток из 1С часто реализуется через графический макет (табличный документ), который отправляется на Windows-драйвер. Однако при больших объемах печати, работе через RDP или необходимости идеальной четкости штрихкодов программисты прибегают к прямой печати на языке принтера (ZPL, TSPL, EPL). Одной из главных сложностей здесь является вывод длинных наименований: как заставить принтер самостоятельно переносить слова и соблюдать межстрочный интервал? Разберем современные способы решения этой задачи.

Зачем использовать языки принтера вместо обычных макетов?

Прежде чем перейти к коду, выясним причины, по которым профессиональная разработка в 1С часто требует ухода от графической печати:

  1. Скорость: Команда в текстовом виде (1-2 Кб) передается мгновенно, в отличие от тяжелого графического образа.
  2. Четкость: Штрихкод, сформированный внутренними алгоритмами принтера, всегда имеет идеальные границы, что критично для маленьких этикеток.
  3. Стабильность в RDP: Графическая печать через проброшенные порты часто «тормозит» или выдает ошибки, тогда как текстовый поток RAW проходит без искажений.

Решение для принтеров Zebra (язык ZPL II)

Вопреки распространенному мнению, что ZPL печатает только «строку в строку», в нем существует мощная команда для работы с текстовыми блоками — ^FB (Field Block). Она позволяет определить границы прямоугольника, внутри которого принтер сам управляет текстом.

Рассмотрим структуру команды ^FB:

^FB[ширина],[макс_строк],[интервал],[выравнивание],[отступ]

Проанализируем пример кода для 1С, который выводит длинное наименование с автоматическим переносом и увеличенным интервалом:


КомандаZPL = "^XA" + // Начало этикетки
             "^CI28" + // Установка кодировки UTF-8
             "^FT50,100" + // Позиция блока (X=50, Y=100)
             "^A0N,30,30" + // Выбор шрифта (высота 30)
             "^FB400,3,10,C,0" + // Блок: ширина 400, до 3 строк, интервал +10, по центру
             "^FDДлинное наименование товара для проверки переноса слов^FS" + 
             "^XZ"; // Конец этикетки

В данном примере принтер самостоятельно разобьет строку на пробелах так, чтобы она вписалась в ширину 400 точек. Если вам нужно принудительно разорвать строку в определенном месте, используйте маркер \& внутри данных ^FD.

Решение для принтеров TSC, Godex, Gprinter (язык TSPL)

Принтеры, поддерживающие TSPL (один из самых популярных языков в бюджетном сегменте), предлагают еще более продвинутую команду — BLOCK. Она позволяет не только переносить текст, но и динамически подбирать размер шрифта.

Синтаксис команды:

BLOCK x, y, width, height, "font", rotation, x-multiplication, y-multiplication, [space], [align], [fit], "content"

Разберем ключевые параметры:

  1. space: прямое управление межстрочным интервалом в точках.
  2. align: выравнивание (1 - слева, 2 - по центру, 3 - справа).
  3. fit: если текст не помещается, принтер попытается уменьшить его размер (очень полезно для длинных названий).

Посмотрим на пример формирования строки для TSPL:


ТекстКоманды = "SIZE 48 mm, 30 mm" + Символы.ПС;
ТекстКоманды = ТекстКоманды + "CLS" + Символы.ПС;
// Выводим блок текста с координатами 20,20, шириной 400 и высотой 150
// Используем шрифт "3", интервал 12 точек, выравнивание по центру
ТекстКоманды = ТекстКоманды + "BLOCK 20,20,400,150,""3"",0,1,1,12,2,1,""Наименование очень длинного товара с автопереносом""" + Символы.ПС;
ТекстКоманды = ТекстКоманды + "PRINT 1,1" + Символы.ПС;

Как быть, если принтер старый (например, Zebra LP 2824 на EPL)?

В старых моделях или упрощенных диалектах (EPL2) встроенных функций блока может не быть. В этом случае задачу переноса строк нам придется решать на стороне 1С. Выясним алгоритм действий:

Шаг 1: Разбить строку на слова. Используем функцию СтрРазделить.

Шаг 2: Рассчитать длину строки. Для моноширинных шрифтов это просто (количество символов * ширина). Для пропорциональных шрифтов (где буква "i" уже буквы "W") потребуется таблица ширин символов, которую можно найти в документации к принтеру.

Шаг 3: Собрать строки. В цикле добавляем слова к текущей строке, пока ее суммарная ширина не превысит ширину этикетки.

Пример простой функции разбиения (без учета ширины символов, по количеству):


Функция РазбитьСтрокуДляПринтера(ИсходныйТекст, МаксСимволов)
    МассивРезультат = Новый Массив;
    Слова = СтрРазделить(ИсходныйТекст, " ");
    ТекущаяСтрока = "";
    
    Для Каждого Слово Из Слова Цикл
        Если СтрДлина(ТекущаяСтрока + " " + Слово) > МаксСимволов Тогда
            МассивРезультат.Добавить(СокрЛП(ТекущаяСтрока));
            ТекущаяСтрока = Слово;
        Иначе
            ТекущаяСтрока = ТекущаяСтрока + " " + Слово;
        КонецЕсли;
    КонецЦикла;
    МассивРезультат.Добавить(СокрЛП(ТекущаяСтрока));
    Возврат МассивРезультат;
КонецФункции

После получения массива строк мы просто выводим их командами TEXT или ^FT, увеличивая координату Y на нужный нам межстрочный интервал. Для прямой отправки команд на совместимые устройства также можно использовать внешнюю компоненту печати на принтерах Zebra и Godex.

Важные нюансы: Кодировки и Шрифты

При использовании ^FB или BLOCK часто возникает проблема с «кракозябрами» вместо кириллицы. Это происходит потому, что принтеры по умолчанию настроены на латиницу.

Для Zebra обязательно используйте команду ^CI28 для переключения в UTF-8 и убедитесь, что выбранный шрифт (например, шрифт ^A0) поддерживает кириллические символы. В некоторых случаях русские шрифты нужно предварительно загрузить в память принтера в формате .TTF.

Для TSPL-принтеров важно передавать текст в кодировке Windows-1251 или использовать встроенную поддержку UTF-8, если она предусмотрена прошивкой.

Заключение

Мы выяснили, что современные языки управления принтерами вполне способны брать на себя верстку текста. Использование команд типа ^FB (ZPL) или BLOCK (TSPL) избавляет разработчика 1С от необходимости писать сложные алгоритмы расчета ширины строк и позволяет сосредоточиться на логике бизнес-процесса. Это делает печать этикеток надежной, быстрой и профессиональной. Для отправки сформированных команд на мобильные устройства можно применить решение для печати на мобильных принтерах по Bluetooth и сети.

← На главную