Ciertas impresoras Zebra pueden imprimir mediante un código nativo denominado ZPL, la ventaja de usar este código frente a Crystal Report es la rapidez en la impresión y la posibilidad de enviar comandos de control a la impresora.
En este ejemplo se imprimirán unas etiquetas de asistencia a un congreso. El operador introducirá mediante mediante una aplicación los datos necesarios e imprimirá una etiqueta que internamente será enviada a la impresora mediante código ZPL.
Corregido 08/03/13
Software y Material necesario:
- Impresora Zebra compatible con lenguaje ZPL. En este ejemplo se han usado las impresoras Zebra S600 y S4M.
- Entorno de desarrollo compatible con Visual Basic .NET. Se ha usado Microsoft Visual Studio .NET 2003
- Documentación sobre el lenguaje ZPL. ZPL II Programming Guide
La aplicación solicitará unos datos al operador mediante una pantalla y ofrecerá un botón para imprimir la etiqueta.
Internamente la clase de recogida de datos enviará la información a la clase impresión ZPL y esta se encargará de lanzar los códigos necesarios por el puerto LPT a la impresora.
Pasos
Lo primero que se deberá realizar será compartir la impresora Zebra en el equipo donde esta conectada, en nuestro caso el recurso compartido será \\NombreEquipo\ZebraS60.
Para imprimir vamos a usar el puerto LPT2 (puede ser cualquier otro). Desde el equipo que tiene la aplicación tenemos que mapear este puerto mediante el comando:
net use LPT2 \\NombreEquipo\ZebraS60
Los datos que vamos a solicitar en la aplicación son:
nombre del evento.
nombre, apellidos y empresa del asistente
fecha actual
código, en el ejemplo es un texto manual que servirá de identificador único, en la
etiqueta se imprimirá como un código de barras.
Creamos una clase de Visual Basic con el nombre ImpresionZPL, el código de la misma es el siguiente:
Imports System
Imports System.IO
Imports System.Drawing
Imports System.Drawing.Printing
Imports System.ComponentModel
Imports System.Runtime.InteropServices
Public Class ImpresionZPL
Public Const GENERIC_WRITE = &H40000000
Public Const OPEN_EXISTING = 3
Public Const FILE_SHARE_WRITE = &H2
Dim LPTPORT As String
Dim PuertoImpresion As String = "LPT2"
Friend WithEvents btnImpresion As System.Windows.Forms.Button
Friend WithEvents btnSalir As System.Windows.Forms.Button
Dim hPort As Integer
Public Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" ( _
ByVal lpFileName As String, ByVal dwDesiredAccess As Integer, _
ByVal dwShareMode As Integer, _
ByRef lpSecurityAttributes As SECURITY_ATTRIBUTES, _
ByVal dwCreationDisposition As Integer, _
ByVal dwFlagsAndAttributes As Integer, _
ByVal hTemplateFile As Integer) As Integer
Public Declare Function CloseHandle Lib "kernel32" Alias "CloseHandle" _
(ByVal hObject As Integer) As Integer
Dim retval As Integer
Public Structure SECURITY_ATTRIBUTES
Private nLength As Integer
Private lpSecurityDescriptor As Integer
Private bInheritHandle As Integer
End Structure
Public Sub Impresion(ByVal Evento As String, ByVal Nombre As String, _
ByVal Apellidos As String, ByVal Empresa As String, _
ByVal Codigo As String, ByVal Fecha As String)
Dim SA As SECURITY_ATTRIBUTES
'outFile es el archivo stream que contien la etiqueta y su formato
Dim outFile As FileStream, hPortP As IntPtr
'Imprime por LPT1 en local.
'Para la impresión por red vía net use.
'Se ha de crear un bat con: --> net use LPT2 /del
' --> net use LPT2 \\NombrePC\NombreImpresoraCompartida y colocarlo en
'....\All Users\Menú Inicio\Programas\Inicio
'para que cada usr. que inicie tenga
LPTPORT = PuertoImpresion
hPort = CreateFile(LPTPORT, GENERIC_WRITE, FILE_SHARE_WRITE, _
SA, OPEN_EXISTING, 0, 0)
'Convertir Integer a IntPtr
hPortP = New IntPtr(hPort)
'Crear FileStream usando Handle
outFile = New FileStream(hPortP, FileAccess.Write, False)
Dim fileWriter As New StreamWriter(outFile)
'Sustitución de caracteres. El alfabeto que maneja esta impresora en concreto
'es solo inglés por eso se sustituyen las tildes, eñes, etc.
'Esta operación se debe realizar con todos los campos susceptibles a contener
'carácteres no aceptados
Apellidos = (Apellidos.Replace("á", "a").Replace("é", "e").Replace("í", "i").Replace("ó", "o").Replace("ú", "u").Replace("Á", "A").Replace("É", "E").Replace("Í", "I").Replace("Ó", "O").Replace("Ú", "U").Replace("ñ", "n").Replace("Ñ", "N").Replace("ç", "c").Replace("Ç", "C").Replace("ª", "."))
'Poner a mayusculas la primera letra
Empresa = Empresa.ToLower
Empresa = (Application.CurrentCulture.TextInfo.ToTitleCase(Empresa))
Nombre = Nombre.ToLower
Nombre = (Application.CurrentCulture.TextInfo.ToTitleCase(Nombre))
Apellidos = Apellidos.ToLower
Apellidos = (Application.CurrentCulture.TextInfo.ToTitleCase(Apellidos))
'--------------------------INICIO ETIQUETA---------------------------'
fileWriter.Write("^XA")
'Deshabilita el panel de la impresora, para que el usr no pueda acceder
fileWriter.Write("^MPS")
'Posicion del eje de cordenadas, en dots
fileWriter.Write("^LH0,0")
'FO para el inicio de escritura, eje X,Y
'AU el formato de la fuente
'FB establece un espacio de 900 dots y la C para centrar el texto
fileWriter.Write("^FO1,30^AU^FB900,1,0,C^FD" & Evento & "^FS")
'AD el formato de la fuente y el 20 para el tamaño de la fuente
fileWriter.Write("^FO50,90^AD,,20^FD" & Apellidos & "^FS")
fileWriter.Write("^FO50,130^AD,,20^FD" & Nombre & "^FS")
fileWriter.Write("^FO520,130^AD,,10^FD" & "Historia Cl. " & Empresa & "^FS")
'GB escribe una linea horizontal 900 largo, 0 grosor y 2 ancho
fileWriter.Write("^FO50,165^FR^GB900,0,2^FS")
fileWriter.Write("^FO520,180^AD^FD" & Fecha & "^FS")
'B3 escribe el texto en cod. de barras tipo B3 (alfanumerico)
'el 60 para el tamaño
fileWriter.Write("^FO200,200^B3,,60^FD" & Codigo & " ^FS")
'--------------------------PIE DE ETIQUETA---------------------------'
fileWriter.Write("^FO100,290^AD^FD" & "SUJA Corporation" & "^FS")
'Finaliza la etiqueta
fileWriter.Write("^XZ")
fileWriter.Flush()
fileWriter.Close()
outFile.Close()
retval = CloseHandle(hPort)
End Sub
End Class
Ahora es necesario crear una interfaz para introducir de forma sencilla los datos.
Public Class frmSolicitudInfo
Private Sub btnImprimir_Click(sender As System.Object, e As System.EventArgs) _
Handles btnImprimir.Click
Dim NuevaImpresionZPL As New ImpresionZPL
NuevaImpresionZPL.Impresion(txtEvento.Text, txtNombre.Text, _
txtApellidos.Text, txtEmpresa.Text, _
txtCodigo.Text, dtpFecha.ToString)
End Sub
Private Sub btnSalir_Click_1(sender As System.Object, e As System.EventArgs) Handles btnSalir.Click
Me.Close()
End Sub
End Class
_____________________________________________________________
Problema:
La aplicación fue realizada con MS Visual Studio 2003 y al compilarla con una versión superior muestra la siguiente alerta referente al uso de una biblioteca obsoleta.
Para solucionarlo ver el enlace http://msdn.microsoft.com/es-es/library/ee461502.aspx
Debemos modificar el archivo app.config de nuestra aplicación.


Hola, estaba usando tu ejemplo desde hace harto tiempo, y de pronto comenzó a arrojar un error al imprimir, esto comienza cuando el computador que tiene la impresora cambio de sistema operativo WinXP a Win7, habrá que hacer alguna configuración adicional en la impresora?
ResponderEliminarGracias, Ariel.
que pasa si el puerto no es LPT, si fuera el puerto USB??? o TCP IP???? como podria imprimir en la impresora zebra?
ResponderEliminarTengo problemas imprimiendo con una Zebra USB. El puerto virtual es el USB005 y no me funciona. ¿Alguna idea?
ResponderEliminarHola! que versión se debería colocar en el archivo app.config?
ResponderEliminarHola,
ResponderEliminarEstaba validando tu codigo pero me da error en esta linea
outFile = New FileStream(hPortP, FileAccess.Write, False)
Error
System.ArgumentException: 'Invalid handle.