Время на прочтение
5 мин
Количество просмотров 69K
Добрый день, Хабрахабр.
Благодаря тепло принятой прошлой публикации, я могу опубликовать здесь эту статью. Спасибо всем, кто ставил плюсы.
По долгу службы мне частенько приходится формировать отчеты для этикеточных принтеров семейства Zebra.
Зебры они такие
Механизм формирования этикеток выглядит следующим образом: сначала с машины пользователя (компьютер, терминал сбора данных) на принтер отправляется специальным образом оформленная строка, затем внутренний процессор принтера обрабатывает эту строку, и выводит ее на печать.Но язык, на котором формируется строка для принтера (называется ZPL) на первый взгляд вызывает у непосвящённых нервную икоту и мандраж.
Прошу под кат, всех кто хочет разобраться в данном вопросе.
Пример:
^XA
^FO 0,10
^GB632,0,2^FS
^FO0,25
^FB632,1,0,C,0
^ASN,70,70
^FDWAR INC.^FS
^FO0,100
^GB632,0,2^FS
^FO0,120
^FB632,1,0,C,0
^ASN,60,60
^FDGoose^FS
^FO0,180
^FB632,1,0,C,0
^ASN,60,60
^FDWild^FS
^FO0,240
^GB632,0,2^FS
^FO120,260
^BY2
^BCN,70,N,N,N
^FDSECRECTCODE^FS -
^XZ
А на печать выводится такой аккуратный бейджик:
Давайте разберемся, что же написано в этом коде, и рассмотрим основные элементы.
Первую часть своего выступления я посвящу разбору синтаксиса этого языка, в объеме достаточном для создания этикеток удовлетворительного качества. Во-второй части, приведу примеры кода на Java и VisualBasic, для того, чтобы отправить этикетку на печать самостоятельно. На основе этих примеров, вы сможете самостоятельно построить свою програму, для печати.
Часть 1. Синтаксис ZPL
Во первых, все измерения в ZPL указываются в точках (points). Поэтому, для более ясного представления вы должны посмотреть в документации на принтер, какая у вас плотность точек на единицу измерения длины.
Сначала кратко пробежимся по основным командам, затем рассмотрим их более подробно в связке.
1. Начало и конец ZPL-кода:
^XA – начало кода, ^XZ – конец кода;
2.Отступы для последующего содержимого:
^FO x,y где: x – отступ от левого края, y – отступ сверху;
3.Разделитель полей:
^FS — обозначает конец определения поля. Буквально можно считать его сигналом конца строки;
4.Масштабируемый текст. Состоит из двух частей, выбор шрифта и ввод текста:
4.1. Выбор шрифта:
^A<название шрифта><ориентация текста>,<высота шрифта в точках>,<ширина в точках>:
<название шрифта> – по-умолчанию стоит A. Точнее ее даже не надо вводить, другие шрифты можно взять из официальной документации:
<ориентация текста>:
N – нормальная ориентация; R – повернуто на 90 градусов по часовой стрелке;
I – перевернуто на 180 градусов; B – повернуто на 270 градусов;
4.2. Вывод текста с параметрами указанными в предыдущем пункте:
^FD<текст>
Примеры:
^XA
^FO20,20 - отступ по 20 точек от верхнего и левого края этикетки
^ASN,70,70 - нормальная ориентация, шрифт S, высота и ширина 70 точек
^FDWAR INC.^FS – содержание текста WAR INC.
^XZ
Повернем, и изменим шрифт:
^XA
^FO20,20 - отступ по 20 точек от верхнего и левого края этикетки
^ABB,30,30 - повернуто на 270 градусов, шрифт B, высота и ширина 30 точек
^FDWAR INC.^FS – содержание текста WAR INC.
^XZ
Изменим шрифт на S:
^XA
^FO20,20 - отступ по 20 точек от верхнего и левого края этикетки
^ASB,30,30 - повернуто на 270 градусов, шрифт S, высота и ширина 30 точек
^FDWAR INC.^FS – содержание текста WAR INC.
^XZ
Обязательно запомните, что разные шрифты могут выглядеть по разному, в отношении размеров, как можно видеть выше. Я чаще всего использую шрифт S.
5.Блок текста:
^FB<ширина>,<количество строк>,<пробелы между строками>,<выравнивание текста>,< отступ для второй или последующей строки>
<положение текста> — может принимать значения: L(по левому краю), R (по правому краю), C (по центру), J (растянуть текст по ширине поля);
Обычно я использовал данную команду для центрирования текста, или если необходимо разместить текст в несколько строчек. Если текст не умещается в строку, он начинает накладываться сам на себя. И получается так:
^XA
^FO 20,20
^FB400,1,0,C,0
^AVN,70,70
^FDWAR INC WILD GOOSE^FS
^XZ
Изменим код, чтобы было две строки, и расстояние между строчками сделаем в 10 точек:
^XA
^FO 20,20
^FB400,2,10,C,0
^AVN,70,70
^FDWAR INC WILD GOOSE^FS
^XZ
А теперь сделаем отступ для второй строки в 30 точек влево:
^XA
^FO 20,20
^FB400,2,10,L,30
^AVN,70,70
^FDWAR INC WILD GOOSE^FS
^XZ
6. Рисование прямоугольников:
^GB<ширина>,<высота>,<толщина линии>, (<цвет линии>, <скругление углов>)
В скобках указаны не обязательные параметры.
Цвет линии: B (черный) или W (белый)
Скругление углов указывается цифрой от 0, до 8 (сильное скругление)
Примеры:
С сильным скруглением:
^XA
^FO20,20
^GB300,100,2,B,8^FS
^XZ
Без скругления:
^XA
^FO20,20
^GB300,100,2^FS
^XZ
Если хотим нарисовать просто линию, то рисуем прямоугольник с высотой равной 0:
^XA
^FO20,20
^GB300,0,2^FS
^XZ
7.Штрихкод состоит из трех команд – первая задает его размеры, вторая настройки и третья — содержание:
7.1.Размеры штрихкода:
^BY<ширина>, (<cоотношение толщин линий>, <высота штрихкода>)
7.2. Настройки штрихкода:
^BC<ориентация>,<высота штрихкода в точках>, <печатать ли расшифровку кода>, <расшифровка кода над штрихкодом>, <режим>
<ориентация> — N – нормальная ориентация; R – повернуто на 90 градусов по часовой стрелке; I – перевернуто на 180 градусов; B – повернуто на 270 градусов;
<печатать ли расшифровку кода>, <расшифровка кода над штрихкодом> — принимают значения Y (да) или N (нет);
<режим> — с этим полем я не разобрался, по умолчанию N;
^BC – штрихкод в стандарте 128 (подробнее Code_128); Есть также еще несколько форматов, но ввиду того, что мне не приходилось ими пользоваться, в данной статье они рассматриваться не будут, и рекомендую посмотреть информацию по ним в официальной документации поставляемой к принтерам Zebra;
7.3. Вывод штрихкода на печать:
^FD<кодируемая информация>
К сожалению, штрихкод нельзя поместить в «коробку», как текст, чтобы отцентрировать по ширине этикетки, и поэтому приходится шаманить с полями и отступами.
Примеры:
^XA
^FO 20,20
^BY3
^BCN,100,Y,N,N
^FD123456789^FS
^XZ
Перевернем, и укажем печатать расшифровку сверху (сейчас получилось снизу):
^XA
^FO 20,20
^BY3
^BCI,100,Y,Y,N
^FD123456789^FS
^XZ
На этом остановимся на рассмотрении основных элементов ZPL, и перейдем к части второй, в которой вкратце рассмотрим механизм отправки информации на принтер.
Часть 2. Печать
Механизм передачи проще некуда. Для этого, мы должны знать IP, где находится принтер, и порт. Далее, формируем поток, который отправляем по указанному адресу, и получаем на выходе этикетку.
Пример на Visual Basic:
Dim i As Double
Dim SSCC As String
Dim ipAddress As String = "127.0.0.1"
Dim port As Integer = 1234
Dim ZPLString As String
Try
'Открываем соединение
Dim client As New System.Net.Sockets.TcpClient
client.Connect(ipAddress, port)
Dim writer As New System.IO.StreamWriter(client.GetStream())
'Формируем ZPL-строку
ZPLString=
"^XA" &
"^BY2" &
"^FO0,200" &
"^FB632,2,0,C,0" &
"^ASN,60,60" &
"^FDHELLO HABRAHABR!!!^FS" &
"^XZ"
writer.Write(ZPLString)
writer.Flush()
'закрываем соединение
writer.Close()
client.Close()
Catch ex As Exception
End Try
Пример на Java:
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
public class PrintToZebra {
public static void main(String[] args) throws IOException {
System.out.println("Готовлю к печати");
try(Socket s = new Socket("127.0.0.1", 1234)){
OutputStream out = s.getOutputStream();
PrintWriter writer = new PrintWriter(out, true);
String ZPLString=
"^XA" +
"^BY2" +
"^FO0,200" +
"^FB632,2,0,C,0" +
"^ASN,60,60" +
"^FDHELLO HABRAHABR!!!^FS" +
"^XZ";
writer.println(ZPLString);
writer.flush();
System.out.println("Отправил на печать");
}
}
}
Как видите, ничего сложного. Надеюсь, что моя статья, облегчит путь отважным укротителям Зебр.
Засим позвольте откланяться. Жду советов, критики и поддержки.
Введение | |
Простейший пример | |
Реальный пример | |
XA | |
PW | |
CI | |
RW | |
RS | |
RB | |
RF | |
FD | |
FN | |
HV | |
Python скрипты для печати ZPL | |
Похожие статьи |
Введение
Zebra Programming Language это более новая версия Eltron Programming Language
В 1998 году компании Zebra и Eltron объединились
ZPL FAQ
Описание команд на официальном сайте Zebra:
ZPL
.
Для наглядности команды я буду выделять жирным шрифтом, параметры постараюсь сделать цветными.
Введенный текст и передаваемые переменные оставлю обычными.
FT Examples available here
,
A Examples available here
Простейший пример
^XA
^LH30,
100
^FO20,10
^AD^FDWWW.AskQA.RU^FS
^FO20,
60^B3^FDWWW.URN.SU^FS
^XZ
Пояснения
^XA — Начало этикетки
^LH30,
100 — Задаёт начальную позицию 30 точек вправо и 100
точек вниз
^FO20,
10 — Field Origin, отступает ещё на 20 точек вправо и 10 вниз от точки,
которую мы определили предыдущей командой.
^A — Определяет шрифт.
В нашем случае ^AD выбран шрифт
D. По умолчанию стоит A. Шрифты, которые
соответсвуют этим буквам хранятся в EPROM принтера. ZPL II разрешает использовать буквы
A — Z и цифры 1 — 9.
^FD — Field Data, объявляет начало поля с данными
WWW.AskQA.RU — обычные данные которые я ввёл. Они будут просто напечатаны на теге.
^FS — Field Separator
^FO20,
60 — Отступаем по-прежнему 20 точек вправо, но теперь, чтобы
надписи не наложились друг на друга — 60 точек вниз.
^B3 — Этой командой мы показываем, что хотим распечатать баркод в формате
Code 39 (USD-3 Code, Code 3 of 9).
^FDWWW.URN.SU^FS — здесь всё как в предыдущем примере, но мы помним,
что теперь данные из поля будут не только распечатаны, но и изображены в виде баркода.
^XZ — Обозначает конец этикетки.
Результат
Пример файла для печати
На каждый параметр можно кликнуть чтобы перейти к подробному описанию. Любо просто пролистать вниз.
^XA
^PW366
^CI28
^RW24,24,A2
^FS
^RS8,B10,200,3,E
^FS
^RB96,8,3,3,24,20,38
^FS
^RFW,E
^FD48,0,5,6438092,0,#Serial#
^FS
^FN3^RFR,H
^FS
^HV3
^FT8,24^A0N,26,26^FD#ProductCode#
^FS
^FO8,36^A0N,26,26^FB300,10,,100^FD#ProductName#
^FS
^FT8,105^A0N,26,26^FD#Quantity#
^FS
^FT130,105^A0N,26,26^FD#UnitOfQuantity#
^FS
^FT8,128^A0N,26,26^FDASK.QA
^FS
^FT134,128^A0N,26,26^FD#Serial#
^FS
^XZ
Пояснения
1) Параметры, помещённые между символами решётки # — это переменные, которые
передаются с сервера. Для печати статичного изображения они не нужны, но на практике
теги печатаются большими сериями и серийный номер меняется автоматически.
#Serial#
2)
🔝
Print Width |
Change International Font |
Read and Write Power Levels
24 — Read Power
Чтобы узнать правильное положение антенны и бэкфида, нужно выполнить |
🔝
^RS — Задаёт RFID параметры
8 — (t) tag type тип тега. Gen 2 это единственный тип, поддерживаемый UHF Принтеры
Допустимые значения: 0 = None
Значение по умолчанию: 4
B10 — (p) Sets the read/write position
This parameter sets the read/write position of the transponder in one of two ways:
Important: If a label format specifies a value for the programming position, this value will Допустимые значения:
Absolute Mode:
Relative Mode Forward:
Relative Mode Backward:
Note: When using a backward program position, allow enough media or liner to ensure that the printer Значение по умолчанию: F0 (which moves the leading edge of the label to the print line)
200 — (v) — length of void printout — не рекомендуется использовать
3 — (n) — number of labels — The number of labels that will
E — (e) — error handling — |
🔝
^RB — Define EPC Data Structure
96
8,3,3,24,20,38 (p1 … p15) — partition sizes — Specify each
Разделение на поля происходит, естественно, не произвольным образом. В данном примере
96 — длина EPC блока. 8 — Header. 3 — Filter. 3 — Partition. 24 — Company Prefix. 20 — |
🔝
^RF — Read or Write RFID Format.
W — (o) — operation — The action to be performed. Accepted
E — (t) — type — Допустимые значения: A = ASCII, H = Hexadecimal, |
🔝
^FD
48,0,5,6438092,0,#Serial#
Что означают параметры 48,0,5,6438092,0,#Serial# после
^FD с первого взгляда непонятно. В описании у ^FD всего один параметр
(a) — data to be printed. Допустимые значения: any ASCII string up to 3072
characters
Значение по умолчанию: none — a string of characters must be entered.
Объяснение:
^FD у нас идёт не один, а в связке с ^RFW,
E и определённым перед ним ^RB96,
8,3,3,24,20,38
То есть нужно рассматривать всю комбинацию команд.
^RB96,8,3,3,24,20,38
^RFW,E^FD48,0,5,6438092,0,#Serial#
И при этом не забывать, что мы записываем теги в соответствии со стандартом
SGTIN-96
Название поля→ |
Общая длина |
Header | Filter | Partition | Company Prefix | Indicator / Item Reference | Серийный номер |
---|---|---|---|---|---|---|---|
Длина в битах → | 96 | 8 | 3 | 3 | 24 | 20 | 38 |
Что мы туда записываем → | N/A | 48 | 0 | 5 | 6438092 | 0 | #Serial# |
🔝
^FN — Field Number Description the ^FN command numbers the data fields. This command is used in both ^DF (Store Format) and ^XF (Recall Format) commands.
In a stored format, use the ^FN command where you would Format ^FN#
Comments
Example: The ^FN1«Name»
^RF — Read or Write RFID Format. This command allows you to read or write to an RFID tag.
Note: When using this command to read a tag, you may use a field variable to Printers That Support This Command: RXi, R110PAX4
Format ^RFo,
o = operation — The action to be performed.
t = type — Допустимые значения: A = ASCII, H = Hexadecimal,
b = starting block number — Допустимые значения: |
🔝
^HV — Host Verification
Description — This command is used to return data from specified fields, along with an
Format ^HV#,n,
# = field number specified with another command. The value
Допустимые значения: 0 to 9999
n = number of bytes to be returned
Допустимые значения: 1 to 256
h = header — Header (in uppercase ASCII characters) to be returned with
Acceptable values: 0 to 3072 characters |
🔝
^FT — Field Typeset
The ^FT command sets the field position, relative to the home position of Note: The ^FT command is capable of concantination of fields.
Format: ^FTx,y,
|
^FT8,24
8 — отступ слева
Description The ^FT command also sets the field position, relative to the home position of the label designated by the ^LH command. Format ^FTx,y
Text The origin is at the start of the character string, at the baseline of the font. Normally the baseline is the bottom of most characters, Bar Codes The origin is at the base of the bar code, even when an interpretation is present below the bar code, or if the bar code has guard bars. Graphic Boxes The origin is at the bottom-left corener of the box. Images The origin is at the bottom-left corner of the rectangular image area. Examples available here
When a coordinate is missing, the position following the last formatted field is assumed. This
There are several instances where using the ^FT command without specifying x and y parameters is not
^A0N,26,26^FD#ProductCode# ^A — Определяет шрифт.
В нашем случае ^A0 выбран шрифт 0 — parameter (f) — font name. По умолчанию стоит A. Шрифты, которые соответсвуют этим буквам хранятся в EPROM принтера.
N — parameter o = font orientation. Допустимые значения: N = normal, R = rotated 90 degrees (clockwise),
26,26 — это |
^FS
^FO8, 36 — Field Origin, отступает ещё на 8 точек вправо и 36 вниз от точки, которую мы определили командой ^LH (а точнее не определили).
^FB300,10, ^FB — Field Block
Description The ^FB command allows you to print text into a
Format ^FBa,b,
|
^FS
^FT8,105^A0N,26,26^FD#Quantity#^FS
^FT130,105^A0N,26,26^FD#UnitOfQuantity#^FS
^FT8,128^A0N,26,26^FDASK.QA^FS
^FT9,128^A0N,26,26^FDASK.QA^FS
^FT134,128^A0N,26,26^FD#Serial#^FS
^FT134,128^A0N,26,26^FD#Serial#^FS
^XZ
Основные команды
RFID калибровка
^XA
^HR
^XZ
start
position=B9 MM,A2,25,25
leading edge
B20, , ,A2,29,29
B19, , ,A2,29,29
B18,R, ,A2,29,29
B17, , ,A2,29,29
B16, , ,A2,29,29
B15,R,W,A2,17,21
B14,R,W,A2,11,15
B13,R,W,A2,7,11
B12,R,W,A2,5,9
B11,R,W,A2,5,7
B10,R,W,A2,5,9
B9,R,W,A2,5,11<—**** B9 MM,A2,25,25
B8,R,W,A2,11,15
B7,R,W,A2,23,23
B6, , ,A2,29,29
B5,R,W,A2,25,25
B4,R,W,A2,25,25
B3,R,W,A2,27,29
B2, , ,A2,29,29
trailing edge
end
Предпросмотр ZPL
ZPL симулятор для просмотра layout файлов
Создание штрихкодов
sscc-18
^FO250,50
^BY3,3,10
^BCN,110,N,N,N,N
^FD{SERIAL}^FS
^BY — Bar Code Field Default
The ^BY command is used to change the Значение по умолчаниюs for the module width (in dots),
Format: ^BYw
For parameter r, the actual ratio generated is a function
Example: Set module width (w) |
The ^BC command creates the Code 128 bar code, a high-density, variable length, continuous, alphanumeric symbology. It was designed for complexly encoded product identification.
Code 128 has three subsets of characters. There are 106 encoded printing characters in each set,
^BC supports a fixed print ratio.
Format: ^BCo,h,f,g,e,m
Format: ^BCo
|
Python скрипты для печати ZPL
Очень часто бывает нужно напечатать большое количество тэгов таким образом, чтобы
серийный номер возрастал на 1 у каждого следующего тэга.
Предположим, что серийный номер должен быть напечатан как в память тэга так и на этикетку.
Формат пусть будет
GIAI-96
, код компании помещается в 24 бита, для примера возьмём 1234567
Запишем сперва код для этикетки.
^XA
^CI28
^PW500^FS
^RW24,26,A2^FS
^RS8,B13,100,1,E^FS
^RB96,8,3,3,24,58^FS
^RFW,E^FD52,0,5,1234567,${userID},^FS
^FN3^RFR,H^FS
^HV3
^FWN^FO90, 15^AD,90,22^FDTVS^FS
^FT90,110^A0N,25,25^FH^FDUSER:${userID}
^FS
^XZ
Для создания скрипта нужно познакомиться с основами языка
Python
а также с
сокетами
, которые нужны для работы с сетью
import socket
mysocket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
host = "10.6.1.123"
port = 9100
try:
mysocket.connect((host, port)) #connecting to host
for i in range(100073,100100):
userId = str(i)
mysocket.send(b"^XA^CI28^PW500^FS")
mysocket.send(b"^RW24,26,A2^FS")
mysocket.send(b"^RS8,B13,100,1,E^FS")
mysocket.send(b"^RB96,8,3,3,24,58^FS")
mysocket.send(b"^RFW,E^FD52,0,5,1234567,")
mysocket.send(bytes(userId,"utf-8"))
mysocket.send(b",^FS")
mysocket.send(b"^FN3^RFR,H^FS")
mysocket.send(b"^HV3")
mysocket.send(b"^FWN^FO90, 15^AD,90,22^FDCompanyName^FS")
mysocket.send(b"^FT90,110^A0N,25,25^FH^FDUSER:")
mysocket.send(bytes(userId,"utf-8"))
mysocket.send(b"^FS^XZ")
mysocket.close () #closing connection
except:
print("Error with the connection")
Можно не писать в каждой строчке mysocket.send , а использовать Heredoc и Python f-string
import socket
mysocket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
host = "10.6.1.123"
port = 9100
try:
mysocket.connect((host, port)) #connecting to host
for i in range(100073,100100):
userId = str(i)
layout = (f"""
^XA^CI28^PW500^FS
^RW24,26,A2^FS
^RS8,B13,100,1,E^FS
^RB96,8,3,3,24,58^FS
^RFW,E^FD52,0,5,1234567,{userId},^FS
^FN3^RFR,H^FS
^HV3
^FWN^FO90, 15^AD,90,22^FDCompanyName^FS
^FT90,110^A0N,25,25^FH^FDUSER:{userId},^FS
^FS^XZ
""")
mysocket.send(bytes(layout,"utf-8"))
mysocket.close () #closing connection
except:
print("Error with the connection")
RFID | |
ZPL FAQ | |
A пример | |
FT примеры |
Автор:
Eugene Taylor
Дата создания:
11 Август 2021
Дата обновления:
15 Сентябрь 2023
Содержание
- Синтаксис команды
- Внешний вид этикетки
- Коробка и рисование линий
- Штрих-коды
Язык программирования Zebra (ZPL) — это проприетарный язык сценариев для принтеров этикеток, производимый Zebra Technologies. Язык позволяет вам контролировать внешний вид напечатанных этикеток. Например, вы можете добавить штрих-коды к этикеткам вместе с названием и адресом компании.
Синтаксис команды
Синтаксис ZPL: «^ XA», который запускает каждую команду форматирования, «^ FO», которая является командой источника поля; «^ FS» — команда разделителя полей; «^ FD», которая является командой поля данных, и «^ XZ», которая завершает каждую команду форматирования.
Внешний вид этикетки
Различные команды позволяют настраивать шрифты и другие аспекты внешнего вида этикеток, особенно текста. Например, команда «^ A» указывает шрифт для использования в текстовом поле, а команда «^ FD» определяет информационную строку для поля.
Коробка и рисование линий
Команда «^ GB» позволяет рисовать прямоугольники и линии, например, для разделения надписей на разные области. Параметры команды «^ GB» позволяют форматировать кадры и строки. Например, вы можете указать толщину границы или степень закругления углов.
Штрих-коды
Команда «^ B» позволяет печатать штрих-коды на этикетках, включая коды отраслевых стандартов 11 и 39. Вы можете изменить определенные аспекты штрих-кодов, включая ориентацию и высоту.