C#使用Zebra 斑马打印标签--使用winspool.Drv方式
2014-04-16 21:10
1281 查看
原本是使用网络上最流行的环路网卡方式套印标签,但是最近公司电脑换win7的,麻烦就来了。这个麻烦纠结了我两周,中间还把标签机搬到办公室来测试,累死了都(估计卖废铁能买个好价钱)。
采用环路网卡调用时,驱动kernel32.dll时,无法连接到标签机,但是打印测试又是ok的。个人分析情况两种:一种就是我的zebra打印驱动方式不对(虽然后面网上下了专门win7的,但是依然不行);一种就是Windows 9x/Me中非常重要的32位动态链接库文件,属于内核级文件,系统很可能里面的API接口变了。
基本上确认原有方法无解后,就换了个方式,即期待预把标签机当作一般打印机使用,所以我就使用了水晶报表,照着原有格式慢慢调试,最后打印效果差强人意,还有就是打印一段时间标签机参数都会还原回去。最后在网上找到一种使用winspool.Drv驱动标Zebra标签机的方法,能够使用ZPII编程语言驱动标签机,才算是圆满解决问题了。
驱动类 RawPrinterHelper
主函数(这是一个画面摘下来的,大家看 btnPrintZPL_Click调用了驱动函数)
我测试了一下在32位系统上使用完全能够胜任,64位还是有问题。。。。
采用环路网卡调用时,驱动kernel32.dll时,无法连接到标签机,但是打印测试又是ok的。个人分析情况两种:一种就是我的zebra打印驱动方式不对(虽然后面网上下了专门win7的,但是依然不行);一种就是Windows 9x/Me中非常重要的32位动态链接库文件,属于内核级文件,系统很可能里面的API接口变了。
基本上确认原有方法无解后,就换了个方式,即期待预把标签机当作一般打印机使用,所以我就使用了水晶报表,照着原有格式慢慢调试,最后打印效果差强人意,还有就是打印一段时间标签机参数都会还原回去。最后在网上找到一种使用winspool.Drv驱动标Zebra标签机的方法,能够使用ZPII编程语言驱动标签机,才算是圆满解决问题了。
驱动类 RawPrinterHelper
using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Drawing; using System.Drawing.Printing; using System.Windows.Forms; using System.Runtime.InteropServices; namespace ZPLPrinter { class RawPrinterHelper { // 结构和API声明 [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, IntPtr 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); /// <summary> /// 发送byte值给打印机 /// </summary> /// <param name="szPrinterName">打印机名称</param> /// <param name="pBytes">byte</param> /// <param name="dwCount">字符长度</param> /// <returns>成功标记(true为成功)</returns> 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; // 返回标志,默认失败 di.pDocName = "My Zebra Print File"; di.pDataType = "RAW"; // 打开打印机 if (OpenPrinter(szPrinterName.Normalize(), out hPrinter, IntPtr.Zero)) { // 开始文档 if (StartDocPrinter(hPrinter, 1, di)) { // 开始页 if (StartPagePrinter(hPrinter)) { // 写比特流 bSuccess = WritePrinter(hPrinter, pBytes, dwCount, out dwWritten); EndPagePrinter(hPrinter); } EndDocPrinter(hPrinter); } ClosePrinter(hPrinter); } // 如果不成功,写错误原因 if (bSuccess == false) { dwError = Marshal.GetLastWin32Error(); } return bSuccess; } /// <summary> /// 将字符串转换为bytes值,驱动bytes打印函数 /// </summary> /// <param name="szPrinterName"></param> /// <param name="szString"></param> /// <returns></returns> public static bool SendStringToPrinter(string szPrinterName, string szString) { //for (int i = 0; i < 3; i++) //{ IntPtr pBytes; Int32 dwCount; //字符串长度 dwCount = szString.Length; // 转换ANSIbyte码 pBytes = Marshal.StringToCoTaskMemAnsi(szString); //驱动byte打印 SendBytesToPrinter(szPrinterName, pBytes, dwCount); Marshal.FreeCoTaskMem(pBytes); //} return true; } } }
主函数(这是一个画面摘下来的,大家看 btnPrintZPL_Click调用了驱动函数)
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Runtime.InteropServices; namespace ZPLPrinter { public partial class Form1 : Form { private void btnPrintZPL_Click(object sender, EventArgs e) { //将标签机名和ZPII字符串发送给标签机 RawPrinterHelper.SendStringToPrinter("Zebra ZM400 300 dpi (ZPL)", SM0001()); } //标签打印 private string SM0001() { //string prod_code = "HA"; //品名代码 string prod_cname = "鋼卷"; //品名 string prod_cname_long = ""; //2014-01-03 品名 string v_prod_ename = "Hot Rolled Stainless Steel Sheet in Coil"; //品名英文 string v_sg_std = "JIS G4304"; //标准 string v_mat_no = "HE1300084200"; //材料号 string v_sg_sign = "SUS304"; //牌号 string v_size = "2.97mm x 1240mm x Coil"; //尺寸 string v_gross_wt = "20.110"; //毛重 string v_net_wt = "20.040"; //净重 string v_grade = "1"; //等级 string v_grade_cn = "1"; //等级 //string v_surface = "No.1"; //表面 string c_surface = "No.1"; //表面描述 string v_edge = "M"; //边部 string v_order_no = ""; //合同号 string v_heat_no = "1000076"; //炉号 string v_date = "2014.01.27"; //日期 string data = ""; //打印数据 string cn_prod_cname = ""; string cn_prod_cname_long = ""; string cn_grade = ""; string v_mat_act_thick = "(3.00mm)"; //prod_cname_long = 鋼卷"; //string c_div = "M"; //碳锈区分 //string cn_surface = ""; int j = 0; //等级中文代码 //简体中文转换繁体中文 System.Text.Encoding gb2312 = System.Text.Encoding.GetEncoding("gb2312"); System.Text.Encoding big5 = System.Text.Encoding.GetEncoding("big5"); v_grade_cn = "級"; byte[] bGB2312 = gb2312.GetBytes(v_grade_cn); byte[] bBig5 = System.Text.Encoding.Convert(gb2312, big5, bGB2312); string result = big5.GetString(bBig5); //品名 LPTControl getChinese = new LPTControl(); cn_prod_cname = getChinese.PrintChinese(prod_cname, "標楷體", 100, 40, 1, 0); //品名超长 LPTControl getChinese02 = new LPTControl(); cn_prod_cname_long = getChinese.PrintChinese(prod_cname_long, "標楷體", 100, 40, 1, 0); //等级 LPTControl getChinese01 = new LPTControl(); cn_grade = getChinese01.PrintChinese(result, "標楷體", 100, 40, 1, 0); ////表面 //LPTControl getChinese02 = new LPTControl(); //cn_surface = getChinese02.PrintChinese(v_surface, "黑体", 45, 25, 1, 0); #region//最初 System.Text.StringBuilder sw = new System.Text.StringBuilder("^XA\r\n", 10240); sw.Append(@"^LH0,0" + "\r\n"); sw.Append(@"^POI" + "\r\n"); //反向 //默认生成的图片都是OUTSTR01,品名中文 sw.Append(cn_prod_cname.Replace("OUTSTR01", "OUTSTR" + j.ToString()) + "\r\n"); sw.Append(@"^FO780,460"); sw.Append(@"^XGOUTSTR" + j.ToString() + ",1,1^FS" + "\r\n"); //品名超长 modified by zxq on 2014-01-04 if (prod_cname_long.Length > 0) { sw.Append(cn_prod_cname_long.Replace("OUTSTR01", "OUTSTRB" + j.ToString()) + "\r\n"); sw.Append(@"^FO780,1112"); sw.Append(@"^XGOUTSTRB" + j.ToString() + ",1,1^FS" + "\r\n"); } //品名英文 sw.Append(@"^FO720,460"); sw.Append((@"^A0R,60,50^FD" + v_prod_ename + "^FS" + "\r\n"));//60,50打印较饱满 sw.Append(@"^FO560,460^A0R,140,140^FD" + v_mat_no + "^FS" + "\r\n"); sw.Append(@"^FO450,460^A0R,90,90^FD" + v_sg_std + "^FS" + "\r\n"); sw.Append(@"^FO320,460^A0R,90,90^FD" + v_sg_sign + "^FS" + "\r\n"); sw.Append(@"^FO250,460^A0R,80,80^FD" + v_size + "^FS" + "\r\n"); sw.Append(@"^FO190,460^A0R,80,80^FD" + v_mat_act_thick + "^FS" + "\r\n"); sw.Append(@"^FO60,460^A0R,90,90^FD" + v_gross_wt + "^FS" + "\r\n"); sw.Append(@"^FO60,1130^A0R,90,90^FD" + v_net_wt + "^FS" + "\r\n"); //等级 sw.Append(@"^FO700,1800^A0R,180,180^FD" + v_grade + "^FS" + "\r\n"); //等级中文(级汉字) sw.Append(@"^FO730,1900"); sw.Append(cn_grade.Replace("OUTSTR01", "OUTSTRA" + j.ToString()) + "\r\n"); sw.Append(@"^XGOUTSTRA" + j.ToString() + ",1,1^FS" + "\r\n"); //表面 sw.Append(@"^FO600,1800"); sw.Append(@"^A0R,90,90^FD" + c_surface + "^FS" + "\r\n"); //sw.Append(cn_surface.Replace("OUTSTR01", "OUTSTRB" + j.ToString()) + "\r\n"); //sw.Append(@"^XGOUTSTRB" + j.ToString() + ",2,2^FS" + "\r\n"); sw.Append(@"^FO450,1800^A0R,90,90^FD" + v_edge + "^FS" + "\r\n"); sw.Append(@"^FO320,1800^A0R,90,90^FD" + v_order_no + "^FS" + "\r\n"); sw.Append(@"^FO190,1800^A0R,90,90^FD" + v_heat_no + "^FS" + "\r\n"); sw.Append(@"^FO60,1800^A0R,90,90^FD" + v_date + "^FS" + "\r\n"); //条形码 sw.Append(@"^FO180,2290^BY4,3,130^B3N,N,,N,N^FD" + v_mat_no + "^FS" + "\r\n"); sw.Append(@"^XZ"); #endregion data = sw.ToString(); MessageBox.Show("返回数据"); data = sw.ToString(); return data; } //使用LPT1连接打印机,进行打印 2013-8-8 by zxq public class LPTControl { [StructLayout(LayoutKind.Sequential)] private struct OVERLAPPED { int Internal; int InternalHigh; int Offset; int OffSetHigh; int hEvent; } [DllImport("kernel32.dll")] private static extern int CreateFile( string lpFileName, uint dwDesiredAccess, int dwShareMode, int lpSecurityAttributes, int dwCreationDisposition, int dwFlagsAndAttributes, int hTemplateFile ); [DllImport("kernel32.dll")] private static extern bool WriteFile( int hFile, byte[] lpBuffer, int nNumberOfBytesToWrite, out int lpNumberOfBytesWritten, out OVERLAPPED lpOverlapped ); [DllImport("kernel32.dll")] private static extern bool CloseHandle( int hObject ); [DllImport("FNTHEX32.DLL")] public static extern int GETFONTHEX( string ChineseText, //待转变中文内容 string FontName, //字体名称 int Orient, //旋转角度0,90,180,270 int Height, // 字体高度 int Width, // 字体宽度,通常是0 byte IsBold, //1 变粗,0 正常 byte IsItalic, //1 斜体,0 正常 System.Text.StringBuilder ReturnPicData); //返回的图片字符 private int iHandle; private string cName; //中文名 public bool Open() { iHandle = CreateFile("lpt1", 0x40000000, 0, 0, 3, 0, 0); if (iHandle != -1) { return true; } else { return false; } } public bool Write(String Mystring) { if (iHandle != -1) { int i; OVERLAPPED x; byte[] mybyte = System.Text.Encoding.Default.GetBytes(Mystring); return WriteFile(iHandle, mybyte, mybyte.Length, out i, out x); } else { throw new Exception("埠未打開!"); } } public bool Close() { return CloseHandle(iHandle); } public string PrintChinese(string sChn, string sFont, int nHeight, int nWidth, byte nBold, byte nItalic) { StringBuilder hexbuf = new StringBuilder(21 * 1024); int count = GETFONTHEX(sChn, sFont, 90, nHeight, nWidth, nBold, nItalic, hexbuf); cName = hexbuf.ToString(); return (cName); } } } }
我测试了一下在32位系统上使用完全能够胜任,64位还是有问题。。。。
相关文章推荐
- C# 操作FTP
- C# 导出导入TXT文件
- C#获取IP和主机名
- C#中的数据类型装换
- C# ListView用法详解
- C#winform菜单权限分配,与菜单同步的treeView树状菜单权限控制使用心得
- C#读取XML配置文件
- c# 范型Dictionary实用例子
- [C#]桌面模式下GDI绘制(全透明背景)
- 友元函数(相当于C#的属性)
- C#对话框全接触
- Visual C# 字体对话框 & 颜色对话框
- C# this.Invoke()的作用与用法
- C#获取文件路径的几种方法
- C#获取word的页数
- C# Windows - 创建控件
- C# 的三种序列化方法
- C#操作文件夹、收藏夹、库
- 转:C# 线程同步技术 Monitor 和Lock
- C#中datagridview选中行后textbox显示选中的内容