C# 通过USB连接斑马打印机打印ZPL条码

用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

准备工作

  1. 安装驱动程序:确保已安装斑马打印机的驱动程序。
  2. 获取打印机名称:在Windows的"设备和打印机"中找到你的斑马打印机名称。
  3. 安装SDK(如果使用SDK方法):通过NuGet安装Zebra.Sdk包。

常见一些问题

 

专注于matlab/simulink,电子电路,编程