2012-06-10 254 views
27

我们试图从网页上打印条形码到我们的Zebra打印机。从网页打印条形码到Zebra打印机

我不知道是否有一种方法使用打印机自带的字体可能使用网络字体,或​​者如果我知道的字体名称用于打印呢?

我一直在尝试使用PHP的条码生成器,基本上生成包含条形码的图像。事实上,我已经尝试了这种方法几天,但没有成功。

问题是,当我打印它们时,扫描仪无法读取它。我试图改变图像分辨率以匹配打印机(203dpi)的分辨率,也尝试使用图像大小和格式进行播放,但打印后的条形码仍然无法扫描。

那么有没有人有这方面的经验?

打印机:斑马TLP 2844

条码每页需要:

  • 01 39码水平(可扫描仅当印刷在非常特定的大小和浏览器)
  • 01的Code128垂直(仍然不能得到它的工作,打印总是很模糊的文件,也不会扫描)

===========

我已经取得了一些进展,我发现这款打印机支持EPL2语言,所以我试图用它打印出条码。

首先,我需要启用直通模式,我这样做的打印机选项>高级设置>杂项。

现在我能打印无可挑剔使用打印机的内置字体条码:d使用这个命令:

ZPL: B10,10,0,1,2,2,60,N,” TEXT-GOES-HERE“ :ZPL

但是我只能从记事本打印它,我仍然无法从浏览器打印此文件......这可能是LF被CR + LF替换的问题。

如何解决这个问题?

===========

我想实际打印的标签具有条形码之前一些文字,一些HTML表格很好地进行格式化。所以我需要首先打印,而在中间我需要粘贴一个不错的标签,然后添加更多的文字。

所以我不能使用纯EPL2来打印整个东西,我想知道我是否可以使用html + EPL2 + html中的一些来实现我的目标或者是不允许的? =/

+0

看起来你在下面有一些有希望的答案。只是想补充一点,您不能将HTML格式与ZPL结合在一起。您需要使用ZPL完成整个标签格式。有很多箱子和文字和东西的选项,所以它是可行的。 – EdHayes3

回答

18

您正在运行到几个障碍:

1)当您打印通过OS安装打印机驱动程序,打印机驱动程序试图把发送给它的数据,并(重新)光栅化或对输出设备(Zebra打印机)进行缩放。由于打印机的分辨率相对较低,为203dpi,因此打印驱动程序所需的缩放比例并不会太大,因为打印驱动程序必须采取措施来降低条形码质量的某些完整性。这就是为什么使用直接ZPL命令生成的条形码更为可靠的原因是更多

2)由于Web浏览器通过不允许访问客户端计算机的目的而提供的安全性,您不能直接与客户端连接的打印机进行通信。这种沙盒功能有助于保护用户免受恶意软件攻击,因此恶意网站无法执行将文件写入客户端计算机或将输出直接发送到设备(如打印机)的操作。因此,您无法通过浏览器直接将ZPL命令发送到客户端连接的打印机。

但是,有一种方法可以完成您所描述的内容。如果您对访问试图打印到Zebra打印机的网站的客户端计算机有一定程度的控制权,那么必要的步骤通常才会有用。例如,这只会被公司网络中的机器使用,或者由愿意安装需要编写的小型应用程序的客户使用。要做到这一点,你需要看看以下步骤:你需要组成你自己的自定义MIME类型。这基本上只是你想使用的任何名字,不会与任何registered MIME types相冲突。

B)接下来,您将定义一个将映射到您的自定义MIME类型的文件扩展名。为此,您通常需要配置您的Web服务器(步骤取决于您使用的Web服务器)以允许您想要定义的新MIME类型以及用于这些类型的文件的文件扩展名。

C)然后在您的Web应用程序中,当您要输出ZPL数据时,使用映射到新MIME类型的文件扩展名将其写入文件。然后一旦生成文件,您可以提供HTML链接,或将客户端浏览器重定向到该文件。通过手动将您创建的文件直接复制到原始打印机端口,您可以测试您的文件是否正常工作。

D)接下来你需要编写一个可以安装在客户端上的小应用程序。安装应用程序时,您需要将自己注册为您的自定义MIME类型的有效使用应用程序。如果浏览器检测到某个指定MIME类型的文件已安装应用程序,它只是将该文件写入客户端计算机上的临时目录,然后尝试启动具有相同注册MIME类型的应用程序,并将临时文件一个参数给应用程序。因此,您的应用程序现在只是读取浏览器传递给它的文件,然后尝试将其直接转储到打印机。

这是您需要做什么才能完成您所描述的内容的概述。某些具体步骤将取决于您使用的Web服务器的类型以及您的客户端计算机的操作系统。但这是高层次的概述,可以让你完成你正在尝试的任务。

+0

可以在打印机选项上启用的传递模式如何?根据Zebra手册,只要在其设置中启用了模式,就应该能够从任何Windows应用程序访问传递。 – user1447134

+0

即使安装的打印驱动程序确实允许这样做,但仍然受到浏览器允许您在上述第一条响应中执行的操作的限制。如果这确实起作用,那么您的最终用户仍然会得到他们需要回复的打印对话框并选择正确的打印机。这是一个不错的交易,但由于最终用户需要额外采取措施,可能仍然存在一些小错误。 – dmarietta

+0

我们必须这样做才能打印一次条形码。它是一场噩梦,恰恰相反,大多数打印机都有API,有些则具有网络API,但它们并不总是得到很好的支持。 – nycynik

3

我在这里开发类似的东西。 我需要从我的web应用程序打印LP2844。问题是我的web应用程序位于云中的远程服务器(Amazon EC2)中,打印机将在仓库中。

我的解决方案: Web应用程序为条形码标签生成EPL2 code,然后发布PubNub message。 我写了一个C#程序,运行在打印机连接的计算机上。该程序收到该消息,然后将代码发送到打印机。

+0

你愿意分享你的解决方案的来源吗?我正在研究开发同样的事情(并开发Mac客户端),如果可能,我想开源。 –

+0

对不起,我放弃了那个项目,并没有执行代码的和平。 –

2

您也可以将ZPL命令以文本文件的形式发送(您可以在一个文件中打包多个标签)并让用户打开并通过Windows记事本打印文件。唯一需要注意的是他们必须删除默认页眉和页脚(文件 - >页面设置)。

这是一些用户培训,但如果您不能控制客户端机器,可能会被接受。

7

如果你会考虑加载一个java小应用程序,qz-print(以前的jzebra)可以完成你所描述的内容,并且可以很好地与评论中提到的LP2844一起工作。

https://code.google.com/p/jzebra/

+2

只是为了让其他人知道..铬app不再支持Java applet .. – batwadi

+0

@batwadi谢谢。编辑。 – tresf

2

我跟着 “特雷斯菲诺基亚罗” 我的申请中提出的理念基础上:

  1. ASP.NET 4.0
  2. IIS
  3. 铬,IEXPLORER,火狐
  4. Zebra TLP 2844
  5. EPL protocolo

不幸的是jzebra需要一些改进才能正常工作,由于当前浏览器的安全问题。

安装jzebra

Downlod jzebdra和dist目录我复制到您的目录(如mydir):

  • 网络
    • MYDIR
      • JS
        • ..
        • 个deployJava.js
      • LIB
        • ...
      • QZ-print.jar
      • QZ-print_jnlp.jnlp

创建print.html

<html> 
<script type="text/javascript" src="js/deployJava.js"></script> 
<script type="text/javascript"> 
    /** 
    * Optionally used to deploy multiple versions of the applet for mixed 
    * environments. Oracle uses document.write(), which puts the applet at the 
    * top of the page, bumping all HTML content down. 
    */ 
    deployQZ(); 

    /** NEW FUNCTION **/ 
    function initPrinter() { 
     findPrinters(); 
     useDefaultPrinter(); 
    } 

    /** NEW FUNCTION **/  
    function myalert(txt) { 
     alert(txt); 
    } 


    /** 
    * Deploys different versions of the applet depending on Java version. 
    * Useful for removing warning dialogs for Java 6. This function is optional 
    * however, if used, should replace the <applet> method. Needed to address 
    * MANIFEST.MF TrustedLibrary=true discrepency between JRE6 and JRE7. 
    */ 
    function deployQZ() { 
     var attributes = {id: "qz", code:'qz.PrintApplet.class', 
      archive:'qz-print.jar', width:1, height:1}; 
     var parameters = {jnlp_href: 'qz-print_jnlp.jnlp', 
      cache_option:'plugin', disable_logging:'false', 
      initial_focus:'false'}; 
     if (deployJava.versionCheck("1.7+") == true) {} 
     else if (deployJava.versionCheck("1.6+") == true) { 
      delete parameters['jnlp_href']; 
     } 
     deployJava.runApplet(attributes, parameters, '1.5'); 
    } 

    /** 
    * Automatically gets called when applet has loaded. 
    */ 
    function qzReady() { 
     // Setup our global qz object 
     window["qz"] = document.getElementById('qz'); 
     var title = document.getElementById("title"); 
     if (qz) { 
      try { 
       title.innerHTML = title.innerHTML + " " + qz.getVersion(); 
       document.getElementById("content").style.background = "#F0F0F0"; 
      } catch(err) { // LiveConnect error, display a detailed meesage 
       document.getElementById("content").style.background = "#F5A9A9"; 
       alert("ERROR: \nThe applet did not load correctly. Communication to the " + 
        "applet has failed, likely caused by Java Security Settings. \n\n" + 
        "CAUSE: \nJava 7 update 25 and higher block LiveConnect calls " + 
        "once Oracle has marked that version as outdated, which " + 
        "is likely the cause. \n\nSOLUTION: \n 1. Update Java to the latest " + 
        "Java version \n   (or)\n 2. Lower the security " + 
        "settings from the Java Control Panel."); 
      } 
     } 
    } 

    /** 
    * Returns whether or not the applet is not ready to print. 
    * Displays an alert if not ready. 
    */ 
    function notReady() { 
     // If applet is not loaded, display an error 
     if (!isLoaded()) { 
      return true; 
     } 
     // If a printer hasn't been selected, display a message. 
     else if (!qz.getPrinter()) { 
      /** CALL TO NEW FUNCTION **/ 
      initPrinter(); 
      return false; 
     } 
     return false; 
    } 

    /** 
    * Returns is the applet is not loaded properly 
    */ 
    function isLoaded() { 
     if (!qz) { 
      alert('Error:\n\n\tPrint plugin is NOT loaded!'); 
      return false; 
     } else { 
      try { 
       if (!qz.isActive()) { 
        alert('Error:\n\n\tPrint plugin is loaded but NOT active!'); 
        return false; 
       } 
      } catch (err) { 
       alert('Error:\n\n\tPrint plugin is NOT loaded properly!'); 
       return false; 
      } 
     } 
     return true; 
    } 

    /** 
    * Automatically gets called when "qz.print()" is finished. 
    */ 
    function qzDonePrinting() { 
     // Alert error, if any 
     if (qz.getException()) { 
      alert('Error printing:\n\n\t' + qz.getException().getLocalizedMessage()); 
      qz.clearException(); 
      return; 
     } 

     // Alert success message 
     alert('Successfully sent print data to "' + qz.getPrinter() + '" queue.'); 
    } 

    /*************************************************************************** 
    * Prototype function for finding the "default printer" on the system 
    * Usage: 
    * qz.findPrinter(); 
    * window['qzDoneFinding'] = function() { alert(qz.getPrinter()); }; 
    ***************************************************************************/ 
    function useDefaultPrinter() { 
     if (isLoaded()) { 
      // Searches for default printer 
      qz.findPrinter(); 

      // Automatically gets called when "qz.findPrinter()" is finished. 
      window['qzDoneFinding'] = function() { 
       // Alert the printer name to user 
       var printer = qz.getPrinter(); 
       myalert(printer !== null ? 'Default printer found: "' + printer + '"': 
        'Default printer ' + 'not found'); 

       // Remove reference to this function 
       window['qzDoneFinding'] = null; 
      }; 
     } 
    } 

    /*************************************************************************** 
    * Prototype function for finding the closest match to a printer name. 
    * Usage: 
    * qz.findPrinter('zebra'); 
    * window['qzDoneFinding'] = function() { alert(qz.getPrinter()); }; 
    ***************************************************************************/ 
    function findPrinter(name) { 
     // Get printer name from input box 
     var p = document.getElementById('printer'); 
     if (name) { 
      p.value = name; 
     } 

     if (isLoaded()) { 
      // Searches for locally installed printer with specified name 
      qz.findPrinter(p.value); 

      // Automatically gets called when "qz.findPrinter()" is finished. 
      window['qzDoneFinding'] = function() { 
       var p = document.getElementById('printer'); 
       var printer = qz.getPrinter(); 

       // Alert the printer name to user 
       alert(printer !== null ? 'Printer found: "' + printer + 
        '" after searching for "' + p.value + '"' : 'Printer "' + 
        p.value + '" not found.'); 

       // Remove reference to this function 
       window['qzDoneFinding'] = null; 
      }; 
     } 
    } 

    /*************************************************************************** 
    * Prototype function for listing all printers attached to the system 
    * Usage: 
    * qz.findPrinter('\\{dummy_text\\}'); 
    * window['qzDoneFinding'] = function() { alert(qz.getPrinters()); }; 
    ***************************************************************************/ 
    function findPrinters() { 
     if (isLoaded()) { 
      // Searches for a locally installed printer with a bogus name 
      qz.findPrinter('\\{bogus_printer\\}'); 

      // Automatically gets called when "qz.findPrinter()" is finished. 
      window['qzDoneFinding'] = function() { 
       // Get the CSV listing of attached printers 
       var printers = qz.getPrinters().split(','); 
       for (i in printers) { 
        myalert(printers[i] ? printers[i] : 'Unknown');  
       } 

       // Remove reference to this function 
       window['qzDoneFinding'] = null; 
      }; 
     } 
    } 

    /*************************************************************************** 
    * Prototype function for printing raw EPL commands 
    * Usage: 
    * qz.append('\nN\nA50,50,0,5,1,1,N,"Hello World!"\n'); 
    * qz.print(); 
    ***************************************************************************/ 
    function print() { 
     if (notReady()) { return; } 

     // Send characters/raw commands to qz using "append" 
     // This example is for EPL. Please adapt to your printer language 
     // Hint: Carriage Return = \r, New Line = \n, Escape Double Quotes= \" 
     qz.append('\nN\n');    
     qz.append('q609\n'); 
     qz.append('Q203,26\n'); 
     qz.append('B5,26,0,1A,3,7,152,B,"1234"\n'); 
     qz.append('A310,26,0,3,1,1,N,"SKU 00000 MFG 0000"\n'); 
     qz.append('A310,56,0,3,1,1,N,"QZ PRINT APPLET"\n'); 
     qz.append('A310,86,0,3,1,1,N,"TEST PRINT SUCCESSFUL"\n'); 
     qz.append('A310,116,0,3,1,1,N,"FROM SAMPLE.HTML"\n'); 
     qz.append('A310,146,0,3,1,1,N,"QZINDUSTRIES.COM"'); 

     // Append the rest of our commands 
     qz.append('\nP1,1\n'); 

     // Tell the applet to print. 
     qz.print(); 
    } 

    /*************************************************************************** 
    * Prototype function for logging a PostScript printer's capabilites to the 
    * java console to expose potentially new applet features/enhancements. 
    * Warning, this has been known to trigger some PC firewalls 
    * when it scans ports for certain printer capabilities. 
    * Usage: (identical to appendImage(), but uses html2canvas for png rendering) 
    * qz.setLogPostScriptFeatures(true); 
    * qz.appendHTML("<h1>Hello world!</h1>"); 
    * qz.printPS(); 
    ***************************************************************************/ 
    function logFeatures() { 
     if (isLoaded()) { 
      var logging = qz.getLogPostScriptFeatures(); 
      qz.setLogPostScriptFeatures(!logging); 
      alert('Logging of PostScript printer capabilities to console set to "' + !logging + '"'); 
     } 
    } 

    /*************************************************************************** 
    **************************************************************************** 
    * *       HELPER FUNCTIONS        ** 
    **************************************************************************** 
    ***************************************************************************/ 

    function getPath() { 
     var path = window.location.href; 
     return path.substring(0, path.lastIndexOf("/")) + "/"; 
    } 

    /** 
    * Fixes some html formatting for printing. Only use on text, not on tags! 
    * Very important! 
    * 1. HTML ignores white spaces, this fixes that 
    * 2. The right quotation mark breaks PostScript print formatting 
    * 3. The hyphen/dash autoflows and breaks formatting 
    */ 
    function fixHTML(html) { 
     return html.replace(/ /g, "&nbsp;").replace(/’/g, "'").replace(/-/g,"&#8209;"); 
    } 

    /** 
    * Equivelant of VisualBasic CHR() function 
    */ 
    function chr(i) { 
     return String.fromCharCode(i); 
    } 

    /*************************************************************************** 
    * Prototype function for allowing the applet to run multiple instances. 
    * IE and Firefox may benefit from this setting if using heavy AJAX to 
    * rewrite the page. Use with care; 
    * Usage: 
    * qz.allowMultipleInstances(true); 
    ***************************************************************************/ 
    function allowMultiple() { 
     if (isLoaded()) { 
     var multiple = qz.getAllowMultipleInstances(); 
     qz.allowMultipleInstances(!multiple); 
     alert('Allowing of multiple applet instances set to "' + !multiple + '"'); 
     } 
    } 
</script> 

    <input type="button" onClick="print()" /> 
    </body> 
</html> 

提供的代码基于“jzebra_installation/dist/sample.html”。

+2

您提到的插件的最新版本规避了整个“Java插件”问题(NPAPI等),并作为桌面应用程序https://github.com/qzind/tray/运行。在新的强制签名过程中,它还使用.NET的“PageMethods”更好地实现ASYNC。 – tresf

4

我们做了我们的web应用程序:

1)下载免费的应用程序printfile http://www.lerup.com/printfile/

“PrintFile是一个免费的MS Windows实用程序,使您能够快速,轻松地打印文件。该程序可识别纯文本,PostScript,封装PostScript(EPS)和二进制格式。使用这个程序,可以为您节省大量的纸张,从而也节省了宝贵的自然资源。”

当你第一次运行PrintFile,进入高级选项并启用了‘直接发送到打印机’。

2)设置在Windows Zebra打印机的通用文本打印机。

2)生成的Web应用程序这仅仅是一个纯文本文件EPL一个file.prt文件。

3)上下载的文件双击就会瞬间打印条形码,像魅力一样工作,你甚至可以设置PrintFile,这样你甚至不会看到一个gui。

0

尝试创建一个WebSocket,它控制客户端的打印并将数据从页面发送到本地主机。

/// websocket 
using System; 
using System.Net; 
using System.Net.WebSockets; 
using System.Text; 
using System.Threading; 

namespace Server 
{ 
    class Program 
    { 
     public static WebsocketServer ws; 
     static void Main(string[] args) 
     { 
      ws = new Server.WebsocketServer(); 
      ws.LogMessage += Ws_LogMessage; 
      ws.Start("http://localhost:2645/service/"); 
      Console.WriteLine("Press any key to exit..."); 
      Console.ReadKey(); 
     } 

     private static void Ws_LogMessage(object sender, WebsocketServer.LogMessageEventArgs e) 
     { 
      Console.WriteLine(e.Message); 
     } 
    } 

    public class WebsocketServer 
    { 
     public event OnLogMessage LogMessage; 
     public delegate void OnLogMessage(Object sender, LogMessageEventArgs e); 
     public class LogMessageEventArgs : EventArgs 
     { 
      public string Message { get; set; } 
      public LogMessageEventArgs(string Message) 
      { 
       this.Message = Message; 
      } 
     } 

     public bool started = false; 
     public async void Start(string httpListenerPrefix) 
     { 
      HttpListener httpListener = new HttpListener(); 
      httpListener.Prefixes.Add(httpListenerPrefix); 
      httpListener.Start(); 
      LogMessage(this, new LogMessageEventArgs("Listening...")); 
      started = true; 

      while (started) 
      { 
       HttpListenerContext httpListenerContext = await httpListener.GetContextAsync(); 
       if (httpListenerContext.Request.IsWebSocketRequest) 
       { 
        ProcessRequest(httpListenerContext); 
       } 
       else 
       { 
        httpListenerContext.Response.StatusCode = 400; 
        httpListenerContext.Response.Close(); 
        LogMessage(this, new LogMessageEventArgs("Closed...")); 
       } 
      } 
     } 

     public void Stop() 
     { 
      started = false; 
     } 
     private async void ProcessRequest(HttpListenerContext httpListenerContext) 
     { 
      WebSocketContext webSocketContext = null; 

      try 
      { 
       webSocketContext = await httpListenerContext.AcceptWebSocketAsync(subProtocol: null); 
       LogMessage(this, new LogMessageEventArgs("Connected")); 
      } 
      catch (Exception e) 
      { 
       httpListenerContext.Response.StatusCode = 500; 
       httpListenerContext.Response.Close(); 
       LogMessage(this, new LogMessageEventArgs(String.Format("Exception: {0}", e))); 
       return; 
      } 

      WebSocket webSocket = webSocketContext.WebSocket; 
      try 
      { 


       while (webSocket.State == WebSocketState.Open) 
       { 

        ArraySegment<Byte> buffer = new ArraySegment<byte>(new Byte[8192]); 

        WebSocketReceiveResult result = null; 

        using (var ms = new System.IO.MemoryStream()) 
        { 
         do 
         { 
          result = await webSocket.ReceiveAsync(buffer, CancellationToken.None); 
          ms.Write(buffer.Array, buffer.Offset, result.Count); 
         } 
         while (!result.EndOfMessage); 

         ms.Seek(0, System.IO.SeekOrigin.Begin); 

         if (result.MessageType == WebSocketMessageType.Text) 
         { 
          using (var reader = new System.IO.StreamReader(ms, Encoding.UTF8)) 
          { 
           var r = System.Text.Encoding.UTF8.GetString(ms.ToArray()); 
           var t = Newtonsoft.Json.JsonConvert.DeserializeObject<Datos>(r); 
           bool valid = true; 
           byte[] toBytes = Encoding.UTF8.GetBytes(""); ; 

           if (t != null) 
           { 
            if (t.printer.Trim() == string.Empty) 
            { 
             var printers = ""; 
             foreach (var imp in System.Drawing.Printing.PrinterSettings.InstalledPrinters) 
             { 
              printers += imp + "\n"; 
             } 

             toBytes = Encoding.UTF8.GetBytes("No se Indicó la Impresora\nLas Impresoras disponibles son: " + printers); 
             valid = false; 
            } 
            if (t.name.Trim() == string.Empty) 
            { 
             toBytes = Encoding.UTF8.GetBytes("No se Indicó el nombre del Documento"); 
             valid = false; 
            } 
            if (t.code == null) 
            { 
             toBytes = Encoding.UTF8.GetBytes("No hay datos para enviar a la Impresora"); 
             valid = false; 
            } 


            if (valid) 
            { 
             print.RawPrinter.SendStringToPrinter(t.printer, t.code, t.name); 
             toBytes = Encoding.UTF8.GetBytes("Correcto..."); 
            } 

            await webSocket.SendAsync(new ArraySegment<byte>(toBytes, 0, int.Parse(toBytes.Length.ToString())), WebSocketMessageType.Binary, result.EndOfMessage, CancellationToken.None); 
           } 
           else 
           { 
            toBytes = Encoding.UTF8.GetBytes("Error..."); 
            await webSocket.SendAsync(new ArraySegment<byte>(toBytes, 0, int.Parse(toBytes.Length.ToString())), WebSocketMessageType.Binary, result.EndOfMessage, CancellationToken.None); 
           } 
          } 
         } 
        } 
       } 
      } 
      catch (Exception e) 
      { 
       LogMessage(this, new LogMessageEventArgs(String.Format("Exception: {0} \nLinea:{1}", e, e.StackTrace))); 
      } 
      finally 
      { 
       if (webSocket != null) 
        webSocket.Dispose(); 
      } 
     } 
    } 

    public class Datos 
    { 
     public string name { get; set; } 
     public string code { get; set; } 
     public string printer { get; set; } = ""; 
    } 
} 

原始打印:

using Microsoft.VisualBasic; 
using System; 
using System.Collections; 
using System.Collections.Generic; 
using System.Data; 
using System.Diagnostics; 
using System.Runtime.InteropServices; 
using System.IO; 

namespace print 
{ 
    public class RawPrinter 
    { 
     // Structure and API declarions: 
     [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] 
     public class DOCINFOA 
     { 
      [MarshalAs(UnmanagedType.LPStr)] 
      public string pDocName; 
      [MarshalAs(UnmanagedType.LPStr)] 
      public string pOutputFile; 
      [MarshalAs(UnmanagedType.LPStr)] 
      public string pDataType; 
     } 
     [DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
     public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] 
string szPrinter, ref IntPtr hPriknter, IntPtr pd); 

     [DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
     public static extern bool ClosePrinter(IntPtr hPrinter); 

     [DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
     public static extern bool StartDocPrinter(IntPtr hPrinter, Int32 level, [In(), MarshalAs(UnmanagedType.LPStruct)] 
DOCINFOA di); 

     [DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
     public static extern bool EndDocPrinter(IntPtr hPrinter); 

     [DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
     public static extern bool StartPagePrinter(IntPtr hPrinter); 

     [DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
     public static extern bool EndPagePrinter(IntPtr hPrinter); 

     [DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
     public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount, ref Int32 dwWritten); 

     // SendBytesToPrinter() 
     // When the function is given a printer name and an unmanaged array 
     // of bytes, the function sends those bytes to the print queue. 
     // Returns true on success, false on failure. 
     public static bool SendBytesToPrinter(string szPrinterName, IntPtr pBytes, Int32 dwCount, string DocName = "") 
     { 
      Int32 dwError = 0; 
      Int32 dwWritten = 0; 
      IntPtr hPrinter = new IntPtr(0); 
      DOCINFOA di = new DOCINFOA(); 
      bool bSuccess = false; 
      // Assume failure unless you specifically succeed. 
      di.pDocName = string.IsNullOrEmpty(DocName) ? "My C#.NET RAW Document" : DocName; 
      di.pDataType = "RAW"; 

      // Open the printer. 
      if (OpenPrinter(szPrinterName.Normalize(), ref hPrinter, IntPtr.Zero)) 
      { 
       // Start a document. 
       if (StartDocPrinter(hPrinter, 1, di)) 
       { 
        // Start a page. 
        if (StartPagePrinter(hPrinter)) 
        { 
         // Write your bytes. 
         bSuccess = WritePrinter(hPrinter, pBytes, dwCount, ref dwWritten); 
         EndPagePrinter(hPrinter); 
        } 
        EndDocPrinter(hPrinter); 
       } 
       ClosePrinter(hPrinter); 
      } 
      // If you did not succeed, GetLastError may give more information 
      // about why not. 
      if (bSuccess == false) 
      { 
       dwError = Marshal.GetLastWin32Error(); 
      } 
      return bSuccess; 
     } 

     public static bool SendFileToPrinter(string szPrinterName, string szFileName) 
     { 
      // Open the file. 
      FileStream fs = new FileStream(szFileName, FileMode.Open); 
      // Create a BinaryReader on the file. 
      BinaryReader br = new BinaryReader(fs); 
      // Dim an array of bytes big enough to hold the file's contents. 
      Byte[] bytes = new Byte[fs.Length]; 
      bool bSuccess = false; 
      // Your unmanaged pointer. 
      IntPtr pUnmanagedBytes = new IntPtr(0); 
      int nLength = 0; 

      nLength = Convert.ToInt32(fs.Length); 
      // Read the contents of the file into the array. 
      bytes = br.ReadBytes(nLength); 
      // Allocate some unmanaged memory for those bytes. 
      pUnmanagedBytes = Marshal.AllocCoTaskMem(nLength); 
      // Copy the managed byte array into the unmanaged array. 
      Marshal.Copy(bytes, 0, pUnmanagedBytes, nLength); 
      // Send the unmanaged bytes to the printer. 
      bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, nLength); 
      // Free the unmanaged memory that you allocated earlier. 
      Marshal.FreeCoTaskMem(pUnmanagedBytes); 
      return bSuccess; 
     } 
     public static bool SendStringToPrinter(string szPrinterName, string szString, string DocName = "") 
     { 
      IntPtr pBytes = default(IntPtr); 
      Int32 dwCount = default(Int32); 
      // How many characters are in the string? 
      dwCount = szString.Length; 
      // Assume that the printer is expecting ANSI text, and then convert 
      // the string to ANSI text. 
      pBytes = Marshal.StringToCoTaskMemAnsi(szString); 
      // Send the converted ANSI string to the printer. 
      SendBytesToPrinter(szPrinterName, pBytes, dwCount, DocName); 
      Marshal.FreeCoTaskMem(pBytes); 
      return true; 
     } 
    } 
} 

html页面:

<!DOCTYPE html> 
<html> 

<head> 
</head> 

<body ng-app="myapp"> 

    <div ng-controller="try as ctl"> 
     <input ng-model="ctl.ticket.nombre"> 

     <textarea ng-model="ctl.ticket.code"></textarea> 

     <button ng-click="ctl.send()">Enviar</button> 
    </div> 


    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script> 
    <script> 
     var ws = new WebSocket("ws://localhost:2645/service"); 
     ws.binaryType = "arraybuffer"; 
     ws.onopen = function() { 
      console.log('connection is opened!!!'); 
     }; 

     ws.onmessage = function (evt) { 
      console.log(arrayBufferToString(evt.data)) 

     }; 

     ws.onclose = function() { 
      console.log("Connection is Closed...") 
     }; 

     function arrayBufferToString(buffer) { 
      var arr = new Uint8Array(buffer); 
      var str = String.fromCharCode.apply(String, arr); 

      return decodeURIComponent(escape(str)); 
     } 
     var app = angular.module('myapp', []); 
     app.controller('try', function() { 
      this.ticket= {nombre:'', estado:''} 

      this.send =() => { 
       var toSend= JSON.stringify(this.ticket); 
       ws.send(toSend); 
      } 
     }); 
    </script> 
</body> 

</html> 

然后从HTML发送ZPL代码(写在textarea的代码);

^XA 
^FO200,50^BY2^B3N,N,80,Y,N^FD^FS 
^PQ1^XZ 
0

我使用QZ Tray将标签从网页打印到Zebra热敏打印机。

在QZ托盘的demo/js文件夹下有所需用QZ托盘应用程序通信3个JavaScript文件 - dependencies/rsvp-3.1.0.min.jsdependencies/sha-256.min.jsqz-tray.js

在项目中包含这些JavaScript文件如下:

<script type="text/javascript" src="/lib/qz-tray/rsvp-3.1.0.min.js"></script> 
<script type="text/javascript" src="/lib/qz-tray/sha-256.min.js"></script> 
<script type="text/javascript" src="/lib/qz-tray/qz-tray.js"></script> 

最简单的方法来打印标签斑马热敏打印机如下图所示。

<script type="text/javascript"> 
qz.websocket.connect().then(function() { 
    // Pass the printer name into the next Promise 
    return qz.printers.find("zebra"); 
}).then(function(printer) { 
    // Create a default config for the found printer 
    var config = qz.configs.create(printer); 

    // Raw ZPL 
    var data = ['^XA^FO50,50^ADN,36,20^FDRAW ZPL EXAMPLE^FS^XZ']; 

    return qz.print(config, data); 
}).catch(function(e) { console.error(e); }); 
</script> 

请参阅How to print labels from a web page to Zebra thermal printer了解更多信息。