您的位置:首页 > 编程语言 > C#

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

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位还是有问题。。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: