在将ZPL II命令发送到Zebra打印机之前,使用.NET WinForm预览并打印ZPL II命令。

20

我有一个.NET Windows应用程序,它使用ZPL II或EPL2将命令打印到Zebra打印机。是否有办法在直接从Zebra打印机打印之前预览表单中的数据?

5个回答

27

请查看Labelary web服务,该服务允许您以编程方式将ZPL转换为图像。

只需构建一个包含要呈现的ZPL的URL,从Web服务器获取图像,并在应用程序中向用户显示该图像。

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");
}

还有一个ZPL查看器,可以让您直接在网页上编辑和查看ZPL。


13

我需要在我的应用程序中显示标签。因此,我使用了Fiddler,并弄清楚了获取标签图像的通信方式。

我已将其运行在LinqPad中。HTTP部分可以进行一些清理,但我想发布代码供其他人使用:

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;
    }   
}

这里列出了以下参考文献:

HtmlAgilityPack
System.Drawing
System.Net

以及以下用途:

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

注意:我找不到一种与串口或非IP地址打印机进行通信的方法。(尽管这并不意味着没有方法。)


@bluish - Zebra 标签打印机。我在 ZM400 上进行了测试。 - Vaccano
也适用于Zebra170Xi4。我发现打印机生成的图像在渲染标签周围创建了大量的空白区域。我不确定在ZPL中设置标签宽度是否会解决此问题(我们大部分设计都不需要)。 - nbering
你用什么来设置打印机的IP地址?是通过USB连接到电脑上吗?还是连接到打印服务器上了?有没有想过如何通过USB或本地网络使用它? - JWiley
@JWiley - 我不知道这是否可以通过 USB 实现。我们使用的打印机位于局域网上。它有一个固定的 IP 地址(由我的系统管理员设置)。你可以从我使用的 ZM400 打印机中获取 IP 地址。 - Vaccano
你的ZM400有一个固定的IP地址吗?它不是通过LPT1连接的吗?如果我可以根据连接到打印机的计算机来分配IP地址,你有什么想法如何使用这种方法? - JWiley
显示剩余4条评论

5
如果您愿意使用Chrome插件,请尝试Simon Binkert的Zpl Printer。该插件基于先前评论中链接的Labelary Web Service
另请参阅:https://dev59.com/41wY5IYBdhLWcg3wD0LG#33066790 请注意,尽管此插件在Google Chrome内运行,但它可以与计算机上能够发送原始命令的任何应用程序一起使用。

chrome zpl printer

它可以配置为侦听本地主机或专用IP地址,因此可用于在PC和本地网络上模拟ZPL打印机。如果您需要本地打印机或打印机共享,可以在PC上设置原始打印队列,该队列指向主机名/IP和端口,并且其他桌面应用程序将能够将ZPL发送到它。
请注意,如果您需要使其对网络中的其他计算机可用,请确保在打印机设置中将127.0.0.1更改为有效的LAN IP地址。

4
如果您不想将数据发送到云服务,可以查看我们的项目,我们开发了一个开放的ZPL查看器,将ZPL数据转换为图形。该项目基于.NET。
更多信息请参见BinaryKits.Zpl.Viewer (GitHub) 同时提供nuget包

PM> install-package BinaryKits.Zpl.Viewer

示例代码
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);
}

你们项目中的“BinaryKits.Zpl.Viewer”模块是否有针对Android(Java/Kotlin)的版本?如果没有,你们有计划在Android上提供该模块吗? - Ben Bloodworth
@BenBloodworth,我们没有这方面的计划。 - Tino Hager

2

唯一预览标签的方法是在打印机的网页上。

如果您进入打印机的目录列表 http://<打印机IP>/dir,然后单击保存的标签(或创建新标签),则可以单击 "预览标签"


有其他几种方法可以使用打印机格式化标签而不进行打印。在线打印机是否可接受? - banno
如果我只安装了打印机驱动程序而没有实际的打印机,我是否仍然可以访问此目录列表? - SleepNot
对于其他人寻找如何做到这一点的,可以查看我的答案,其中包含获取标签预览的代码。 - Vaccano

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接