C#使用Zebra 斑馬打印標簽--使用winspool.Drv方式


  原本是使用網絡上最流行的環路網卡方式套印標簽,但是最近公司電腦換win7的,麻煩就來了。這個麻煩糾結了我兩周,中間還把標簽機搬到辦公室來測試,累死了都(估計賣廢鐵能買個好價錢)。

采用環路網卡調用時,驅動kernel32.dll時,無法連接到標簽機,但是打印測試又是ok的。個人分析情況兩種:一種就是我的zebra打印驅動方式不對(雖然后面網上下了專門win7的,但是依然不行);一種就是Windows 9x/Me中非常重要的32位動態鏈接庫文件,屬於內核級文件,系統很可能里面的API接口變了。

  基本上確認原有方法無解后,就換了個方式,即期待預把標簽機當作一般打印機使用,所以我就使用了水晶報表,照着原有格式慢慢調試,最后打印效果差強人意,還有就是打印一段時間標簽機參數都會還原回去。最后在網上找到一種使用winspool.Drv驅動標Zebra標簽機的方法,能夠使用ZPII編程語言驅動標簽機,才算是圓滿解決問題了。

     

    驅動類 RawPrinterHelper

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Text;
  4 using System.IO;
  5 using System.Drawing;
  6 using System.Drawing.Printing;
  7 using System.Windows.Forms;
  8 using System.Runtime.InteropServices;
  9 
 10 namespace ZPLPrinter
 11 {
 12     class RawPrinterHelper
 13     {
 14         // 結構和API聲明 
 15         [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
 16         public class DOCINFOA
 17         {
 18             [MarshalAs(UnmanagedType.LPStr)]
 19             public string pDocName;
 20             [MarshalAs(UnmanagedType.LPStr)]
 21             public string pOutputFile;
 22             [MarshalAs(UnmanagedType.LPStr)]
 23             public string pDataType;
 24         }
 25         [DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
 26         public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, IntPtr pd);
 27 
 28         [DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
 29         public static extern bool ClosePrinter(IntPtr hPrinter);
 30 
 31         [DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
 32         public static extern bool StartDocPrinter(IntPtr hPrinter, Int32 level, [In, MarshalAs(UnmanagedType.LPStruct)] DOCINFOA di);
 33 
 34         [DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
 35         public static extern bool EndDocPrinter(IntPtr hPrinter);
 36 
 37         [DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
 38         public static extern bool StartPagePrinter(IntPtr hPrinter);
 39 
 40         [DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
 41         public static extern bool EndPagePrinter(IntPtr hPrinter);
 42 
 43         [DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
 44         public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount, out Int32 dwWritten);
 45         
 46         /// <summary>
 47         /// 發送byte值給打印機
 48         /// </summary>
 49         /// <param name="szPrinterName">打印機名稱</param>
 50         /// <param name="pBytes">byte</param>
 51         /// <param name="dwCount">字符長度</param>
 52         /// <returns>成功標記(true為成功)</returns>
 53         public static bool SendBytesToPrinter(string szPrinterName, IntPtr pBytes, Int32 dwCount)
 54         {
 55             Int32 dwError = 0, dwWritten = 0;
 56             IntPtr hPrinter = new IntPtr(0);
 57             DOCINFOA di = new DOCINFOA();
 58             bool bSuccess = false; // 返回標志,默認失敗
 59             di.pDocName = "My Zebra Print File";
 60             di.pDataType = "RAW";
 61 
 62             // 打開打印機
 63             if (OpenPrinter(szPrinterName.Normalize(), out hPrinter, IntPtr.Zero))
 64             {
 65                 // 開始文檔
 66                 if (StartDocPrinter(hPrinter, 1, di))
 67                 {
 68                     // 開始頁
 69                     if (StartPagePrinter(hPrinter))
 70                     {
 71                         // 寫比特流
 72                         bSuccess = WritePrinter(hPrinter, pBytes, dwCount, out dwWritten);
 73                         EndPagePrinter(hPrinter);
 74                     }
 75                     EndDocPrinter(hPrinter);
 76                 }
 77                 ClosePrinter(hPrinter);
 78             }
 79             // 如果不成功,寫錯誤原因
 80             if (bSuccess == false)
 81             {
 82                 dwError = Marshal.GetLastWin32Error();
 83             }
 84             return bSuccess;
 85         }
 86 
 87         /// <summary>
 88         /// 將字符串轉換為bytes值,驅動bytes打印函數
 89         /// </summary>
 90         /// <param name="szPrinterName"></param>
 91         /// <param name="szString"></param>
 92         /// <returns></returns>
 93         public static bool SendStringToPrinter(string szPrinterName, string szString)
 94         {
 95             //for (int i = 0; i < 3; i++)
 96             //{
 97                 IntPtr pBytes;
 98                 Int32 dwCount;
 99                 //字符串長度
100                 dwCount = szString.Length;
101                 // 轉換ANSIbyte碼
102                 pBytes = Marshal.StringToCoTaskMemAnsi(szString);
103                 //驅動byte打印
104                 SendBytesToPrinter(szPrinterName, pBytes, dwCount);
105                 Marshal.FreeCoTaskMem(pBytes);
106                 
107             //}
108             return true;
109          }
110     }
111 }

 

 

主函數(這是一個畫面摘下來的,大家看 btnPrintZPL_Click調用了驅動函數)

  1 using System;
  2 using System.Collections.Generic;
  3 using System.ComponentModel;
  4 using System.Data;
  5 using System.Drawing;
  6 using System.Text;
  7 using System.Windows.Forms;
  8 using System.Runtime.InteropServices;
  9 
 10 namespace ZPLPrinter
 11 {
 12     public partial class Form1 : Form
 13     {
 14 
 15         private void btnPrintZPL_Click(object sender, EventArgs e)
 16         {
 17               //將標簽機名和ZPII字符串發送給標簽機
 18                 RawPrinterHelper.SendStringToPrinter("Zebra  ZM400 300 dpi (ZPL)", SM0001());
 19           
 20         }
 21 
 22 
 23         //標簽打印 
 24         private string SM0001()
 25         {
 26 
 27             //string prod_code = "HA";    //品名代碼
 28             string prod_cname = "鋼卷";   //品名
 29             string prod_cname_long = ""; //2014-01-03 品名
 30             string v_prod_ename = "Hot Rolled Stainless Steel Sheet in Coil";   //品名英文
 31             string v_sg_std = "JIS G4304";     //標准
 32             string v_mat_no = "HE1300084200";     //材料號
 33             string v_sg_sign = "SUS304";    //牌號
 34             string v_size = "2.97mm x 1240mm x Coil";       //尺寸
 35             string v_gross_wt = "20.110";   //毛重
 36             string v_net_wt = "20.040";     //凈重
 37             string v_grade = "1";      //等級
 38             string v_grade_cn = "1";   //等級
 39             //string v_surface = "No.1";    //表面
 40             string c_surface = "No.1";    //表面描述
 41             string v_edge = "M";       //邊部
 42             string v_order_no = "";   //合同號
 43             string v_heat_no = "1000076";    //爐號
 44             string v_date = "2014.01.27";       //日期
 45             string data = "";    //打印數據
 46             string cn_prod_cname = "";
 47             string cn_prod_cname_long = "";
 48             string cn_grade = "";
 49             string v_mat_act_thick = "(3.00mm)";
 50      
 51             //prod_cname_long = 鋼卷";
 52             //string c_div = "M";      //碳銹區分
 53             //string cn_surface = "";
 54             int j = 0;
 55         
 56             //等級中文代碼 //簡體中文轉換繁體中文
 57             System.Text.Encoding gb2312 = System.Text.Encoding.GetEncoding("gb2312");
 58             System.Text.Encoding big5 = System.Text.Encoding.GetEncoding("big5");
 59             v_grade_cn = "";
 60             byte[] bGB2312 = gb2312.GetBytes(v_grade_cn);
 61             byte[] bBig5 = System.Text.Encoding.Convert(gb2312, big5, bGB2312);
 62             string result = big5.GetString(bBig5);
 63             //品名
 64             LPTControl getChinese = new LPTControl();
 65             cn_prod_cname = getChinese.PrintChinese(prod_cname, "標楷體", 100, 40, 1, 0);
 66 
 67             //品名超長
 68             LPTControl getChinese02 = new LPTControl();
 69             cn_prod_cname_long = getChinese.PrintChinese(prod_cname_long, "標楷體", 100, 40, 1, 0);
 70            
 71             //等級
 72             LPTControl getChinese01 = new LPTControl();
 73             cn_grade = getChinese01.PrintChinese(result, "標楷體", 100, 40, 1, 0);
 74             ////表面
 75             //LPTControl getChinese02 = new LPTControl();
 76             //cn_surface = getChinese02.PrintChinese(v_surface, "黑體", 45, 25, 1, 0);
 77             #region//最初
 78             System.Text.StringBuilder sw = new System.Text.StringBuilder("^XA\r\n", 10240);
 79             sw.Append(@"^LH0,0" + "\r\n");
 80             sw.Append(@"^POI" + "\r\n"); //反向
 81             //默認生成的圖片都是OUTSTR01,品名中文
 82             sw.Append(cn_prod_cname.Replace("OUTSTR01", "OUTSTR" + j.ToString()) + "\r\n");
 83             sw.Append(@"^FO780,460");
 84             sw.Append(@"^XGOUTSTR" + j.ToString() + ",1,1^FS" + "\r\n");
 85             //品名超長 modified by zxq on 2014-01-04
 86             if (prod_cname_long.Length > 0)
 87             {
 88                 sw.Append(cn_prod_cname_long.Replace("OUTSTR01", "OUTSTRB" + j.ToString()) + "\r\n");
 89                 sw.Append(@"^FO780,1112");
 90                 sw.Append(@"^XGOUTSTRB" + j.ToString() + ",1,1^FS" + "\r\n");
 91             }
 92             //品名英文 
 93             sw.Append(@"^FO720,460");
 94             sw.Append((@"^A0R,60,50^FD" + v_prod_ename + "^FS" + "\r\n"));//60,50打印較飽滿
 95             sw.Append(@"^FO560,460^A0R,140,140^FD" + v_mat_no + "^FS" + "\r\n");
 96             sw.Append(@"^FO450,460^A0R,90,90^FD" + v_sg_std + "^FS" + "\r\n");
 97             sw.Append(@"^FO320,460^A0R,90,90^FD" + v_sg_sign + "^FS" + "\r\n");
 98             sw.Append(@"^FO250,460^A0R,80,80^FD" + v_size + "^FS" + "\r\n");
 99             sw.Append(@"^FO190,460^A0R,80,80^FD" + v_mat_act_thick + "^FS" + "\r\n");
100             sw.Append(@"^FO60,460^A0R,90,90^FD" + v_gross_wt + "^FS" + "\r\n");
101             sw.Append(@"^FO60,1130^A0R,90,90^FD" + v_net_wt + "^FS" + "\r\n");
102             //等級
103             sw.Append(@"^FO700,1800^A0R,180,180^FD" + v_grade + "^FS" + "\r\n");
104             //等級中文(級漢字)
105             sw.Append(@"^FO730,1900");
106             sw.Append(cn_grade.Replace("OUTSTR01", "OUTSTRA" + j.ToString()) + "\r\n");
107             sw.Append(@"^XGOUTSTRA" + j.ToString() + ",1,1^FS" + "\r\n");
108             //表面
109             sw.Append(@"^FO600,1800");
110             sw.Append(@"^A0R,90,90^FD" + c_surface + "^FS" + "\r\n");
111             //sw.Append(cn_surface.Replace("OUTSTR01", "OUTSTRB" + j.ToString()) + "\r\n");
112             //sw.Append(@"^XGOUTSTRB" + j.ToString() + ",2,2^FS" + "\r\n"); 
113             sw.Append(@"^FO450,1800^A0R,90,90^FD" + v_edge + "^FS" + "\r\n");
114             sw.Append(@"^FO320,1800^A0R,90,90^FD" + v_order_no + "^FS" + "\r\n");
115             sw.Append(@"^FO190,1800^A0R,90,90^FD" + v_heat_no + "^FS" + "\r\n");
116             sw.Append(@"^FO60,1800^A0R,90,90^FD" + v_date + "^FS" + "\r\n");
117             //條形碼
118             sw.Append(@"^FO180,2290^BY4,3,130^B3N,N,,N,N^FD" + v_mat_no + "^FS" + "\r\n");
119             sw.Append(@"^XZ");
120             #endregion
121 
122             
123             data = sw.ToString();
124             MessageBox.Show("返回數據");
125 
126                 data = sw.ToString();
127 
128             return data;
129         }
130 
131         //使用LPT1連接打印機,進行打印 2013-8-8 by zxq
132         public class LPTControl
133         {
134             [StructLayout(LayoutKind.Sequential)]
135             private struct OVERLAPPED
136             {
137                 int Internal;
138                 int InternalHigh;
139                 int Offset;
140                 int OffSetHigh;
141                 int hEvent;
142             }
143 
144             [DllImport("kernel32.dll")]
145             private static extern int CreateFile(
146             string lpFileName,
147             uint dwDesiredAccess,
148             int dwShareMode,
149             int lpSecurityAttributes,
150             int dwCreationDisposition,
151             int dwFlagsAndAttributes,
152             int hTemplateFile
153             );
154 
155             [DllImport("kernel32.dll")]
156             private static extern bool WriteFile(
157             int hFile,
158             byte[] lpBuffer,
159             int nNumberOfBytesToWrite,
160             out int lpNumberOfBytesWritten,
161             out OVERLAPPED lpOverlapped
162             );
163 
164 
165             [DllImport("kernel32.dll")]
166             private static extern bool CloseHandle(
167             int hObject
168             );
169 
170             [DllImport("FNTHEX32.DLL")]
171             public static extern int GETFONTHEX(
172              string ChineseText, //待轉變中文內容
173              string FontName,  //字體名稱
174              int Orient,    //旋轉角度0,90,180,270
175              int Height,  // 字體高度
176              int Width,   // 字體寬度,通常是0
177              byte IsBold, //1 變粗,0 正常
178              byte IsItalic,  //1 斜體,0 正常
179              System.Text.StringBuilder ReturnPicData);  //返回的圖片字符
180 
181             private int iHandle;
182             private string cName; //中文名
183             public bool Open()
184             {
185                 iHandle = CreateFile("lpt1", 0x40000000, 0, 0, 3, 0, 0);
186                 if (iHandle != -1)
187                 {
188                     return true;
189                 }
190                 else
191                 {
192                     return false;
193                 }
194             }
195 
196             public bool Write(String Mystring)
197             {
198                 if (iHandle != -1)
199                 {
200                     int i;
201                     OVERLAPPED x;
202                     byte[] mybyte = System.Text.Encoding.Default.GetBytes(Mystring);
203                     return WriteFile(iHandle, mybyte, mybyte.Length, out i, out x);
204                 }
205                 else
206                 {
207                     throw new Exception("埠未打開!");
208                 }
209             }
210 
211             public bool Close()
212             {
213                 return CloseHandle(iHandle);
214             }
215 
216             public string PrintChinese(string sChn, string sFont, int nHeight, int nWidth, byte nBold, byte nItalic)
217             {
218                 StringBuilder hexbuf = new StringBuilder(21 * 1024);
219                 int count = GETFONTHEX(sChn, sFont, 90, nHeight, nWidth, nBold, nItalic, hexbuf);
220 
221                 cName = hexbuf.ToString();
222                 return (cName);
223             }
224         }  
225    
226 
227     }
228 
229 
230 }

 

我測試了一下在32位系統上使用完全能夠勝任,64位還是有問題。。。。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM