You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在VB.NET中通过USB向Zebra打印机发送ZPL字符串打印

解决VB.NET下USB连接Zebra打印机打印FedEx ZPL运单的问题

第一步:验证ZPL内容有效性

先将FedEx API返回的ZPL字符串保存为.zpl文件,用Zebra官方的ZPL Viewer工具或在线预览工具确认格式正确,排除ZPL本身的语法错误。

第二步:VB.NET原生API发送原始ZPL数据

直接调用Windows打印API发送原始数据是最可靠的方式,以下是完整的VB.NET实现:

Imports System
Imports System.Runtime.InteropServices
Imports System.Windows.Forms

Public Class ZplPrinterHelper
    ' Windows打印API声明
    <DllImport("winspool.drv", EntryPoint:="OpenPrinterA", SetLastError:=True, CharSet:=CharSet.Ansi, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)>
    Private Shared Function OpenPrinter(ByVal szPrinter As String, ByRef hPrinter As IntPtr, ByVal pd As IntPtr) As Boolean
    End Function

    <DllImport("winspool.drv", EntryPoint:="ClosePrinter", SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)>
    Private Shared Function ClosePrinter(ByVal hPrinter As IntPtr) As Boolean
    End Function

    <DllImport("winspool.drv", EntryPoint:="StartDocPrinterA", SetLastError:=True, CharSet:=CharSet.Ansi, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)>
    Private Shared Function StartDocPrinter(ByVal hPrinter As IntPtr, ByVal level As Integer, ByVal di As DOCINFOA) As Boolean
    End Function

    <DllImport("winspool.drv", EntryPoint:="EndDocPrinter", SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)>
    Private Shared Function EndDocPrinter(ByVal hPrinter As IntPtr) As Boolean
    End Function

    <DllImport("winspool.drv", EntryPoint:="StartPagePrinter", SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)>
    Private Shared Function StartPagePrinter(ByVal hPrinter As IntPtr) As Boolean
    End Function

    <DllImport("winspool.drv", EntryPoint:="EndPagePrinter", SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)>
    Private Shared Function EndPagePrinter(ByVal hPrinter As IntPtr) As Boolean
    End Function

    <DllImport("winspool.drv", EntryPoint:="WritePrinter", SetLastError:=True, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)>
    Private Shared Function WritePrinter(ByVal hPrinter As IntPtr, ByVal pBytes As IntPtr, ByVal dwCount As Integer, ByRef dwWritten As Integer) As Boolean
    End Function

    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)>
    Private Structure DOCINFOA
        <MarshalAs(UnmanagedType.LPStr)> Public pDocName As String
        <MarshalAs(UnmanagedType.LPStr)> Public pOutputFile As String
        <MarshalAs(UnmanagedType.LPStr)> Public pDataType As String
    End Structure

    ''' <summary>
    ''' 发送ZPL字符串到指定USB打印机
    ''' </summary>
    ''' <param name="printerName">控制面板中显示的打印机全名</param>
    ''' <param name="zplContent">FedEx API返回的ZPL格式字符串</param>
    ''' <returns>是否发送成功</returns>
    Public Shared Function SendZplToPrinter(ByVal printerName As String, ByVal zplContent As String) As Boolean
        Dim hPrinter As IntPtr = IntPtr.Zero
        Dim di As New DOCINFOA()
        Dim dwWritten As Integer = 0
        Dim success As Boolean = False

        Try
            di.pDocName = "FedEx Shipping Label"
            di.pDataType = "RAW" ' 必须指定为原始数据模式,否则打印机无法识别ZPL

            If OpenPrinter(printerName, hPrinter, IntPtr.Zero) Then
                If StartDocPrinter(hPrinter, 1, di) Then
                    If StartPagePrinter(hPrinter) Then
                        ' ZPL使用ASCII编码,避免UTF-8导致的乱码
                        Dim zplBytes As Byte() = System.Text.Encoding.ASCII.GetBytes(zplContent)
                        Dim pBytes As IntPtr = Marshal.AllocCoTaskMem(zplBytes.Length)
                        Marshal.Copy(zplBytes, 0, pBytes, zplBytes.Length)

                        success = WritePrinter(hPrinter, pBytes, zplBytes.Length, dwWritten)

                        Marshal.FreeCoTaskMem(pBytes)
                        EndPagePrinter(hPrinter)
                    End If
                    EndDocPrinter(hPrinter)
                End If
                ClosePrinter(hPrinter)
            End If

            If Not success Then
                Throw New Exception($"打印失败,Windows错误码:{Marshal.GetLastWin32Error()}")
            End If
        Catch ex As Exception
            MessageBox.Show($"打印异常:{ex.Message}")
            success = False
        End Try

        Return success
    End Function
End Class

第三步:业务逻辑调用示例

获取FedEx返回的ZPL字符串后,直接调用工具类:

' 替换为你的Zebra打印机全名(从控制面板复制,确保完全一致)
Dim targetPrinter As String = "Zebra ZD420 (USB)"
' 假设zplContent是从FedEx API获取的ZPL内容
Dim zplContent As String = "你的FedEx ZPL字符串"

ZplPrinterHelper.SendZplToPrinter(targetPrinter, zplContent)

常见问题排查

  • 打印机名称错误:必须使用控制面板中显示的完整打印机名称,不要手动简写。
  • USB连接异常:确保打印机驱动安装正确,能打印Windows测试页。
  • 编码问题:严格使用ASCII编码转换ZPL字符串,UTF-8会导致ZPL指令解析失败。
  • 权限不足:若程序以服务或受限账号运行,需给账号分配打印权限。

内容的提问来源于stack exchange,提问作者Joseph Davenport

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 10:07:16