Pull to refresh

Как приготовить Зебру (Мой опыт в ZPL)

Reading time6 min
Views9.4K

Всем привет.

На текущем месте работы, в один момент, мне пришлось экстренно разобраться с печатью этикеток на принтеры Zebra. Так как информации в сети(особенно на русском) оказалось не так много, я как добросовестный программист обратился к документации. В этой статье хотелось бы сделать выжимку, для таких же счастливчиков как я, о том, что такое язык ZPL, как с ним работать и с чем я столкнулся в процессе своих познаний.

Как же всё работает

Если вкратце, то принтер Zebra и ему подобные, эмулирующие в себе ZPL, принимают на вход специальную строку с ПК, обрабатывают её и выводят на печать. Всё просто. Но вот как эту самую строку корректно сформировать, чтобы принтер всё понял?

Пример этикетки с QR-кодом

^XA
^FO50,80^A0,30,50 ^FDSamsung Galaxy S22^FS
^FO50,130^A0,30,50 ^FDSM-S908BDRHSKZ^FS
^FO50,180^A0,30,50 ^FDExynos 2200^FS
^FO50,230^A0,30,50 ^FDXclipse 920^FS
^FX Для примера этикетки взял информацию о смартфоне.
^FO490,30 ^BY5,2.0,50 ^BQN,2,6 ^FD   Смартфон Samsung Galaxy S22 Ultra^FS
^BY5,2,270
^FO50,280^BC^FD12345678^FS
^XZ

И вот что у нас получилось:

Что же мы имеем?

Исходя из представленного выше кода, управляющий символ в ZPL это "^". После него следует команда отвечающая за тот или иной аспект настройки этикетки.

Давайте же узнаем о них.

^XA и ^XZ - открывающий и закрывающий символ.

^FOx,y - отступ от левого верхнего края, принимает значение от 0 до 32000

^Af,h,w - изменение шрифта для последующего текста
f - сам шрифт, может быть в значении 0-9 либо A-Z
h - высота (от 1 до 32000)
w - ширина (от 1 до 32000)
Так же после f, перед запятой можно использовать символ вращения R - 90°, I - 180°, B - 270°

^FDdata - символ начала поля данных

^FS - символ конца определения поля

^FX - комментарий

Используя эти символы можно начать выводить простые текстовые этикетки.
Например:

^XA
^FO50,80^A0,30,50 ^FDSamsung Galaxy S22^FS
^FO50,150^AEI,5,5 ^FDSamsung Galaxy S22^FS
^FO50,230^AVR,30,50 ^FDSamsung Galaxy S22^FS
^FO180,230^AAB,50,20 ^FDSamsung Galaxy S22^FS
^XZ

Но стоит знать то, что не каждый шрифт поддаётся редактированию по размеру!
Получим:

^FB maxWidth, maxLines, lineSpacing, alignment, hangingIndent
maxWidth - ширина (от 0 до 9999)
maxLines - количество строк (от 1 до 9999)
lineSpacing - пробелы между строками (от -9999 до 9999)
alignment - выравнивание ( L (по левому краю), R (по правому краю), C (по центру),
J (растянуть текст по ширине поля) Дефолтное значение - L
hangingIndent - отступ от строки (от 0 до 9999)

Теперь добавим это в наш код и посмотрим, что будет:

^XA
^FB200,5,5,C
^FO50,80^A0,30,50 ^FDSamsung Galaxy S22^FS
^FB400,5,5,J
^FO50,220^A0,30,50 ^FDSamsung Galaxy S22^FS
^XZ

Первый текст получил "окно" шириной 200 точек и максимальным количеством строк = 5 с выравниванием по центру. В 200 точек влезало только одно слово, из-за этого текст разбился на 3 строки
А второй тест получил 400 точек и выравнивание по ширине поля. Два слова влезли в первую строку, но получился большой пробел, в который, однако, не влезло третье слово

Как видно, меняя эти параметры можно получить тест абсолютно любого формата

Штрих-коды

Штрих-кодов в документации описано огромное количество, но я для себя выделил 4 основных:

  1. ^BC - orientation, height, line, lineAbove, checkDigit, mode - Code 128 Bar code
    orientation - вращение (R - 90°, I - 180°, B - 270°)
    height - высота (от 1 до 32000)
    line - печатать ли расшифровку (Y,N)
    lineAbove - расшифровка сверху (Y,N)

^XA
^BY5,2,200
^FO50,50^BCN,,Y^FD12345678^FS
^XZ

Сразу опишу настройки, применимые ко всем штрих-кодам:
^BY width, widthRatio, height
width - ширина (от 1 до 100)
widthRatio - соотношение толщин линий (от 2.0 до 3.0 шаг 0.1)
height - высота (любое положительное число)
^FD - кодируемая информация

  1. ^BE - EAN-13 Bar Code
    Настройки такие же, что и у ^BC

^XA
^FO50,50^BY3
^BEN,80,Y
^FD000012345678^FS
^XZ
  1. ^BQ orientation, model, magnification, errorCorrection- QR Code Bar code
    orientation - вращение QR (R - 90°, I - 180°, B - 270°)
    model - обычный или улучшенyый QR (1 или 2) Важно! Современными принтерами Zebra, model(1) не воспринимается, рекомендовано использовать (2)
    magnification - увеличение QR (от 1 до 10)
    errorCorrection - H = ultra-high reliability level, Q = high reliability level, M = standard level L = high density level (Рекомендую использовать H)

    Ещё один важный момент
    По какой-то причине, некоторые принтеры не хотят воспринимать последний параметр после ^BQ, но воспринимают его после ^FD:

^FX вместо:
^XA
^FO50,50
^BQN,2,3,H
^FDSamsung Galaxy S22^FS
^XZ

^FX используй:
^XA
^FO50,50
^BQN,2,3
^FDH,Samsung Galaxy S22^FS
^XZ
  1. ^BX - orientation, height, quality, columns, rows, format, escape - Data Matrix
    orientation - думаю, тут уже понятно))
    height - высота (от 1 до размера листа)
    quality - качество DM (0, 50, 80, 100, 140, 200) рекомендованный - 200
    columns, rows - количество кодируемых колонок и строк (от 1 до 144)
    format - формат DM (от 0 до 6) не используется при качестве 200
    escape - эскейп символ, может использоваться любой символ, дефолтное значение тильда (~). При массовой печати стоит смотреть, не будет ли ваш эскейп символ передаваться в кодируемой информации. Я обычно использую бэкслеш (\)

С обычной кодировкой Data Matrix нет ничего сложного, просто передаётся информация и настраиваются параметры DM.
Например:

^XA
^FO50,50
^BXN,5,200,
^FDZPL (programming language) 
ZPL (short for Z-level Programming Language) is an array programming 
language designed to replace C and C++ programming languages in engineering 
and scientific applications. Because its design goal was to obtain 
cross-platform high performance, ZPL programs run fast on both sequential 
and parallel computers. Highly-parallel ZPL programs are simple 
and easy to write because it exclusively uses implicit parallelism.^FS
^XZ

Но как вам может быть известно, в России есть такая организация как "Честный знак" и они используют Data Matrix для маркировки товара(сигареты, алкоголь, обувь, лекарства)
В кодировку для Честного знака передаётся несколько полей, используя специальные разделители и передаваться они должны не просто строкой. DM то конечно составится, но только через проверку Честного знака он не пройдёт
В честном знаке используется открывающий символ FNC1 и разделители GS
Чтобы поставить FNC1 в начало строки необходимо использовать ваш ескейп символ и "1"
Т.е. ^BXN,5,200,,,,\,1 ^FD\1 и далее зашифрованный код маркировки
Символы GS как правило передаются внутри и прописывать из отдельно не приходится

Пример реальной этикетки Data Matrix:
P.S. Не обращайте внимание на непонятные символы переданные вместо текста, принтеры клиента лишь эмулируют ZPL, из-за чего не удалось установить на них драйвера для русского языка, в данном примере русские буквы пришлось зашифровать в URL.

^XA ^CI28
			^CFP,5,10 ^FO20,2 ^FH^FD_D0_9D_D0_B0_D0_B8_D0_BC_D0_B5_D0_BD_D0_BE_D0_B2_D0_B0_D0_BD_D0_B8_D0_B5 _D0_BF_D1_80_D0_BE_D0_B4_D1_83_D0_BA_D1_86_D0_B8_D0_B8: _D0_A0_D0_B5_D0_B7_D0_B8_D0_BD_D0_BE_D0_B2_D1_8B_D0_B5 _D0_A7_D0_81_D0_A0_D0_9D_D0_AB_D0_99^FS
			^CFP,5,10 ^FO20,20 ^FH^FD_D0_9C_D0_B0_D1_80_D0_BA_D0_B0_2F_D0_90_D1_80_D1_82_D0_B8_D0_BA_D1_83_D0_BB: Lemon Jelly/GRAD^FS
			^CFP,5,10 ^FO20,38 ^FH^FD_D0_A1_D0_BE_D1_81_D1_82_D0_B0_D0_B2 _D0_92_D0_B5_D1_80_D1_85_2F_D0_9F_D0_BE_D0_B4_D0_BA_D0_BB_D0_B0_D0_B4_D0_BA_D0_B0_2F_D0_9D_D0_B8_D0_B7: _D0_BF_D0_BE_D0_BB_D0_B8_D0_BC_D0_B5_D1_80_2F_D1_82_D0_B5_D0_BA_D1_81_D1_82_D0_B8_D0_BB_D1_8C_2F_D1_80_D0_B5_D0_B7_D0_B8_D0_BD_D0_B0^FS
			^CFP,5,10 ^FO20,56 ^FH^FD_D0_94_D0_B0_D1_82_D0_B0 _D0_B8_D0_B7_D0_B3: 202204 _D0_93_D0_B0_D1_80_D0_B0_D0_BD_D1_82_D0_B8_D0_B9_D0_BD_D1_8B_D0_B9 _D1_81_D1_80_D0_BE_D0_BA:30^FS
			^CFP,5,10 ^FO20,74 ^FH^FD_D0_A1_D1_82_D1_80_D0_B0_D0_BD_D0_B0 _D0_B8_D0_B7_D0_B3_D0_BE_D1_82_D0_BE_D0_B2_D0_B8_D1_82_D0_B5_D0_BB_D1_8C: _D0_9F_D0_9E_D0_A0_D0_A2_D0_A3_D0_93_D0_90_D0_9B_D0_98_D0_AF^FS
			^CFP,5,10 ^FO20,92 ^FH^FD_D0_9F_D1_80_D0_BE_D0_B8_D0_B7_D0_B2_D0_BE_D0_B4_D0_B8_D1_82_D0_B5_D0_BB_D1_8C: Design e More, S.A.^FS
			^CFP,5,10 ^FO20,110 ^FH^FD_D0_90_D0_B4_D1_80_D0_B5_D1_81 _D0_BF_D1_80_D0_BE_D0_B8_D0_B7_D0_B2_D0_BE_D0_B4_D0_B8_D1_82_D0_B5_D0_BB_D1_8F: Rua das Casas Queimadas n 567.4415-439 Grijo V/N Gaia, Portugal^FS
			^CFP,5,10 ^FO20,128 ^FH^FD_D0_9F_D1_80_D0_BE_D0_B4_D0_B0_D0_B2_D0_B5_D1_86 _D1_8E_D1_80_D0_B0_D0_B4_D1_80_D0_B5_D1_81 _D0_9E_D0_9E_D0_9E _D0_90_D0_A0_D0_95_D0_9D_D0_90 115 093 _D0_9C_D0_BE_D1_81_D0_BA_D0_B2_D0_B0 _D0_9F_D0_B0_D1_80_D1_82_D0_B8_D0_B9_D0_BD_D1_8B_D0_B9 _D0_BF_D0_B5_D1_80 _D0_B4 1^FS
			^CFP,5,10 ^FO20,146 ^FH^FD_D0_BA_D0_BE_D1_80_D0_BF 11 _D1_8D_D1_82_D0_B0_D0_B6 3 _D0_BA_D0_BE_D0_BC_D0_BD №34 _D0_98_D0_BD_D1_81_D1_82_D1_80_D1_83_D0_BA_D1_86_D0_B8_D1_8F _D0_BF_D0_BE _D1_83_D1_85_D0_BE_D0_B4_D1_83 _D0_B7_D0_B0 _D0_B8_D0_B7_D0_B4_D0_B5_D0_BB_D0_B8_D0_B5_D0_BC _D0_BF_D1_80_D0_B8_D0_BB_D0_B0_D0_B3_D0_B0_D0_B5_D1_82_D1_81_D1_8F^FS
			^CFP,5,10 ^FO20,164 ^FH^FD_D0_A0_D0_B5_D0_B7_D0_B8_D0_BD_D0_BE_D0_B2_D1_8B_D0_B5 _D0_A7_D0_81_D0_A0_D0_9D_D0_AB_D0_99^FS
			^CFP,5,10 ^FO20,182 ^FH^FDLemon Jelly^FS
			^CFP,5,10 ^FO20,200 ^FH^FDGRAD/231 11^FS
			^CFP,5,10 ^FO20,218 ^FH^FD02 black^FS
			^CFP,5,10 ^FO560,310 ^FH^FD04630162491475^FS
            ^CFP,5,10 ^FO560,330 ^FH^FD5aWoWlascYnb8^FS
			^FO 45,270 ^BY4 ^BEN,60,Y,N  ^FD2000016664232^FS 
			^FO465,265^GFA,294,294,7,,::1IF87FFE1IF8:::1EI0781E1E,:::::::::::1IF87FFE1E,:::1EI0781E1E,::::::::::::1IF8781E1IF8:::,: ^FS
			^CFT,5,10 ^FO600,25 ^FH^FD_D0_A0_D0_B0_D0_B7_D0_BC_D0_B5_D1_80^FS
			^CFT,5,10 ^FO635,100  ^FD037^FS
			^FO560,150 ^BXN,4,200,,,,\,1 ^FD\10104630162491475215aWoWlascYnb89100BE929+ipgNo9UkRCzC7IfwA5bk1MhoLw3tpy9377HN7wpKFuOnG3KAfasNiHNDjwjR019xcThmlABPWm1VJFj3dl1w==^FS
			^XZ

Отсканировав данный Data Matrix с помощью приложения Checkmark или Честный знак, вы увидите что он принадлежит Резиновым сапогам

P.P.S. для редактирования этикеток без печати я использую: Labelary Online ZPL Viewer
Там есть подсказки, для начала работы с ZPL это очень удобно.

Так же приложу ссылку на документацию: ZPL II Programming Guide (servopack.de)

Спасибо за уделённое время, буду рад вашим советам

Tags:
Hubs:
Total votes 4: ↑4 and ↓0+4
Comments13

Articles