20

I have an .NET Windows application that prints commands to Zebra printer using ZPL II or EPL2. Is there any way to print preview the data in a form before printing it directly from Zebra printer?

5 Answers 5

28

Have a look at the Labelary web service, which allows you to convert ZPL to an image programmatically.

Just build a URL containing the ZPL that you want to render, get the image back from the web server, and show the image to the user from within your application.

string zpl = "YOUR ZPL HERE"; string url = "http://api.labelary.com/v1/printers/8dpmm/labels/4x6/0/" + zpl; using (WebClient client = new WebClient()) { client.DownloadFile(url, "zpl.png"); } 

There's also a ZPL viewer lets you edit and view ZPL directly on a web page.

Sign up to request clarification or add additional context in comments.

Comments

14

I needed the ability to show the label in my Application. So I hooked up Fiddler and figured out what the communication was to get the image of the label.

I got it running in LinqPad. The HTTP stuff can be cleaned up a bit, but I thought I would post the code for others to use:

void Main() { string printerIpAddress = "10.92.0.167"; string zpl="^XA^CFD^CVY^PON^FWN^LS0^LT0^LH15,17^FS^FO0,2^FO14,3^FH^FDHi^FS^XZ"; // post the data to the printer var imageName = PostZplAndReturnImageName(zpl, printerIpAddress); // Get the image from the printer var image = LoadImageFromPrinter(imageName, printerIpAddress); Console.WriteLine(image); } public static string PostZplAndReturnImageName(string zpl, string printerIpAddress) { string response = null; // Setup the post parameters. string parameters = "data="+ zpl; parameters = parameters + "&" + "dev=R"; parameters = parameters + "&" + "oname=UNKNOWN"; parameters = parameters + "&" + "otype=ZPL"; parameters = parameters + "&" + "prev=Preview Label"; parameters = parameters + "&" + "pw="; // Post to the printer response = HttpPost("http://"+ printerIpAddress +"/zpl", parameters); // Parse the response to get the image name. This image name is stored for one retrieval only. HtmlAgilityPack.HtmlDocument doc = new HtmlDocument(); doc.LoadHtml(response); var imageNameXPath = "/html[1]/body[1]/div[1]/img[1]/@alt[1]"; var imageAttributeValue = doc.DocumentNode.SelectSingleNode(imageNameXPath).GetAttributeValue("alt",""); // Take off the R: from the front and the .PNG from the back. var imageName = imageAttributeValue.Substring(2); imageName = imageName.Substring(0,imageName.Length - 4); // Return the image name. return imageName; } public static string HttpPost(string URI, string Parameters) { System.Net.WebRequest req = System.Net.WebRequest.Create(URI); req.Proxy = new System.Net.WebProxy(); //Add these, as we're doing a POST req.ContentType = "application/x-www-form-urlencoded"; req.Method = "POST"; //We need to count how many bytes we're sending. //Post'ed Faked Forms should be name=value& byte [] bytes = System.Text.Encoding.ASCII.GetBytes(Parameters); req.ContentLength = bytes.Length; System.IO.Stream os = req.GetRequestStream(); os.Write (bytes, 0, bytes.Length); //Push it out there os.Close (); System.Net.WebResponse resp = req.GetResponse(); if (resp== null) return null; System.IO.StreamReader sr = new System.IO.StreamReader(resp.GetResponseStream()); return sr.ReadToEnd().Trim(); } public static Image LoadImageFromPrinter(string imageName, string printerIpAddress) { string url = "http://"+ printerIpAddress +"/png?prev=Y&dev=R&oname="+ imageName +"&otype=PNG"; var response = Http.Get(url); using (var ms = new MemoryStream(response)) { Image image = Image.FromStream(ms); return image; } } public static class Http { public static byte[] Get(string uri) { byte[] response = null; using (WebClient client = new WebClient()) { response = client.DownloadData(uri); } return response; } } 

This has the following References:

HtmlAgilityPack System.Drawing System.Net 

and the following Uses:

HtmlAgilityPack System.Drawing System.Drawing.Imaging System.Net 

NOTE: I could not find a way to communicate with a serial/non-IP Addressed printer. (Though that does not mean that there is not a way.)

9 Comments

Seems good work! Could you add which printer vendor and model your code works with, please?
@bluish - Zebra Label Printers. I tested it on a ZM400.
Also works with Zebra170Xi4. I've found that the image the printer generates creates a large amount of white space around the rendered label. I'm not sure if setting a label width in the ZPL will fix that (most of our designs do not).
What did you use for your printer IP address? Was it hooked up to your computer via USB? Or was it just under a print server? Any idea how I would use this just through USB or local network?
@JWiley - I don't know that this could work via USB. We use a printer that is on our LAN. It has a fixed IP address (setup by my system admins). You can get the IP address from the ZM400 printer that I used.
|
6

If you don't want to send your data to a cloud service you can have a look at our project we have developed an open ZPL viewer that converts ZPL data into a graphic. The project is based on .NET.

More Informations are available here BinaryKits.Zpl.Viewer (GitHub)

Also a nuget package is available

PM> install-package BinaryKits.Zpl.Viewer

Example code

IPrinterStorage printerStorage = new PrinterStorage(); var drawer = new ZplElementDrawer(printerStorage); var analyzer = new ZplAnalyzer(printerStorage); var analyzeInfo = analyzer.Analyze("^XA^FT100,100^A0N,67,0^FDTestLabel^FS^XZ"); var labels = new List<LabelDto>(); foreach (var labelInfo in analyzeInfo.LabelInfos) { var imageData = drawer.Draw(labelInfo.ZplElements); } 

2 Comments

Is your project's "BinaryKits.Zpl.Viewer" module available in a version for Android (Java/Kotlin)? If not, do you have any plans to make it available on Android?
@BenBloodworth No we have no plans for this
5

If you're ok with using a Chrome Plugin, please try Simon Binkert's Zpl Printer. This plugin is based on the Labelary Web Service linked in previous comments.

See also: https://stackoverflow.com/a/33066790/3196753

Note, although this plugin runs inside Google Chrome, it can work with any application on the computer capable of sending raw commands.

chrome zpl printer

It can be configured to listen on localhost or dedicated IP address, so it can be used to emulate a ZPL printer on the PC and local network. If you need a local printer or printer share, you can set up a raw printer queue on the PC which points to it on hostname/ip and port and other desktop applications will be able to send ZPL to it.

Note, if you need to make it available to other computers on the network, make sure to change 127.0.0.1 in the Printer Settings to a valid LAN IP address.

Comments

2

The only way to preview the label is on the printer's web page.

If you go to the printer's directory listing http://<printer IP>/dir and click on the saved label (or create a new one) then you can click "Preview Label"

3 Comments

There are a few other ways to do this using the printer format the label without printing. Is having a printer in-line acceptable?
What if I only have the printer driver installed and not the actual printer? Can I still be able to access this directory listing?
For others looking for how to do this, see my answer that has the code to get the label preview.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.