pikopong

it's all about knowledge

Printing to Zebra S4M Using Java and ZPL II

with 17 comments

Apparently there’re some codes scattered on the net telling people that you can print to a Zebra printer by sending ZPL II codes using PrintService. But the problem is, it’s not working, I don’t know why, maybe because of a different version of printer or model but I’m pretty sure the thing that came out from the printer is just ordinary text not barcode which is what the code was supposed to output.

New Version

Thanks to Oleg for pointing out on how to print using Zebra S4M connected either via USB or network.

The solution is pretty simple, all you have to do is do not install Zebra S4M as a Zebra S4M (sounds weird, I know), instead, just install it as a local raw printer (Linux) or generic text printer (Windows).

For CUPS user in Linux, this is the example for the correct configurations:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#/etc/cups/printers.conf
<Printer Zebra>
Info
Location
DeviceURI socket://10.1.1.5:9100
State Idle
StateTime 1223445299
Accepting Yes
Shared Yes
JobSheets none none
QuotaPeriod 0
PageLimit 0
KLimit 0
OpPolicy default
ErrorPolicy stop-printer
Option orientation-requested 3
</Printer>

You can always add the printer using the web interface, just make sure you choose the RAW as the Make/Manufacturer and Model/Driver.

For Windows user, please take a look at Oleg comment.

Test this Java code, it should print out a barcode:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import javax.print.Doc;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintException;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.SimpleDoc;
import javax.print.attribute.PrintServiceAttribute;
import javax.print.attribute.standard.PrinterName;
 
public class SimplePrint {
 
   public static void main(String[] args) {
 
       try {
 
           PrintService psZebra = null;
           String sPrinterName = null;
           PrintService[] services = PrintServiceLookup.lookupPrintServices(null, null);
 
           for (int i = 0; i < services.length; i++) {
 
               PrintServiceAttribute attr = services[i].getAttribute(PrinterName.class);
               sPrinterName = ((PrinterName) attr).getValue();
 
               if (sPrinterName.toLowerCase().indexOf("zebra") >= 0) {
                   psZebra = services[i];
                   break;
               }
           }
 
           if (psZebra == null) {
               System.out.println("Zebra printer is not found.");
               return;
           }
           DocPrintJob job = psZebra.createPrintJob();
 
           String s = "^XA^FO100,40^BY3^B3,,30^FD123ABC^XZ";
 
           byte[] by = s.getBytes();
           DocFlavor flavor = DocFlavor.BYTE_ARRAY.AUTOSENSE;
           Doc doc = new SimpleDoc(by, flavor, null);
           job.print(doc, null);
 
       } catch (PrintException e) {
           e.printStackTrace();
       }      
   }
}

Old Version

So, I started looking around for other methods. I even tried posting on java’s forum and offered 10 duke points, but no one seems to answer my question. After googling around, I found out that I could upload a file containing the ZPL II to the printer, so, I tried and it did work. But another problem arise, Two people cannot ftp simultaneously due to the limited access set by the printer.

Printing using FTP (I’m using Apache Commons Net library)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import java.io.FileInputStream;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
 
public class FtpPrint {
 
   public static void main(String[] args) {
 
       try {
 
           FTPClient f = new FTPClient();            
 
           f.connect("10.1.127.3");
           f.login("anonymous", "");
           f.setFileType(FTP.ASCII_FILE_TYPE);                            
 
           FileInputStream in = new FileInputStream("/path/to/file");
           if (f.storeFile("filename", in)) {
               System.out.println("Upload ok");
           }                
 
           f.logout();
           f.disconnect();
 
       } catch (Exception e) {
           e.printStackTrace();
       }
   }
}

In the end I had to find another solution. After 3 days of searching the internet up and down, I found out that Zebra’s website offered a piece of code in Java to print using ZPL II using socket programming which automatically solve all of my problems, I was like, what the.. Note to myself, always search for the manufacturer site before googling around. However, a few modifications needed for the given code such as the printer port and the language sent. You can get the codes below:

Printing using socket (Got it from Zebra website)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import java.io.DataOutputStream;
import java.net.Socket;
 
public class SocketPrint {
 
   public static void main(String argv[]) throws Exception {
 
       for (int i = 0; i &lt; 10; i++) {
           Socket clientSocket = new Socket("10.1.127.3", 9100);
           DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
           outToServer.writeBytes("^XA^FO100,40^BY3^B3,,30^FD123ABC^XZ");
           clientSocket.close();
       }
   }
}

Download guide to ZPL II

  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • PDF
  • Print
  • Reddit
  • Slashdot
  • Technorati
  • Twitter

Related Posts

Written by amree

May 11th, 2008 at 9:44 am

Posted in programming

Tagged with ,

17 Responses to 'Printing to Zebra S4M Using Java and ZPL II'

Subscribe to comments with RSS or TrackBack to 'Printing to Zebra S4M Using Java and ZPL II'.

  1. ty this helps! is there a way to test this codeif you dont have a thermal printer – on a normal dev system? i guess can make a port watcher … but anyway if nothing else will test on client dev.

    Tushar KapilaNo Gravatar

    4 Jul 08 at 09:01 AM

  2. @Tushar Kapila

    I’m not sure about that, but the best way is of course to test it on your client’s printer and the codes above definitely work. I tested it using JRE 1.6 and Zebra S4M. Good luck !

    amreeNo Gravatar

    4 Jul 08 at 02:35 PM

  3. UPDATE: This only works on S4M with a PrintServer attached to it. I still don’t know how to print directly using USB cable. If anyone has an idea, please contact me or put your link in the comment box. Thanks :)

    amreeNo Gravatar

    18 Jul 08 at 06:14 PM

  4. In Windows you can use “Enable Printer Pooling” to merge the USB port to LPT1. You can then print to LPT1 programmatically and it will go to the printer.

    It’s in the Printer properties under Ports.

    cdNo Gravatar

    30 Jul 08 at 04:27 AM

  5. @cd

    I’m not sure how can I apply your information in solving problems printing to S4M without a PrintServer. Care to explain more ?

    amreeNo Gravatar

    30 Jul 08 at 11:07 PM

  6. Hello,

    I print to Zebras S4M and S600 anytime by sending ZPL II command in a following way:

    Install Zebra printer (I use standard TCP/IP port). Go to properties of the printer, advanced tab, and change printer driver to “generic text”. (Alternatively, you could just create it as text printer).

    Now, print txt file with ZPL II commands inside directly to that “generic / text” printer. This is it.

    Good luck,
    Oleg.
    OCB Reprographics, Inc.

    OlegNo Gravatar

    8 Oct 08 at 04:02 AM

  7. @Oleg

    That’s what I’m looking for, thanks for your comment. I’ve updated my post accordingly.

    amreeNo Gravatar

    23 Oct 08 at 09:29 AM

  8. hello

    I am trying to work on implementing a similar thing on Zebra TLP2844 which uses EPL. I used the same code that you have used to print out a barcode. I have various requirements of printing text, graphics and a barcode. At the moment, with your code, I am able to connect to the printer in that, I am able to open a tiny printer window but there are no jobs queued in it.
    The printer is connected to my machine via a USB cable. At the moment I am trying to print just a line in the EPL language. I am not sure what it is that I am doing wrong, do I have to change the DocFlavor as it seems to me that the program is connecting to the printer but not printing the job.

    Any help in resolving this issue will be appreciated.

    Thanks.

    lakshmiNo Gravatar

    14 Nov 08 at 12:28 AM

  9. @lakshmi

    I’m sorry, can’t really help you since I don’t have any Zebra connected using USB port, but if I do know about it, I’ll update my post accordingly.

    amreeNo Gravatar

    9 Feb 09 at 08:28 PM

  10. The easest way is to connect the printer using the serial cable using an USB to serial converter like we do. This guarantees bidirectional communication in one easy step.

    You can also just use the parallel port, however the port must be set in bidirectional mode in the BIOS to make sure the communication is bidirectional. On some older PC’s such a bidirectional port is not always available, so the serial channel is always the safest.

    You will of course need to use one of the serial / parallel implementations for java, such as the RXTX library or the Java Comm library.

    FedericoNo Gravatar

    21 Apr 09 at 04:43 PM

  11. i know the above works for text files. if i have a pdf file how do i go about printing to Zebra Printer. I tried reading the pdf file as text and sending it to Zebra using the same method as above…but Zebra Printer Tells me it received x bytes of data but does not physically print anything…Any help is appreciated!

    @preeNo Gravatar

    16 Sep 09 at 04:12 AM

  12. @pree

    I think you need a way to read the pdf file to a normal text and then write it to the printer. But of course, that’s just a suggestion, I don’t know how to do it, maybe Google can help you with that. Good luck!

    amreeNo Gravatar

    18 Sep 09 at 04:12 PM

  13. It’s not the Java way, but I write the ZPL or EPL code to a temporary file and then print it using the operating system’s ‘command line’ print program:

    Windows: print /d:\\WINDOWS\PRINTER_PATH filename.epl
    Linux/OS X: lpr -l -P CUPS_PRINTERNAME filename.epl

    chris_farleyNo Gravatar

    23 Oct 09 at 09:41 PM

  14. You can use a passthrough Mode on the Zebra Printer driver.

    I installed the latest Zebra printer driver for my S4M that came with it.
    Go to Printers and find your S4M, right click and select properties to display the driver info.
    On the General tab, click the Printing Preferences… button. On the Printing Preferences dialog, select the Options tab. Make sure “Enable Passthrough Mode” is checked. Click the options button next to it to check/change the start and end sequence for passthrough mode. By default, the start sequence is “${“, and the end sequence is “}$”.
    So if you put that around you ZPL and then print, it should work. I am connected over USB.

    ${ }$

    SeanNo Gravatar

    9 Nov 09 at 11:05 PM

  15. sir how could i print in a web app using a java applet for a datamax barcode printer

    RencieNo Gravatar

    22 Jan 10 at 08:36 PM

  16. We also had major issues with settings and all for our Windows applications.

    “Zebra Setup Utilities” is a great tool to config your Zebra. Make a custom .zpl file and upload using this tool is only 1 of many possibilities.

    Download tool here from the manufactors site (www.zebr.com):
    http://www.zebra.com/id/zebra/na/en/index/drivers_downloads/utilities/other_utilities/zebra_setup_utilities.html

    Or, if the download location is changed/link doesn’t work, find it this way:
    Home > Drivers & Downloads > Utilities > Other
    Utilities > Zebra Setup Utilities

    SuperTrooper (compenz.nl)No Gravatar

    28 May 10 at 06:31 PM

  17. Great blog, been having problems myself with my Zebra Lp2844 barcode label printer. But after reading this it has helped me no end.

    Many Thanks

    Yan HapplerNo Gravatar

    15 Jun 10 at 10:14 PM

Leave a Reply