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?
问题:
回答1:
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.
回答2:
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.)
回答3:
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"
回答4:
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.
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.