c#通过标签软件bartender的zpl命令打印条码-kb88凯时官网登录

来自:网络
时间:2023-01-01
阅读:
免费资源网 - https://freexyz.cn/

注:

由于工作需要, 也是第一次接触到打印机的相关内容, 凑巧, 通过找了很多资料和帮助后, 也顺利的解决了打印标签的问题

(标签的表面信息[二维码,条形码, 文字] 和 rfid标签的epc写入)

kb88凯时官网登录的解决方案

1. 由于开发准备的前期工作, 手里面是有很多的原厂api。

2.熟之, 斑马打印机官方是由一套自己的打印语言, 简称zpl语言, 然后各种费解找到官方的sbpl api, 大概就是这样/

通过阅读大概阅读了这些api文档(尽管看不懂...) ,大概知道原理是通过zpl命令发送至打印机执行。

所以,顺藤摸瓜, 我直接就去搜索zpl的操作命令, 自己尝试了编写zpl命令操作打印机。在这里,先讲一下什么是zpl命令~~

zebra programming language (printer language) 简称zpl是由斑马公司发明的一种用于打印机通信的命令。

3. 在zpl api 文档种, 会用很详细的介绍, 从是怎样开始, 到各个指令的作用都会介绍, 如下图

根据官方的说明, 每个完整的zpl 指令, 它都是 ^xa 开始, 以^z 结束。 而^则是一个标记头, 后面跟着的字母,则是对应的作用功能, 例如:

  • ^lh : 定义标签的起始位置
  • ^ll : 定义标签的长度
  • ^pw : 打印宽度
  • ^ls : 标签的位移
  • ^......

实现

那么现在自己组成自己想要打印的zpl指令, 该如何发送到打印机?

1.demo(示例), 这里以打印一串字符 12345678 生成的zpl指令演示如何发送到打印机

* 12345678所生成的zpl指令如下: 
^ xa
^ fo50,50
^ a0n,36,20
^ fd12345678 ^ fs
^ pq1,0,1,y
^ xz
注释:
^xa/^xz 分别代表zpl的开始与结束, 始终固定
^fo :代表字段的起始位置, 50,50代表具体的坐标位置
^aon,36,20: 可缩放/位图字体 o代表字体, n代表字段的方向, 36代表字符的高度,20代表宽度
^fd12345678^fs: 字符内容, 代表输出的字符 12345678 标准以^fs结束
^pq1,0,1,y: 打印数量, 1打印数量,0暂停和切纸值,1每个序列号的副本数,y代表覆盖暂停计数

2.核心代码( 将zpl转换成intptr 然后调用 sendbytestoprinter 方法)

//zpl命令测试方法
        public bool printzpl(string zpl)
        {
            return sendstringtoprinter("zdesigner r110xi4 300 dpi", zpl);
        }
  注:  zdesigner r110xi4 300 dpi 是打印机的名称
        /// 
        /// 内容打印
        /// 
        /// 打印机名称
        /// 打印的sbpl指令
        /// 
        public bool sendstringtoprinter(string szprintername, string szstring)
        {
            intptr pbytes;
            int dwcount;
            dwcount = szstring.length;
            pbytes = marshal.stringtocotaskmemansi(szstring);
            sendbytestoprinter(szprintername, pbytes, dwcount);
            marshal.freecotaskmem(pbytes);
            return true;
        }
        // structure and api declarions:
        [structlayout(layoutkind.sequential, charset = charset.ansi)]
        public class docinfoa
        {
            [marshalas(unmanagedtype.lpstr)]
            public string pdocname;
            [marshalas(unmanagedtype.lpstr)]
            public string poutputfile;
            [marshalas(unmanagedtype.lpstr)]
            public string pdatatype;
        }
        [dllimport("winspool.drv", entrypoint = "openprintera", setlasterror = true, charset = charset.ansi, exactspelling = true, callingconvention = callingconvention.stdcall)]
        public static extern bool openprinter([marshalas(unmanagedtype.lpstr)] string szprinter, out intptr hprinter, int pd);
        [dllimport("winspool.drv", entrypoint = "closeprinter", setlasterror = true, exactspelling = true, callingconvention = callingconvention.stdcall)]
        public static extern bool closeprinter(intptr hprinter);
        [dllimport("winspool.drv", entrypoint = "startdocprintera", setlasterror = true, charset = charset.ansi, exactspelling = true, callingconvention = callingconvention.stdcall)]
        public static extern bool startdocprinter(intptr hprinter, int32 level, [in, marshalas(unmanagedtype.lpstruct)] docinfoa di);
        [dllimport("winspool.drv", entrypoint = "enddocprinter", setlasterror = true, exactspelling = true, callingconvention = callingconvention.stdcall)]
        public static extern bool enddocprinter(intptr hprinter);
        [dllimport("winspool.drv", entrypoint = "startpageprinter", setlasterror = true, exactspelling = true, callingconvention = callingconvention.stdcall)]
        public static extern bool startpageprinter(intptr hprinter);
        [dllimport("winspool.drv", entrypoint = "endpageprinter", setlasterror = true, exactspelling = true, callingconvention = callingconvention.stdcall)]
        public static extern bool endpageprinter(intptr hprinter);
        [dllimport("winspool.drv", entrypoint = "writeprinter", setlasterror = true, exactspelling = true, callingconvention = callingconvention.stdcall)]
        public static extern bool writeprinter(intptr hprinter, intptr pbytes, int32 dwcount, out int32 dwwritten);
        public static bool sendbytestoprinter(string szprintername, intptr pbytes, int32 dwcount)
        {
            int32 dwerror = 0, dwwritten = 0;
            intptr hprinter = new intptr(0);
            docinfoa di = new docinfoa();
            bool bsuccess = false; // assume failure unless you specifically succeed.
            di.pdocname = "labelprint";
            di.pdatatype = "raw";
            // open the printer.
            if (openprinter(szprintername, out hprinter, 0))
            {
                // start a document.
                if (startdocprinter(hprinter, 1, di))
                {
                    // start a page.
                    if (startpageprinter(hprinter))
                    {
                        // write your bytes.
                        bsuccess = writeprinter(hprinter, pbytes, dwcount, out dwwritten);
                        endpageprinter(hprinter);
                    }
                    enddocprinter(hprinter);
                }
                closeprinter(hprinter);
            }
            // if you did not succeed, getlasterror may give more information
            // about why not.
            if (bsuccess == false)
            {
                dwerror = marshal.getlastwin32error();
            }
            return bsuccess;
        }

3.最终效果

原理

*: 看官方的api没有实际的例子不好学习和了解怎么办? 同时, 官方提供的标签设计软件(bartender)是可以将数据预先设置好,

导出本地文件的,这样更加方便学习。

1.打开已经破解版本的bartender9.4演示如何将设计的标签导出本地文件,然后查看zpl指令.

>1.打开bartender9.4

>2..选择一个新的标签格式即可, 一直下一步, 直到进入主界面, 给标签添加一个文本数据: 12345678 为例

>3.然后选择打印按钮

>4.勾选打印至文件, 保存至本地文件。

>5.打开刚才保存的文件, 找到里面的内容

里面的内容, 由两个 ^xa ~ ^xz 组成, 还有一些xml标签组成。 很明显, 第二个 ^xa-^xz 是我们打印的实际内容指令;

>6. 像图中的 标签 标签, 这些应该是软件里面的数据格式, 肯定没用处的, 所以我们找到需要的内容即可, 然后放在测试程序里面。

注: 调用代码

        /// 
        /// 测试zpl命令执行
        /// 
        /// 
        /// 
        private void btn_print_click(object sender, eventargs e)
        {
            if (string.isnullorempty(txt_zpl.text)) return;
            sendstringtoprinte("zdesigner r110xi4 300 dpi",txt_zpl.text); 
        }
        public static bool sendstringtoprinter(string szprintername, string szstring)
        {
            intptr pbytes;
            int32 dwcount;
            dwcount = szstring.length;
            pbytes = marshal.stringtocotaskmemansi(szstring);
            sendbytestoprinter(szprintername, pbytes, dwcount);
            marshal.freecotaskmem(pbytes);
            return true;
        }

注: 由于标签纸的大小问题, 在设置标签模板的时候, 我是选定了标签的长宽, 如果出现打印不出来

或者显示不全的, 可以在标签模板设置好长宽和条码的位置即可

模板打印

代码贴了这么多, 可能还不知道引用了什么dll, 指令也是刚刚接触,可能只有博主自己懂, 那还有没有更好更简单的方法实现呢?

kb88凯时官网登录的解决方案: 《模板打印》

1.设置好打印的标签模板

工具:bartender9.4

2.用代码给调用模板赋值

3.调用打印

bartender

1. bartender 官方提供的标签设计软件, 同时具体所有的打印功能。

bartender标签软件内部原理也无非一样:1.设计好标签数据。2.打印的时候生成指令的语言发送至打印机打印。

同时bartender也可以将设计好的样式导出模板,用于外部赋值参数打印。

友情连接:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

免费资源网 - https://freexyz.cn/
返回顶部
顶部
网站地图