ZPL一些简单的指令

 

ZPL一些简单的指令

^XA 开始

^XZ 结束

 

^LL 设置标签长度(我用的打印机是TSC TE344,这好像没有效果)

^PW 设置标签宽度

^FS 换行

^FS 注释

 

^LH0,0 纸张的边距,左边距和上边距
 

^FO0,0 设置打印内容坐标

^FD123 设置打印内容,可以是文本,一维码,二维码

 

更多指令:请看这里

 

一段完整的ZPL指令

  1.  
    ^XA
  2.  
    ^XA^LH0,0^LL100^PW580
  3.  
     
  4.  
    ^FX 文本
  5.  
    ^FO10,10^AFN,0,20,10^FD123456^FS
  6.  
    ^FX 一维码
  7.  
    ^FO10,10^BY2,11.0,10,40^BCC,90,N^FD12345678^FS
  8.  
    ^FX 二维码
  9.  
    ^FO10,10^BQ,2,5^CI26^FH^FDQA^FD1215445244^FS
  10.  
     
  11.  
    ^XZ

 

打印文本

^FO10,10^AFN,0,20,10^FD123456^FS
 

打印一维码

^FO10,10^BY2,11.0,10,40^BCC,80,N^FD12345678^FS
 

其中^BCC,80,N的80为一维码的高度,N表示不显示注释行,则显示内容12345678

 

打印二维码

^FO10,10^BQ,2,5^CI26^FH^FDQA^FD1215445244^FS
 

其中^BQ,2,5的5为二维码大小,范围1-10

 

关于中文打印

由于打印机没有中文的字库,打印中文会出现乱码

一种解决方法就是安装中文字符,码表,这个有点麻烦,就不用了

另一种就是,通过Fnthex32.dll,将文字转为打印机指令,再发送到打印机


Fnthex32.dll下载:

链接:https://pan.baidu.com/s/1_lU0zswvE929wpXG0431Wg 
提取码:oi41 


使用

  1.  
    [DllImport("Fnthex32.dll")]
  2.  
    private static extern int GETFONTHEX(
  3.  
    string text,//文本
  4.  
    string fontName,//字体
  5.  
    string tempName,//临时变量
  6.  
    int orient,//方向
  7.  
    int height,//字体高度
  8.  
    int width,//字体宽度
  9.  
    int isBold,//是否加粗0,1
  10.  
    int isItalic,//是否斜体0,1
  11.  
    StringBuilder cmd);//内容
  12.  
     
  13.  
    /// <summary>
  14.  
    /// 获取文本编码
  15.  
    /// </summary>
  16.  
    /// <param name="text">文本</param>
  17.  
    /// <param name="fontName">字体</param>
  18.  
    /// <param name="tempName">临时变量</param>
  19.  
    /// <param name="height">字体高度</param>
  20.  
    /// <param name="width">字体宽度</param>
  21.  
    /// <param name="isBlod">是否加粗</param>
  22.  
    /// <param name="isItalic">是否斜体</param>
  23.  
    /// <returns></returns>
  24.  
    public static string GetFontHex(string text, string fontName, string tempName,
  25.  
    int height = 40, int width = 15, bool isBlod = false, bool isItalic = false)
  26.  
    {
  27.  
    int nIsBlod = isBlod ? 1 : 0;
  28.  
    int nIsItalic = isItalic ? 1 : 0;
  29.  
     
  30.  
    StringBuilder context = new StringBuilder(text.Length * 1024);
  31.  
    int count = GETFONTHEX(text, fontName, tempName, 1, height, width, nIsBlod, nIsItalic, context);
  32.  
    string temp = " " + context.ToString();
  33.  
    temp = temp.Substring(0, count);
  34.  
    return temp;
  35.  
    }

通过GetFontHex获取ZPL指令

 string sTemp = GetFontHex("啊", "Arial", "temp0");
 

其中temp0是一个临时变量

 

接下来,再通过一条指令来设置

^FO30,0^XGtemp0,1,1^FS
 

完整指令

  1.  
    ^XA
  2.  
    ^LH0,0^LL80^PW580
  3.  
    ~DGtemp0,00240,006,iH0108H0CL01FDHFEJ03F918018J031918018J03191H018J03191H018J031
  4.  
    93H018J03192H198J031921F98J03192H198J03194H198J03192H198J0319I198J0319I198J03191
  5.  
    9198J031909198J03190D198J03190DF98J03F90D198J031919H18J03H1F8018J03013H018L01I01
  6.  
    8L01I018L01I018L01I018L01I018L01H01F8L01I07M01I02iK0
  7.  
    ^FO30,0^XGtemp0,1,1^FS
  8.  
    ^XZ

 

关于图片的打印

打印图片,需要将图片转换成十六进制指令

https://blog.csdn.net/weixin_38211198/article/details/96494614

 

指令发送到打印机

首选需要设置打印机共享

才使用System.IO.File.Copy方法

  1.  
    //保存到本地文件
  2.  
    using (System.IO.StreamWriter sw = new System.IO.StreamWriter(printFilePath))
  3.  
    {
  4.  
    sw.Write(cmd.ToString());
  5.  
    }
  6.  
    //将ZPL指令发送到打印机
  7.  
    File.Copy(printFilePath, mPrintName, true);

其中

printFilePath为ZPL指令文件路径

mPrintName为打印机路径,例如:mPrintName = @"\\192.168.0.132\TSC TE344";

指令需要获取本机IP4地址

  1.  
    /// <summary>
  2.  
    /// 获取IP4地址
  3.  
    /// </summary>
  4.  
    private string GetIP4()
  5.  
    {
  6.  
    string ip4 = string.Empty;
  7.  
     
  8.  
    IPHostEntry ipe = Dns.GetHostEntry(Dns.GetHostName());
  9.  
    IPAddress[] ips = ipe.AddressList;
  10.  
     
  11.  
    for (int i = 0; i < ips.Length; i++)
  12.  
    {
  13.  
    if (ips[i].AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
  14.  
    {
  15.  
    ip4 = ips[i].ToString();
  16.  
    break;
  17.  
    }
  18.  
    }
  19.  
     
  20.  
    return ip4;
  21.  
    }

其实本机IP直接写127.0.0.1就好

关于打印机初始化

由于之前使用佳博Gprinter GP-9134T打印机,不是使用ZPL指令,直接使用PrintDocument类打印控件的图片,打印机都是自动校准的,现在TSC TE344打印机,由于现在打印机没有校准功能,用PrintDocument打印总是会打印一半纸张,所以改为ZPL指令打印,为了能同时使用多种打印机,之后做兼容。

由于用PrintDocument打印,导致出纸不准确,可用下面这指令初始化打印机,这指令是从NiceLabel得到的

首先,要设置好打印纸张的大小,边距等,在打印到文件,即可获取该初始化指令(BarTender)

  1.  
    /// <summary>
  2.  
    /// 打印机初始化
  3.  
    /// </summary>
  4.  
    private void PrintInit()
  5.  
    {
  6.  
    string printerInitCMD = @"
  7.  
    <xpml><page quantity='0' pitch='15.1 mm'></xpml>SIZE 47.5 mm, 15.1 mm
  8.  
    GAP 2 mm, 0 mm
  9.  
    DIRECTION 0,0
  10.  
    REFERENCE 0,0
  11.  
    OFFSET 0 mm
  12.  
    SET PEEL OFF
  13.  
    SET CUTTER OFF
  14.  
    SET PARTIAL_CUTTER OFF
  15.  
    <xpml></page></xpml><xpml><page quantity='1' pitch='15.1 mm'></xpml>SET TEAR ON
  16.  
    CLS
  17.  
    <xpml></page></xpml><xpml><end/></xpml>";
  18.  
     
  19.  
    string PrinterInitFilePath = printPath + "\\PrinterInit.prn";
  20.  
     
  21.  
    using (StreamWriter sw = new StreamWriter(PrinterInitFilePath))
  22.  
    {
  23.  
    sw.Write(printerInitCMD);
  24.  
    }
  25.  
     
  26.  
    File.Copy(PrinterInitFilePath, mPrintName, true);
  27.  
    }

使用的打印纸规格

双排打印纸

 

实际大小(mm)

标签宽高:22*15

卷宽:50

 左右边距:2  

行距:2

列距:2

代码中大小

标签宽高:235*160

纸张宽度:580

左右边距:30

中缝边距:50

 

总结:

由于ZPL刚学,不熟悉,项目中需要支持自定义打印模板功能,即用户自己调整,拖拽标签位置等,

考虑到

1.ZPL预览功能有点难度

2.ZPL指令的参数限制,比如条码的宽高无法与控件的大小兼容

 

所以直接通过打印控件上的图片,将图片转为十六进制指令发送到打印机,

这样还有一个好处就是不用考虑中文乱码的问题

 

下面是我的PrintManager

  1.  
    public class PrintManager
  2.  
    {
  3.  
    #region 文字转图像
  4.  
    [DllImport("Fnthex32.dll")]
  5.  
    private static extern int GETFONTHEX(
  6.  
    string text,//文本
  7.  
    string fontName,//字体
  8.  
    string tempName,//临时变量
  9.  
    int orient,//方向
  10.  
    int height,//字体高度
  11.  
    int width,//字体宽度
  12.  
    int isBold,//是否加粗0,1
  13.  
    int isItalic,//是否斜体0,1
  14.  
    StringBuilder cmd);//内容
  15.  
     
  16.  
    /// <summary>
  17.  
    /// 获取文本编码
  18.  
    /// </summary>
  19.  
    /// <param name="text">文本</param>
  20.  
    /// <param name="fontName">字体</param>
  21.  
    /// <param name="tempName">临时变量</param>
  22.  
    /// <param name="height">字体高度</param>
  23.  
    /// <param name="width">字体宽度</param>
  24.  
    /// <param name="isBlod">是否加粗</param>
  25.  
    /// <param name="isItalic">是否斜体</param>
  26.  
    /// <returns></returns>
  27.  
    public static string GetFontHex(string text, string fontName, string tempName,
  28.  
    int height = 40, int width = 15, bool isBlod = false, bool isItalic = false)
  29.  
    {
  30.  
    int nIsBlod = isBlod ? 1 : 0;
  31.  
    int nIsItalic = isItalic ? 1 : 0;
  32.  
     
  33.  
    StringBuilder context = new StringBuilder(text.Length * 1024);
  34.  
    int count = GETFONTHEX(text, fontName, tempName, 1, height, width, nIsBlod, nIsItalic, context);
  35.  
    string temp = " " + context.ToString();
  36.  
    temp = temp.Substring(0, count);
  37.  
    return temp;
  38.  
    }
  39.  
    #endregion
  40.  
     
  41.  
    //纸张宽度
  42.  
    int paperWidth = 580;
  43.  
    //左右边距
  44.  
    int padding = 30;
  45.  
    //中缝边距
  46.  
    int middlePadding = 50;
  47.  
     
  48.  
    //标签宽度
  49.  
    int labelWidth = 235;
  50.  
    //标签高度
  51.  
    int labelHeight = 160;
  52.  
     
  53.  
    string ip4;
  54.  
     
  55.  
    public StringBuilder cmd;
  56.  
     
  57.  
    //打印目录
  58.  
    string printPath;
  59.  
    //保存打印指令
  60.  
    string printFilePath ;
  61.  
     
  62.  
    //打印机名称
  63.  
    private string mPrintName;
  64.  
     
  65.  
    public PrintManager()
  66.  
    {
  67.  
    printPath = Application.StartupPath + "\\Print";
  68.  
     
  69.  
    if (Directory.Exists(printPath) == false)
  70.  
    {
  71.  
    Directory.CreateDirectory(printPath);
  72.  
    }
  73.  
     
  74.  
    printFilePath = printPath + "\\print.prn";
  75.  
     
  76.  
    ip4 = GetIP4();
  77.  
     
  78.  
    }
  79.  
     
  80.  
    public void Init(string printerName)
  81.  
    {
  82.  
    mPrintName = string.Format(@"\\{0}\{1}", ip4, printerName);
  83.  
    //mPrintName = @"\\192.168.0.132\TSC TE344";
  84.  
     
  85.  
    //打印机初始化
  86.  
    PrintInit();
  87.  
     
  88.  
    cmd = new StringBuilder();
  89.  
     
  90.  
    cmd.AppendFormat(@"^XA^LH0,0^LL{0}^PW{1}", 80, paperWidth);
  91.  
    }
  92.  
     
  93.  
    /// <summary>
  94.  
    /// 获取IP4地址
  95.  
    /// </summary>
  96.  
    private string GetIP4()
  97.  
    {
  98.  
    string ip4 = string.Empty;
  99.  
     
  100.  
    IPHostEntry ipe = Dns.GetHostEntry(Dns.GetHostName());
  101.  
    IPAddress[] ips = ipe.AddressList;
  102.  
     
  103.  
    for (int i = 0; i < ips.Length; i++)
  104.  
    {
  105.  
    if (ips[i].AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
  106.  
    {
  107.  
    ip4 = ips[i].ToString();
  108.  
    break;
  109.  
    }
  110.  
    }
  111.  
     
  112.  
    return ip4;
  113.  
    }
  114.  
     
  115.  
    /// <summary>
  116.  
    /// 打印机初始化
  117.  
    /// </summary>
  118.  
    private void PrintInit()
  119.  
    {
  120.  
    string printerInitCMD = @"
  121.  
    <xpml><page quantity='0' pitch='15.1 mm'></xpml>SIZE 47.5 mm, 15.1 mm
  122.  
    GAP 2 mm, 0 mm
  123.  
    DIRECTION 0,0
  124.  
    REFERENCE 0,0
  125.  
    OFFSET 0 mm
  126.  
    SET PEEL OFF
  127.  
    SET CUTTER OFF
  128.  
    SET PARTIAL_CUTTER OFF
  129.  
    <xpml></page></xpml><xpml><page quantity='1' pitch='15.1 mm'></xpml>SET TEAR ON
  130.  
    CLS
  131.  
    <xpml></page></xpml><xpml><end/></xpml>";
  132.  
     
  133.  
    string PrinterInitFilePath = printPath + "\\PrinterInit.prn";
  134.  
     
  135.  
    using (StreamWriter sw = new StreamWriter(PrinterInitFilePath))
  136.  
    {
  137.  
    sw.Write(printerInitCMD);
  138.  
    }
  139.  
     
  140.  
    File.Copy(PrinterInitFilePath, mPrintName, true);
  141.  
    }
  142.  
     
  143.  
    /// <summary>
  144.  
    /// 打印
  145.  
    /// </summary>
  146.  
    public void Print()
  147.  
    {
  148.  
    cmd.Append("^XZ");
  149.  
    //保存到本地文件
  150.  
    using (System.IO.StreamWriter sw = new System.IO.StreamWriter(printFilePath))
  151.  
    {
  152.  
    sw.Write(cmd.ToString());
  153.  
    }
  154.  
    //将ZPL指令发送到打印机
  155.  
    File.Copy(printFilePath, mPrintName, true);
  156.  
    }
  157.  
     
  158.  
    /// <summary>
  159.  
    /// 设置文本-中文乱码
  160.  
    /// </summary>
  161.  
    public void SetText(string value, Point loc)
  162.  
    {
  163.  
    cmd.AppendFormat("^FO{0},{1}^AFN,0,20,10^FD{2}^FS", padding + loc.X, loc.Y, value);
  164.  
    }
  165.  
     
  166.  
    int iTemp = 0;
  167.  
    /// <summary>
  168.  
    /// 设置文本-中文正常
  169.  
    /// </summary>
  170.  
    public void SetText_Chinese(string value, Point loc)
  171.  
    {
  172.  
    string tempName = "temp" + iTemp;
  173.  
    string sTemp = GetFontHex(value, "Arial", tempName);
  174.  
    cmd.Append(sTemp);
  175.  
     
  176.  
    cmd.AppendFormat("^FO{0},{1}^XG{2},1,1^FS", padding + loc.X, loc.Y, tempName);
  177.  
    iTemp++;
  178.  
    }
  179.  
     
  180.  
    /// <summary>
  181.  
    /// 设置二维码
  182.  
    /// </summary>
  183.  
    public void SetQR_Code(string value, Point loc, int size)//0到10
  184.  
    {
  185.  
    cmd.AppendFormat("^FO{0},{1}^BQ,2,{2}^CI26^FH^FDQA^FD{3}^FS", padding + loc.X, loc.Y, size, value);
  186.  
    }
  187.  
     
  188.  
    /// <summary>
  189.  
    /// 设置一维码
  190.  
    /// </summary>
  191.  
    public void SetCODE_128(string value, Point loc, Size size)
  192.  
    {
  193.  
    cmd.AppendFormat(@"^FO{0},{1}^BY2,11.0,60,{2}^BCC,{3},N^FD{4}^FS", padding + loc.X, loc.Y, size.Width, size.Height, value);
  194.  
    }
  195.  
     
  196.  
    int iTemp2 = 0;
  197.  
     
  198.  
    /// <summary>
  199.  
    /// 设置图片
  200.  
    /// </summary>
  201.  
    public void SetImage(Image image, bool isRight = false)
  202.  
    {
  203.  
    image = ReSizeImage(image, new Size(labelWidth + 20, labelHeight));
  204.  
     
  205.  
    string data = ZebraUnity.BitmapToHex(image, out int to, out int row);
  206.  
    string zpl = string.Format("~DGR:Temp{0}.GRF,{1},{2},{3}", iTemp2, to, row, data);
  207.  
    cmd.Append(zpl);
  208.  
     
  209.  
    int offset = isRight == true ? labelWidth + middlePadding : 0;
  210.  
     
  211.  
    cmd.AppendFormat("^FO{0},0^XGR:Temp{1}.GRF,1,1^FS", padding + offset, iTemp2);
  212.  
    iTemp2++;
  213.  
    }
  214.  
     
  215.  
    /// <summary>
  216.  
    /// 改变图像大小
  217.  
    /// </summary>
  218.  
    public static Image ReSizeImage(Image img, Size size)
  219.  
    {
  220.  
    Bitmap bitmap = new Bitmap(size.Width, size.Height);
  221.  
    Graphics g = Graphics.FromImage(bitmap);
  222.  
    g.InterpolationMode = InterpolationMode.HighQualityBicubic;
  223.  
    g.DrawImage(img, 0, 0, bitmap.Width, bitmap.Height);
  224.  
    g.Dispose();
  225.  
    return bitmap;
  226.  
    }
  227.  
     
  228.  
    }

其中ZebraUnity.BitmapToHex 看 https://blog.csdn.net/weixin_38211198/article/details/96494614

 

相关链接:

ZPL指令解析:

百度文库:https://wenku.baidu.com/view/ec78b8cbf01dc281e43af039.html

道客巴巴:http://www.doc88.com/p-2018927808824.html

ZPL指令预览:

http://labelary.com/viewer.html

 

转载于:https://greambwang.blog.csdn.net/article/details/95961605?spm=1001.2101.3001.6650.10&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EESLANDING%7Edefault-10-95961605-blog-96494614.pc_relevant_multi_platform_whitelistv4eslandingctr2&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EESLANDING%7Edefault-10-95961605-blog-96494614.pc_relevant_multi_platform_whitelistv4eslandingctr2&utm_relevant_index=16

 

 
posted @ 2022-08-25 11:07  卑微小老弟  阅读(3342)  评论(0编辑  收藏  举报