Unicode characters on ZPL printer

96,757

Solution 1

I just discovered that you need to escape characters above ASCII by first putting ^FH before any ^FD fields that could contain a utf character and you need to prefix the utf-8 hex code with an underscore

_D0_94 will print as Д. My final ZPL code is as follows:

^XA
^LH100,150
^CWT,E:TT0003M_.FNT
^CFT,30,30
^CI28
^FT0,0^FH^FDTesting 1 2 3^FS
^FT0,50^FH^FD_D0_94_D0_BE _D1_81_D0_B2_D0_B8_D0_B4_D0_B0_D0_BD_D0_B8_D1_8F^FS
^FT0,100^B3^FDAAA001^FS
^XZ

I'm just going to have to make a way to generate the escape sequences, which should be much easier!

Solution 2

I had the same problem, you should add an ^FH(Field Hexadecimal Indicator) before any ^FD(Field Data) command that contains special characters, in my case I need spanish chars so I had to use ^CI28(Change International Font/Encoding)

UTF 8 HEX codes list

sample: to print Alvaro Jesús Pérez Peñaranda we need to convert those special characters to UTF 8 Hex code and add an _ before each code, this is the result: Alvaro Jes_c3_bas P_c3_a9rez Pe_c3_b1aranda

^XA

^CI28
^FO60,75
^ASN,36,20^FH^FDAlvaro Jes_c3_bas P_c3_a9rez Pe_c3_b1aranda^FS

^XZ

Solution 3

I'm using Zebra ZM400 printer and use TT0003M_ font.

this font does not print kazakh cyrillic.

if you want to print cryillic + kazakh cyrillic + latin alphabet, use ARI000.FNT (arial font)

I'm using the following method convert char to hex code

I hope this helps

stringConverTextToHex(stringtext)
{
stringnewText="";
char[]charArray=text.ToCharArray();
foreach(charcincharArray)
{
switch(c)
{
case'й':
newText+="_D0_B9";
break;
case'Й':
newText+="_D0_99";
break;
case'ц':
newText+="_D1_86";
break;
case'Ц':
newText+="_D0_A6";
break;
case'у':
newText+="_D1_83";
break;
case'У':
newText+="_D0_A3";
break;
case'к':
newText+="_D0_BA";
break;
case'К':
newText+="_D0_9A";
break;
case'е':
newText+="_D0_B5";
break;
case'Е':
newText+="_D0_95";
break;
case'н':
newText+="_D0_BD";
break;
case'Н':
newText+="_D0_9D";
break;
case'г':
newText+="_D0_B3";
break;
case'Г':
newText+="_D0_93";
break;
case'ш':
newText+="_D1_88";
break;
case'Ш':
newText+="_D0_A8";
break;
case'щ':
newText+="_D1_89";
break;
case'Щ':
newText+="_D0_A9";
break;
case'з':
newText+="_D0_B7";
break;
case'З':
newText+="_D0_97";
break;
case'х':
newText+="_D1_85";
break;
case'Х':
newText+="_D0_A5";
break;
case'ъ':
newText+="_D1_8A";
break;
case'Ъ':
newText+="_D0_AA";
break;
case'ф':
newText+="_D1_84";
break;
case'Ф':
newText+="_D0_A4";
break;
case'ы':
newText+="_D1_8B";
break;
case'Ы':
newText+="_D0_AB";
break;
case'в':
newText+="_D0_B2";
break;
case'В':
newText+="_D0_92";
break;
case'а':
newText+="_D0_B0";
break;
case'А':
newText+="_D0_90";
break;
case'п':
newText+="_D0_BF";
break;
case'П':
newText+="_D0_9F";
break;
case'р':
newText+="_D1_80";
break;
case'Р':
newText+="_D0_A0";
break;
case'о':
newText+="_D0_BE";
break;
case'О':
newText+="_D0_9E";
break;
case'л':
newText+="_D0_BB";
break;
case'Л':
newText+="_D0_9B";
break;
case'д':
newText+="_D0_B4";
break;
case'Д':
newText+="_D0_94";
break;
case'ж':
newText+="_D0_B6";
break;
case'Ж':
newText+="_D0_96";
break;
case'э':
newText+="_D1_8D";
break;
case'Э':
newText+="_D0_AD";
break;
case'я':
newText+="_D1_8F";
break;
case'Я':
newText+="_D0_AF";
break;
case'ч':
newText+="_D1_87";
break;
case'Ч':
newText+="_D0_A7";
break;
case'с':
newText+="_D1_81";
break;
case'С':
newText+="_D0_A1";
break;
case'м':
newText+="_D0_BC";
break;
case'М':
newText+="_D0_9C";
break;
case'и':
newText+="_D0_B8";
break;
case'И':
newText+="_D0_98";
break;
case'т':
newText+="_D1_82";
break;
case'Т':
newText+="_D0_A2";
break;
case'ь':
newText+="_D1_8C";
break;
case'Ь':
newText+="_D0_AC";
break;
case'б':
newText+="_D0_B1";
break;
case'Б':
newText+="_D0_91";
break;
case'ю':
newText+="_D1_8E";
break;
case'Ю':
newText+="_D0_AE";
break;
case'ӑ':
newText+="_D3_91";
break;
case'Ӑ':
newText+="_D3_90";
break;
case'ӓ':
newText+="_D3_93";
break;
case'Ӓ':
newText+="_D3_92";
break;
case'ә':
newText+="_D3_99";
break;
case'Ә':
newText+="_D3_98";
break;
case'ӛ':
newText+="_D3_9B";
break;
case'Ӛ':
newText+="_D3_9A";
break;
case'ӕ':
newText+="_D3_95";
break;
case'Ӕ':
newText+="_D3_94";
break;
case'ґ':
newText+="_D2_91";
break;
case'Ґ':
newText+="_D2_90";
break;
case'ѓ':
newText+="_D1_93";
break;
case'Ѓ':
newText+="_D0_83";
break;
case'ғ':
newText+="_D2_93";
break;
case'Ғ':
newText+="_D2_92";
break;
case'ӷ':
newText+="_D3_B7";
break;
case'Ӷ':
newText+="_D3_B6";
break;
case'ҕ':
newText+="_D2_95";
break;
case'Ҕ':
newText+="_D2_94";
break;
case'ђ':
newText+="_D1_92";
break;
case'Ђ':
newText+="_D0_82";
break;
case'ѐ':
newText+="_D1_90";
break;
case'Ѐ':
newText+="_D0_80";
break;
case'ӗ':
newText+="_D3_97";
break;
case'Ӗ':
newText+="_D3_96";
break;
case'ҽ':
newText+="_D2_BD";
break;
case'Ҽ':
newText+="_D2_BC";
break;
case'ҿ':
newText+="_D2_BF";
break;
case'Ҿ':
newText+="_D2_BE";
break;
case'є':
newText+="_D1_94";
break;
case'Є':
newText+="_D0_84";
break;
case'ӂ':
newText+="_D3_82";
break;
case'Ӂ':
newText+="_D3_81";
break;
case'җ':
newText+="_D2_97";
break;
case'Җ':
newText+="_D2_96";
break;
case'ӝ':
newText+="_D3_9D";
break;
case'Ӝ':
newText+="_D3_9C";
break;
case'ҙ':
newText+="_D2_99";
break;
case'Ҙ':
newText+="_D2_98";
break;
case'ӟ':
newText+="_D3_9F";
break;
case'Ӟ':
newText+="_D3_9E";
break;
case'ӡ':
newText+="_D3_A1";
break;
case'Ӡ':
newText+="_D3_A0";
break;
case'ѕ':
newText+="_D1_95";
break;
case'Ѕ':
newText+="_D0_85";
break;
case'ѝ':
newText+="_D1_9D";
break;
case'Ѝ':
newText+="_D0_8D";
break;
case'ӥ':
newText+="_D3_A5";
break;
case'Ӥ':
newText+="_D3_A4";
break;
case'ӣ':
newText+="_D3_A3";
break;
case'Ӣ':
newText+="_D3_A2";
break;
case'і':
newText+="_D1_96";
break;
case'І':
newText+="_D0_86";
break;
case'ї':
newText+="_D1_97";
break;
case'Ї':
newText+="_D0_87";
break;
case'Ӏ':
newText+="_D3_80";
break;
case'ҋ':
newText+="_D2_8B";
break;
case'Ҋ':
newText+="_D2_8A";
break;
case'ј':
newText+="_D1_98";
break;
case'Ј':
newText+="_D0_88";
break;
case'қ':
newText+="_D2_9B";
break;
case'Қ':
newText+="_D2_9A";
break;
case'ҟ':
newText+="_D2_9F";
break;
case'Ҟ':
newText+="_D2_9E";
break;
case'ҡ':
newText+="_D2_A1";
break;
case'Ҡ':
newText+="_D2_A0";
break;
case'ӄ':
newText+="_D3_84";
break;
case'Ӄ':
newText+="_D3_83";
break;
case'ҝ':
newText+="_D2_9D";
break;
case'Ҝ':
newText+="_D2_9C";
break;
case'ӆ':
newText+="_D3_86";
break;
case'Ӆ':
newText+="_D3_85";
break;
case'љ':
newText+="_D1_99";
break;
case'Љ':
newText+="_D0_89";
break;
case'ӎ':
newText+="_D3_8E";
break;
case'Ӎ':
newText+="_D3_8D";
break;
case'ӊ':
newText+="_D3_8A";
break;
case'Ӊ':
newText+="_D3_89";
break;
case'ң':
newText+="_D2_A3";
break;
case'Ң':
newText+="_D2_A2";
break;
case'ӈ':
newText+="_D3_88";
break;
case'Ӈ':
newText+="_D3_87";
break;
case'ҥ':
newText+="_D2_A5";
break;
case'Ҥ':
newText+="_D2_A4";
break;
case'њ':
newText+="_D1_9A";
break;
case'Њ':
newText+="_D0_8A";
break;
case'ӧ':
newText+="_D3_A7";
break;
case'Ӧ':
newText+="_D3_A6";
break;
case'ө':
newText+="_D3_A9";
break;
case'Ө':
newText+="_D3_A8";
break;
case'ӫ':
newText+="_D3_AB";
break;
case'Ӫ':
newText+="_D3_AA";
break;
case'ҩ':
newText+="_D2_A9";
break;
case'Ҩ':
newText+="_D2_A8";
break;
case'ҧ':
newText+="_D2_A7";
break;
case'Ҧ':
newText+="_D2_A6";
break;
case'ҏ':
newText+="_D2_8F";
break;
case'Ҏ':
newText+="_D2_8E";
break;
case'ҫ':
newText+="_D2_AB";
break;
case'Ҫ':
newText+="_D2_AA";
break;
case'ҭ':
newText+="_D2_AD";
break;
case'Ҭ':
newText+="_D2_AC";
break;
case'ћ':
newText+="_D1_9B";
break;
case'Ћ':
newText+="_D0_8B";
break;
case'ќ':
newText+="_D1_9C";
break;
case'Ќ':
newText+="_D0_8C";
break;
case'ў':
newText+="_D1_9E";
break;
case'Ў':
newText+="_D0_8E";
break;
case'ӳ':
newText+="_D3_B3";
break;
case'Ӳ':
newText+="_D3_B2";
break;
case'ӱ':
newText+="_D3_B1";
break;
case'Ӱ':
newText+="_D3_B0";
break;
case'ӯ':
newText+="_D3_AF";
break;
case'Ӯ':
newText+="_D3_AE";
break;
case'ү':
newText+="_D2_AF";
break;
case'Ү':
newText+="_D2_AE";
break;
case'ұ':
newText+="_D2_B1";
break;
case'Ұ':
newText+="_D2_B0";
break;
case'ҳ':
newText+="_D2_B3";
break;
case'Ҳ':
newText+="_D2_B2";
break;
case'һ':
newText+="_D2_BB";
break;
case'Һ':
newText+="_D2_BA";
break;
case'ҵ':
newText+="_D2_B5";
break;
case'Ҵ':
newText+="_D2_B4";
break;
case'ӵ':
newText+="_D3_B5";
break;
case'Ӵ':
newText+="_D3_B4";
break;
case'ҷ':
newText+="_D2_B7";
break;
case'Ҷ':
newText+="_D2_B6";
break;
case'ӌ':
newText+="_D3_8C";
break;
case'Ӌ':
newText+="_D3_8B";
break;
case'ҹ':
newText+="_D2_B9";
break;
case'Ҹ':
newText+="_D2_B8";
break;
case'џ':
newText+="_D1_9F";
break;
case'Џ':
newText+="_D0_8F";
break;
case'ӹ':
newText+="_D3_B9";
break;
case'Ӹ':
newText+="_D3_B8";
break;
case'ҍ':
newText+="_D2_8D";
break;
case'Ҍ':
newText+="_D2_8C";
break;
case'ӭ':
newText+="_D3_AD";
break;
case'Ӭ':
newText+="_D3_AC";
break;
case'A':
newText+="_41";
break;
case'a':
newText+="_61";
break;
case'B':
newText+="_42";
break;
case'b':
newText+="_62";
break;
case'C':
newText+="_43";
break;
case'c':
newText+="_63";
break;
case'D':
newText+="_44";
break;
case'd':
newText+="_64";
break;
case'E':
newText+="_45";
break;
case'e':
newText+="_65";
break;
case'F':
newText+="_46";
break;
case'f':
newText+="_66";
break;
case'G':
newText+="_47";
break;
case'g':
newText+="_67";
break;
case'H':
newText+="_48";
break;
case'h':
newText+="_68";
break;
case'I':
newText+="_49";
break;
case'i':
newText+="_69";
break;
case'J':
newText+="_4A";
break;
case'j':
newText+="_6A";
break;
case'K':
newText+="_4B";
break;
case'k':
newText+="_6B";
break;
case'L':
newText+="_4C";
break;
case'l':
newText+="_6C";
break;
case'M':
newText+="_4D";
break;
case'm':
newText+="_6D";
break;
case'N':
newText+="_4E";
break;
case'n':
newText+="_6E";
break;
case'O':
newText+="_4F";
break;
case'o':
newText+="_6F";
break;
case'P':
newText+="_50";
break;
case'p':
newText+="_70";
break;
case'R':
newText+="_52";
break;
case'r':
newText+="_72";
break;
case'S':
newText+="_53";
break;
case's':
newText+="_73";
break;
case'T':
newText+="_54";
break;
case't':
newText+="_74";
break;
case'U':
newText+="_55";
break;
case'u':
newText+="_75";
break;
case'V':
newText+="_56";
break;
case'v':
newText+="_76";
break;
case'Y':
newText+="_59";
break;
case'y':
newText+="_79";
break;
case'Z':
newText+="_5A";
break;
case'z':
newText+="_7A";
break;
case'':
newText+="";
break;
default:
newText+=c;
break;
}
}
returnnewText;
}

this is the sample code


^SP ^XA ^PON^FS ^FPH^FO102,63,0 ^A@N,60,60,E:ARIOOO_.FNT ^FH^FD_42_75_72_61_6B _D0_A8_D3_99 ^FS ^XZ


Solution 4

Russian and many other characters can be printed using the free Zebra swiss unicode font. It is already included in most printers as TT0003M_ and supports Roman, Cyrillic, Eastern European, Turkish, Arabic, Hebrew.


For printing languages like Japanese or Chinese, which have thousands of characters, you need a printer with at least 23 MB of free memory and a TrueType font file you can upload (they call it download).

This file can be bought from Zebra (and they say you need 64 MB), but I was also very successful with a very old TTF file found on my Windows 7 system in the Fonts folder: ARIALUNI.TTF 1.01 (23.275.812 Bytes), Arial Unicode MS. It was installed by a MS Office installation and is maybe not licensed for this use.

Most likely you can also use other TTF files, but I tried only this one.

While ZPL-printing on this Zebra printer worked without any original driver (just generic text only), for the font installation the driver was needed. If anyone knows how to send the TTF file to the printer without driver, please comment.

I installed the Zebra Setup Utilities, which include a Fonts Downloader. Click new, then add the font (must be installed in the system), and ignore the message that 226 characters are included. Also ignore that if you configure a test string with Unicode characters, it will not display correctly. You are beeing asked if you want to download now and it takes a long time.

You can check the installation by listing the directory contents (Administration web page or printout). There the font appears as ARI000.TTF in my case.


To print, you need to send the ZPL text as UTF-8. You can copy this example to notepad and select UTF-8 in the save dialog:

^XA
^LH100,150
^CWT,E:ARI000.FNT
^CFT,30,30
^CI28
^FT0,0^FH^FDyour unicode characters here^FS
^XZ

Then, for testing, you can use a simple copy command to send it to the printer:

In case of USB you need to share this printer in the network first.

Then net use lpt1: \\localhost\sharename and copy file.txt lpt1

We tested with many common Japanese and Chinese symbols and it works very well with high quality, on a ZT230 printer with 32 MB flash.

Solution 5

In latest firmware versions (since v x.16.x) you can use ^CI33 for codepage Windows-1251 encoded text (and other codepages) without ^FH. See manual

Share:
96,757
Tom Brunoli
Author by

Tom Brunoli

Updated on October 12, 2021

Comments

  • Tom Brunoli
    Tom Brunoli over 2 years

    I have the task of re-designing a system to print shipping labels, using a networked Zebra GK420T. I have been able to send ZPL print jobs to it perfectly fine, but I cannot seem to get it to print unicode characters, such as cyrillic letters. I have downloaded the lucida sans unicode font to the printer using the Seagull Scientific drivers and I am using the following ZPL code to test:

    ^XA
    ^LH100,150
    ^CI28
    ^FT0,0^A@N,50,50,R:LUCIDASR.FNT^CI28^FDTesting 1 2 3^FS
    ^FT0,50^A@N,50,50,R:LUCIDASR.FNT^CI28^FDДо свидания^FS
    ^FT0,100^B3^FDAAA001^FS
    ^XZ
    

    It will print the 'Testing 1 2 3' and the barcode, but it leaves a blank space instead of the cyrillic characters.

    I also tried using the Zebra swiss unicode font and now it prints the russian characters as question marks:

    ^XA
    ^LH100,150
    ^CWT,E:TT0003M_.FNT
    ^CFT,30,30
    ^CI28
    ^FT0,0^FDTesting 1 2 3^FS
    ^FT0,50^FDДо свидания^FS
    ^FT0,100^B3^FDAAA001^FS
    ^XZ
    

    Am I doing something wrong like not escaping characters or something or is it a problem with the printer?

  • Mak Sim
    Mak Sim about 10 years
    Must note that it works withoust escaping. All you need to do is encode file or string you are sending to printer to UTF-8. Tested on Zebra GK420t.
  • Lidor
    Lidor over 9 years
    It's also worth mentioning that the ^CI command determines the encoding. Make sure your zpl code has ^CI28 if your text is in utf-8.
  • maf-soft
    maf-soft about 9 years
    This is the best answer. It is really not necessary to use hex codes or whatever. You can just send the real unicode characters and it works. For Japanese and Chinese characters this font doesn't work. But I found a free solution for this too. Let me see where to post it... Will update here.
  • maf-soft
    maf-soft about 9 years
    This handy copy command also works with USB and LAN connection. Just use "net use lpt1: \\server\printer"
  • nurettin
    nurettin almost 9 years
    @MakSim that doesn't work with Zebra GK420k, I switched to utf8 on notepad++, sent the file and it didn't print unicode. Perhaps it has to do with the default font.
  • nurettin
    nurettin almost 9 years
    @MakSim OK I downloaded an arial font, switched the D font with arial font: ^CWD,E:ARI001.FNT and wrote ^ADN,30,30^FD and utf-8 glyphs show up without escaping.
  • Robin Jonsson
    Robin Jonsson over 8 years
    @Lidor I'm so sorry but I can't get ^CI28 to output anything! I've tried a simple ^XA^CI28^A0N,34^FH^FVR_F6BIN^XZ Is supposed to print "RÖBIN" but comes out as "RBIN". Any advice?
  • Lidor
    Lidor over 8 years
    @RobinJonsson isn't it supposed to be _C3_96 instead of _F6? You might also want to try just entering Ö without escaping it.
  • Robin Jonsson
    Robin Jonsson over 8 years
    @Lidor Thanks so much for your reply. I was looking for the wrong code. F6 is the unicode code point for ö. For instance, say that I can't change to _C3_96, I see that F6 is the hex for ö in ISO-8859-1. Any way to specify that encoding? Regards, and so thankful for your comment!
  • Lidor
    Lidor over 8 years
    @RobinJonsson Try looking at the ^CI command documentation. ^CI31 might be what you're after.
  • Angel G. Olloqui
    Angel G. Olloqui over 8 years
    This looks what I need. How do you convert your String into this special Hex? are you running it from Android?
  • AMIC MING
    AMIC MING about 7 years
    How do you get _D0_94 will print Д? Any reference link?
  • AMIC MING
    AMIC MING about 7 years
  • AMIC MING
    AMIC MING about 7 years
    mostly Zebra Printer doesn't support cryillic + kazakh cyrillic + latin alphabet and Your function stringConverTextToHex most helpful. Thanks for the answer.
  • Gary Richter
    Gary Richter almost 6 years
    Looking at the ZPL II documentation the CI range only goes up to 26 (page 109 under ^CI "Change International Font")
  • Lutz
    Lutz almost 5 years
    in you example ZPL code you have forgotten the ^FH statment. The 7th line should be: ^FT0,50^FH^FD_d0_94_d0_be _d1_81_d0_b2_d0_b8_d0_b4_d0_b0_d0_bd_d0_b8_d1_8f^FS
  • Florjon
    Florjon about 4 years
    Why the output does not include ^FH ?