BarTender 經過ZPL命令操做打印機打印條碼, 操做RFID標籤

注: html

   因爲工做須要, 也是第一次接觸到打印機的相關內容, 湊巧, 經過找了不少資料和幫助後, 也順利的解決了打印標籤的問題less

(標籤的表面信息[二維碼,條形碼, 文字] RFID標籤的EPC寫入)工具

解決方案學習

 

1. 因爲開發準備的前期工做, 手裏面是有不少的原廠API。測試

 

2.熟之, 斑馬打印機官方是由一套本身的打印語言, 簡稱ZPL語言, 而後各類費解找到官方的SBPL API, 大概就是這樣/字體

 

經過閱讀大概閱讀了這些API文檔(儘管看不懂...) ,大概知道原理是經過ZPL命令發送至打印機執行。spa

因此,順藤摸瓜, 我直接就去搜索ZPL的操做命令, 本身嘗試了編寫ZPL命令操做打印機。在這裏,先講一下什麼是ZPL命令~~設計

Zebra Programming Language (printer language) 簡稱ZPL 是由斑馬公司發明的一種用於打印機通訊的命令。3d

 

3. 在ZPL API 文檔種, 會用很詳細的介紹, 從是怎樣開始, 到各個指令的做用都會介紹, 以下圖code

根據官方的說明, 每一個完整的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 是打印機的名稱
 
        /// <summary>
        /// 內容打印
        /// </summary>
        /// <param name="szPrinterName">打印機名稱</param>
        /// <param name="szString">打印的SBPL指令</param>
        /// <returns></returns>
        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. 像圖中的 <xpml>標籤 <page>標籤, 這些應該是軟件裏面的數據格式, 確定沒用處的, 因此咱們找到須要的內容便可, 而後放在測試程序裏面。

 

 

 : 調用代碼

        /// <summary>
        /// 測試ZPL命令執行
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        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;
        }

注: 因爲標籤紙的大小問題, 在設置標籤模板的時候, 我是選定了標籤的長寬, 若是出現打印不出來

或者顯示不全的, 能夠在標籤模板設置好長寬和條碼的位置便可

PS:本章未更新關於RFID打印的相關內容, 須要瞭解, 請聯繫本人郵件。 

須要源代碼請發送至本人郵箱, zhouhaogg789@outlook.com, 看到會及時回覆!

#

模板打印

代碼貼了這麼多, 可能還不知道引用了什麼DLL, 指令也是剛剛接觸,可能只有博主本身懂, 那還有沒有更好更簡單的方法實現呢?

解決方案:  《模板打印》

1.設置好打印的標籤模板

   工具: Bartender9.4

2.用代碼給調用模板賦值

3.調用打印

#

1. Bartender 官方提供的標籤設計軟件, 同時具體全部的打印功能。

Bartender標籤軟件內部原理也無非同樣: 1.設計好標籤數據。2.打印的時候生成指令的語言發送至打印機打印。

同時Bartender也能夠將設計好的樣式導出模板,用於外部賦值參數打印。

 

友情鏈接: http://www.cnblogs.com/zh7791/p/6907455.html

相關文章
相關標籤/搜索