what are the interface, dll, classes I have to call from an external application to print from zebra 22xi4?
Hello, I am helping a mutual customer to print zebra tags from my application, which is heavily based on vbscript, vbasic. What is the application, classes properties, dlls, I have to call once installed the drivers for the 22xi4 printer for starting the printer, specifying the number of labels I need to print and so on?
Hi Tobias,
If you want to print using the xi4 driver and vbscript, set the driver to default printer and use : objFile.InvokeVerbEx( "Print" )
VBScript Scripting Techniques: Printing Files
In standard VB, you have more control over layout and pages and can use the PrintDocument class:
PrintDocument Class (System.Drawing.Printing)
Points: 0
You voted ‘up’
Hi Robin,
thank you for your quick response. I still do not understand quite right "what file". The customer told me they have a printer and they have a zebra pro where they design the labels. The labels's text can be extracted from a database and the label can be to the printer(at least in the licensed version) as the by default label.
In the other hand they would like to print a row from the grid our program offers. Right now I copied the selected row into a csv file wich is the data base fro the label above.
Now, how do I say to the printer
"Print!" assuming it will take the label by default and the label will be fed in that moment using th cvs file, that I just updated before saying print.
is there a way i can say. printer by default. print or zebra pritner.print? Hopefully with the number of pages(with vbasic as you suggested cause vbscript wont do it)
If things function differently and zebra uses a specific program to print asking for the number of copies let me know as well, and thanks in advance
Points: 0
You voted ‘up’
Hi Tobias,
Thanks for the extra info. I don't believe you will be able to use vbscript.
To explain what you can do, it's necessary to explain a few things about how ZebraDesigner Pro works. The designer allows your customer to create a label template with some fields that get filled in via the database. As an example, if they were printing shipping labels, they design it to place the address always in one area and the tracking number in another. They would also place a barcode that would take the same tracking number for data. Columns in the database table would likely be labeled 'address' and 'tracking_number'.
So, your customer needs to export the template to a file and send it to you in order for you or your app to print the same labels your customer is. Otherwise the printer has no idea where to put each cell of data. You could design something yourself with the free version of ZebraDesigner or VB, but it wouldn't match your customer template.
Once you have the template, you have a few options. What OS are you printing from and are you printing over USB, network, Bluetooth, or don't know?
Points: 0
You voted ‘up’
yes, I already used the designer pro to create a label that looks like a
picture that my customer sent me, but I cannot export it to the printer
because it is a demo(unlicensed) and demo do not export label with more
than 1 variables.
in this case i created in the label the texts as variables and I used as a
database a csv file I modify with the data of my application. when I try to
preview from the designer it shows me the last data, so that part is
running fine.
When i use vbscript to call my application developer kit(my application is
made in visual basic but has dlls that can be used from vbscript) I can
modify that file and it is in that moment I need to say, print and how many
copies.
I assume the customer is using windows, printing to a network location
2017-07-20 16:20 GMT-04:00 Robin West <
zebra-dev@zebra-dev-v8.hosted.jivesoftware.com>:
Points: 0
You voted ‘up’
Hi Tobias,
Because you are not using the designer to print via a database directly you can use the actually free version of ZebraDesigner Basic Barcode Label Software | Zebra . Just save your design and open it in this version and you should be able to export the template.
There are two things you can do with it then:
1. If you know the printers are networked, you can open a TCP socket and send the template and csv data - formatted as in red below - directly to port 9100 on the printer.
2. Create a new Generic Text printer and point it at the same port as your zebra printer. Then you can use the code below to print in vb.
There may be a simpler way to handle this, but this works. It assumes the generic driver is default, but you can add a PrintDialog to let your user select the printer instead. The form just has two buttons on it (one for sending the format, the other for printing the CSV) Always send the format to the printer first, but it is saved so you only really need to do it once.
Form1.vb
Imports System.IO
Imports System.Drawing.Printing
' Based on the sample code found in https://msdn.microsoft.com/en-us/library/system.drawing.printing.printdocument(v=vs.110).aspx?cs-save-lang=1&cs-lang=vb#code-snippet-2
Public Class Form1
Private printFont As Font
Private streamToPrint As TextReader
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Try
streamToPrint = New StreamReader("C:\My Documents\Format.zpl")
' Contents of format.zpl file:
' ^XA^DFE:Format.ZPL^MNN^LL400^FS
' ^FO20,20^A0N,50,50^FN11^FS
' ^FO20,70^A0N,50,50^FN12^FS
' ^FO20,120^A0N,50,50^FN13^FS
' ^XZ
Try
printFont = New Font("Arial", 1)
Dim pd As New PrintDocument()
AddHandler pd.PrintPage, AddressOf Me.pd_PrintPage
pd.Print()
Finally
streamToPrint.Close()
End Try
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Try
Dim startPrint As String = "^XA^XFE:FORMAT.ZPL"
Dim endPrint As String = "^XZ"
Dim setField As String = "^FN"
Dim setData As String = "^FD"
Dim endData As String = "^FS"
Dim myData As String = startPrint
Dim CSVData As String = "Hello, World, 12345"
' Take the csv and convert it to ZPL for printing - This may need to be modified based on the template
Dim words As String() = CSVData.Split(New Char() {","c})
Dim word As String
Dim index As Integer = 11 ' most templates in the designer start at field number 11
For Each word In words
myData = myData & setField & index.ToString & setData & word & endData
index += 1
Next
myData = myData & endPrint
'print the label
streamToPrint = New StringReader(myData)
Try
printFont = New Font("Arial", 1)
Dim pd As New PrintDocument()
AddHandler pd.PrintPage, AddressOf Me.pd_PrintPage
pd.Print()
Finally
streamToPrint.Close()
End Try
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
' The PrintPage event is raised for each page to be printed.
Private Sub pd_PrintPage(ByVal sender As Object, ByVal ev As PrintPageEventArgs)
Dim linesPerPage As Single = 0
Dim yPos As Single = 0
Dim count As Integer = 0
Dim leftMargin As Single = ev.MarginBounds.Left
Dim topMargin As Single = ev.MarginBounds.Top
Dim line As String = Nothing
' Calculate the number of lines per page.
linesPerPage = ev.MarginBounds.Height / printFont.GetHeight(ev.Graphics)
' Print each line of the file.
While count < linesPerPage
line = streamToPrint.ReadLine()
If line Is Nothing Then
Exit While
End If
yPos = topMargin + count * printFont.GetHeight(ev.Graphics)
ev.Graphics.DrawString(line, printFont, Brushes.Black, leftMargin, yPos, New StringFormat())
count += 1
End While
' If more lines exist, print another page.
If (line IsNot Nothing) Then
ev.HasMorePages = True
Else
ev.HasMorePages = False
End If
End Sub
End Class
Points: 0
You voted ‘up’
Also to answer your question about multiple pages:
You can handle each row separately as it's own print job, or combine them as so:
Dim CSVData As String = "Hello,World,12345" & vbCr & "My Name is,Robin,456879" & vbCr & "Tobias,Sanchez,789456"
Dim lines As String() = CSVData.Split(vbCr)
Dim line As String
For Each line In lines
' Take the csv and convert it to ZPL for printing - This may need to be modified based on the template
Dim words As String() = line.Split(New Char() {","c})
Dim word As String
Dim index As Integer = 11 ' most templates in the designer start at field number 11
For Each word In words
myData = myData & setField & index.ToString & setData & word & endData
index += 1
Next word
myData = myData & endPrint
Next line
To print multiple copies with the same data, just before the end of the format file, there is usually a ^PQ1,0,0 Change the first number to your desired copies. You can also set this in the ZDesigner driver preferences and it will be part of the template when you export.
Points: 0
You voted ‘up’
Hello
Thanks for the response.
I have prepared some questions and comments based on it.
1.I have to use designer pro because I am trying to grab the data from the
csv file. the csv file is my "database" allowing the customer to prepare
their own formats and variables
2. About the procedure
this is the way I think it works, please correct me if I am wrong, I create
a cvs file and put it in a location.
The label was set up for grabbing the data from the csv from that location
The label was set up as the label by default in that printer
The printer was setup as the by default printer in that computer
Someone opens my program and from the n records I show them they select
one, go the menu and execute the print option
In the print option, using vbs or a call from vbs to a vb6 component(my
system uses vb6 I do not know if using a vb.net component would create a
problem) I change the values of the csv to the values of the record
selected and somehow ask the printer to print
The printer knows where to find the label, the label got its own format and
knows where to find the data(csv)
I am right or wrong?
3 Answering your advice to send the csv to print directly
If I do so directly I lose the customer formatted .lbl layout, the .lbl
are created by the designer pro in the customer side, i just make sure the
csv has the same fields(more properly the values of that field) the
customer specifies in the .lbl .
4. Do I have to use zpl(I am level 0 in that language) to ask the printer
to star a job?
5 With regard to managing m y rows as its own print job, I print only one
line, the one suggested by the customer, but thanks, I will keep this code
just in case they want to print more lines.
2017-07-20 18:00 GMT-04:00 Robin West <
zebra-dev@zebra-dev-v8.hosted.jivesoftware.com>:
Points: 0
You voted ‘up’
Robin, I found a way to get the zpl code of a label file, via print to
file, and I was able to modify it, putting my data into it. However, when I
put this code into a file and ask the file to be printed from vb.net, it
prints the text/code zpl instead of the label designed in that code,.how
can I "execute this code" so it prints a label?
2017-07-21 10:36 GMT-04:00 Tobias Sanchez <tobias.aquiles@gmail.com>:
>
>> Zebra Technologies Developer Portal <https://developer.zebra.com/>
>> what are the interface, dll, classes I have to call from an external
>> application to print from zebra 22xi4?
>>
>> reply from Robin West
>> <https://developer.zebra.com/people/RWest?et=watches.email.thread> in *Label
>> And Receipt Printing* - View the full discussion
>> <https://developer.zebra.com/message/94269?et=watches.email.thread#94269>
>>
Points: 0
You voted ‘up’
Hi Tobias,
Robin is out for Zebra's AppForum in Shanghai this week. However, it sounds like the printer language may be set to line print. You can check the language using this SGD command:
! U1 getvar "device.languages"
And you can set the printer language to ZPL using this command:
! U1 setvar "device.languages" "zpl"
This command can be found on page 657 of the ZPL Programming Guide. You can send these commands in an application or through Zebra Setup Utilities.
Points: 0
You voted ‘up’
Hello Samantha,
To be honest with you I was attempting this in a regular printer, since I
have no access to a zebra printer. I have now a label printer in my desk
type dymo.
I will research the sgd command. I have seen it before in some forums but I
am writing code in vbscript or vb net. Can i in the middle of the code send
that command just like that?
this is my code in vb net
Imports System.IO
Imports System.Drawing.Printing
Public Class Form1
Inherits System.Windows.Forms.Form
Private streamToPrint As StreamReader
Private printFont As Font
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles
Button1.Click
streamToPrint = New
StreamReader("C:\Users\Tobias\Desktop\testforzebra.zpl")
Dim ipAddress As String = "192.168.2.169"
Dim port As Integer = 9100
Dim ZPLString As String = streamToPrint.ReadToEnd()
MsgBox(ZPLString)
Try
'Open Connection
Dim client As New System.Net.Sockets.TcpClient
client.Connect(ipAddress, port)
Can I do this in the middle of my vb net code?
! U1 getvar "device.languages"
! U1 setvar "device.languages" "zpl"
'Write ZPL String to Connection
Dim writer As New System.IO.StreamWriter(client.GetStream())
writer.Write(ZPLString)
writer.Flush()
! U1 setvar "device.languages" "line"
'Close Connection
writer.Close()
client.Close()
Catch ex As Exception
'Catch Exception Here
End Try
End Sub
End Class
IF i had a print label type dymo, would that help testing or is it an
entirely different language?
2017-07-24 17:07 GMT-04:00 Samantha Corn <
zebra-dev@zebra-dev-v8.hosted.jivesoftware.com>:
Points: 0
You voted ‘up’
Hi Tobias,
Set-Get-Do (SGD) commands are apart of Zebra's printer control language, so they can't be sent as-is in the middle of code. You can send the strings as raw data to the printer, as long as there is a carriage return included in the string. You should just be able to add it to beginning of the string of ZPL you're sending to the printer.
Points: 0
You voted ‘up’
Thanks for the SGDs, I am sure I will use them soon.
I finally found an example to explain myself. This is what I am doing with
a label printer type dymo in visual basic
Sub TestLabel()
Dim myDymo As DYMO_DLS_SDK.DymoHighLevelSDK
Dim dyAddin As DYMO_DLS_SDK.ISDKDymoAddin
Dim dyLabel As DYMO_DLS_SDK.ISDKDymoLabels
Set myDymo = New DYMO_DLS_SDK.DymoHighLevelSDK
Set dyAddin = myDymo.DymoAddin
Set dyLabel = myDymo.DymoLabels
dyAddin.SelectPrinter dyAddin.GetDymoPrinters
dyAddin.Open Environ$("USERPROFILE") & "\My Documents\DYMO
Label\Labels\labelt2.label"
dyLabel.SetField "Text", "Dymo test for Peter"
dyAddin.Print2 3, True, 0
Set myDymo = Nothing
End Sub
In vbscript
Dim DymoAddIn, DymoLabel
Set DymoAddIn = CreateObject("DYMO.DymoAddIn")
Set DymoLabel = CreateObject("DYMO.DymoLabels")
DymoAddIn.Open "C:\Users\Tobias\Documents\My Documents\DYMO
Label\Labels\labelt2.label"
DymoLabel.Setfield "Price" ," 24.99"
DymoAddIn.Print2 1, TRUE, 0
Could you please provide the names in red for calling the zebra
printer instead? I am assuming if Dymo has an interface Zebra has it as well
2017-07-25 8:47 GMT-04:00 Tobias Sanchez <tobias.aquiles@gmail.com>:
>
>
>
>
>
>> Zebra Technologies Developer Portal <https://developer.zebra.com/>
>> what are the interface, dll, classes I have to call from an external
>> application to print from zebra 22xi4?
>>
>> reply from Samantha Corn
>> <https://developer.zebra.com/people/SCorn?et=watches.email.thread> in *Label
>> And Receipt Printing* - View the full discussion
>> <https://developer.zebra.com/message/94324?et=watches.email.thread#94324>
>>
Points: 0
You voted ‘up’
Hi Tobias, I just saw your last question here was not responded to. I know it may be too late, but I wanted to get this out in case others had similar issues. We have a sample of what I think you are looking for here: Zebra Technologies - Send ZPL Commands via TCP/IP in VB.net It looks extremely similar to what you have posted and is code we tested. You can send the SGD's in separate write commands prior to sending the label, or add them to the ZPLString as long as there are carriage returns between them.
Dim ZPLString As String = _
"! U1 setvar ""device.languages"" ""zpl"" " & Chr(13) & Chr(10) _
"^XA" & _
"^FO50,50" & _
"^A0N,50,50" & _
"^FDHello, World!^FS" & _
"^XZ"
Points: 0
You voted ‘up’