用C#通过USB连接斑马打印机并打印ZPL条码是一个实用且强大的功能。
C# 通过USB连接斑马打印机打印ZPL条码
使用C#通过USB接口连接斑马打印机并打印ZPL条码的方案。我将提供两种主要方法:一种是使用原始ZPL指令直接打印,另一种是通过斑马官方SDK进行打印。
1. 使用ZPL指令直接打印(推荐)
这是最常用且灵活的方法,通过向打印机直接发送ZPL指令来实现打印。
using System;
using System.IO;
using System.Drawing;
using System.Text;
using System.Runtime.InteropServices;
public class ZebraUsbPrinter
{
// 引入Windows API函数
[DllImport("winspool.Drv", CharSet = CharSet.Auto)]
public static extern bool OpenPrinter(string printerName, out IntPtr phPrinter, IntPtr pd);
[DllImport("winspool.Drv", CharSet = CharSet.Auto)]
public static extern bool ClosePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", CharSet = CharSet.Auto)]
public static extern bool StartDocPrinter(IntPtr hPrinter, int level, [In] DOCINFOA di);
[DllImport("winspool.Drv", CharSet = CharSet.Auto)]
public static extern bool EndDocPrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", CharSet = CharSet.Auto)]
public static extern bool StartPagePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", CharSet = CharSet.Auto)]
public static extern bool EndPagePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", CharSet = CharSet.Auto)]
public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, int dwCount, out int dwWritten);
// 文档信息结构
[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;
}
// 发送ZPL字符串到打印机
public static bool SendZplToPrinter(string printerName, string zplData)
{
IntPtr printerHandle = IntPtr.Zero;
int bytesWritten = 0;
DOCINFOA docInfo = new DOCINFOA();
docInfo.pDocName = "Zebra Label";
docInfo.pDataType = "RAW";
try
{
// 打开打印机
if (!OpenPrinter(printerName, out printerHandle, IntPtr.Zero))
return false;
// 开始文档
if (!StartDocPrinter(printerHandle, 1, docInfo))
return false;
// 开始页面
if (!StartPagePrinter(printerHandle))
return false;
// 获取ZPL数据的字节数组
byte[] data = Encoding.ASCII.GetBytes(zplData);
int size = data.Length;
// 分配非托管内存并复制数据
IntPtr unmanagedData = Marshal.AllocCoTaskMem(size);
Marshal.Copy(data, 0, unmanagedData, size);
// 发送数据到打印机
bool success = WritePrinter(printerHandle, unmanagedData, size, out bytesWritten);
// 释放非托管内存
Marshal.FreeCoTaskMem(unmanagedData);
if (!success)
return false;
// 结束页面和文档
EndPagePrinter(printerHandle);
EndDocPrinter(printerHandle);
return true;
}
finally
{
if (printerHandle != IntPtr.Zero)
ClosePrinter(printerHandle);
}
}
// 生成简单的ZPL标签代码
public static string GenerateSimpleZpl(string barcodeData, string textData)
{
StringBuilder zpl = new StringBuilder();
// ZPL指令开始
zpl.Append("^XA"); // 开始格式
zpl.Append("^CI28"); // 设置字符编码(支持中文)
// 添加文本
zpl.Append("^FO50,50"); // 设置字段位置 (x,y)
zpl.Append("^A0N,50,50"); // 设置字体大小
zpl.Append("^FD").Append(textData).Append("^FS"); // 字段数据及结束
// 添加条码 (Code 128)
zpl.Append("^FO50,150"); // 设置条码位置
zpl.Append("^BCN,100,Y,N,N"); // 条码指令
zpl.Append("^FD").Append(barcodeData).Append("^FS"); // 条码数据
// ZPL指令结束
zpl.Append("^XZ"); // 结束格式
return zpl.ToString();
}
}
使用方法:
// 使用示例
string printerName = "Zebra ZD888-203dpi ZPL"; // 打印机名称(在设备和打印机中查看)
string text = "产品标签";
string barcode = "1234567890";
// 生成ZPL指令
string zplCommand = ZebraUsbPrinter.GenerateSimpleZpl(barcode, text);
// 发送到打印机
bool success = ZebraUsbPrinter.SendZplToPrinter(printerName, zplCommand);
if (success)
{
Console.WriteLine("打印成功!");
}
else
{
Console.WriteLine("打印失败!");
}
2. 使用斑马官方SDK打印
首先需要通过NuGet安装斑马SDK包:Zebra.Sdk
using System;
using System.Windows.Forms;
using Zebra.Sdk.Comm;
using Zebra.Sdk.Printer;
using Zebra.Sdk.Printer.Discovery;
public class ZebraSdkPrinter
{
// 使用USB连接打印
public static void PrintWithUsbConnection(string printerName, string zplData)
{
Connection connection = null;
try
{
// 创建USB连接
connection = new UsbConnection(printerName);
connection.Open();
// 获取打印机实例
ZebraPrinter printer = ZebraPrinterFactory.GetInstance(connection);
// 发送ZPL指令
printer.SendCommand(zplData);
}
catch (ConnectionException e)
{
MessageBox.Show($"连接错误: {e.Message}");
}
catch (ZebraPrinterLanguageUnknownException e)
{
MessageBox.Show($"打印机语言错误: {e.Message}");
}
finally
{
// 关闭连接
if (connection != null)
{
try
{
connection.Close();
}
catch (Exception) { }
}
}
}
// 发现可用的USB打印机
public static void DiscoverUsbPrinters()
{
try
{
foreach (DiscoveredUsbPrinter usbPrinter in UsbDiscoverer.GetZebraUsbPrinters())
{
Console.WriteLine($"找到USB打印机: {usbPrinter}");
}
}
catch (Exception ex)
{
Console.WriteLine($"发现打印机错误: {ex.Message}");
}
}
}
3. 高级ZPL指令示例
以下是一些常用的ZPL指令示例,你可以根据需要组合使用:
// 创建包含中文、条码和QR码的复杂标签
public static string GenerateComplexZpl(string productName, string barcodeData, string qrData, string price)
{
StringBuilder zpl = new StringBuilder();
zpl.Append("^XA"); // 开始格式
zpl.Append("^CI28"); // 设置字符编码(支持中文)
// 设置中文字体
zpl.Append("^CW1,E:SIMSUN.TTF"); // 设置中文字体
// 中文文本
zpl.Append("^FO50,30^A1N,40,40^FD产品名称:^FS");
zpl.Append("^FO250,30^A1N,40,40^FD").Append(productName).Append("^FS");
// 条码(Code 128)
zpl.Append("^FO50,100^BCN,100,Y,N,N^FD").Append(barcodeData).Append("^FS");
// QR码
zpl.Append("^FO50,250^BQN,2,5^FDMM,A").Append(qrData).Append("^FS");
// 价格
zpl.Append("^FO300,250^A0N,50,50^FD¥").Append(price).Append("^FS");
zpl.Append("^XZ"); // 结束格式
return zpl.ToString();
}
4. 获取打印机状态(可选)
public class PrinterStatusHelper
{
public static void CheckPrinterStatus(string printerName)
{
try
{
Connection connection = new UsbConnection(printerName);
connection.Open();
ZebraPrinter printer = ZebraPrinterFactory.GetInstance(connection);
PrinterStatus status = printer.GetCurrentStatus();
Console.WriteLine($"打印机状态: {status}");
Console.WriteLine($"是否就绪: {status.isReadyToPrint}");
Console.WriteLine($"纸量状态: {status.paperStatus}");
connection.Close();
}
catch (Exception ex)
{
Console.WriteLine($"获取状态错误: {ex.Message}");
}
}
}
5. 完整的示例程序
using System;
using System.Windows.Forms;
namespace ZebraPrinterApp
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
private void btnPrint_Click(object sender, EventArgs e)
{
string printerName = txtPrinterName.Text;
string productName = txtProductName.Text;
string barcode = txtBarcode.Text;
string price = txtPrice.Text;
// 生成复杂的ZPL指令
string zplCommand = GenerateComplexZpl(productName, barcode, barcode, price);
// 使用原始API打印
bool success = ZebraUsbPrinter.SendZplToPrinter(printerName, zplCommand);
if (success)
{
MessageBox.Show("打印成功!");
}
else
{
MessageBox.Show("打印失败,请检查打印机连接和名称!");
}
}
private void btnDiscover_Click(object sender, EventArgs e)
{
// 发现USB打印机
ZebraSdkPrinter.DiscoverUsbPrinters();
}
}
}
参考项目 C# 斑马打印机USB接口ZPL条码打印 www.youwenfan.com/contentzhd/111990.html
准备工作
- 安装驱动程序:确保已安装斑马打印机的驱动程序。
- 获取打印机名称:在Windows的"设备和打印机"中找到你的斑马打印机名称。
- 安装SDK(如果使用SDK方法):通过NuGet安装
Zebra.Sdk包。
常见一些问题
- 打印机不响应:检查USB连接,确认打印机名称正确。
- 中文乱码:确保使用
^CI28指令并正确设置中文字体。 - 打印质量差:调整打印密度或清洁打印头。
- 无法连接:以管理员权限运行应用程序。