【问题标题】:Print barcodes from web page to Zebra printer从网页打印条形码到 Zebra 打印机
【发布时间】:2012-06-13 14:52:43
【问题描述】:

我们正在尝试将条形码从网页打印到我们的 Zebra 打印机。

我想知道是否有办法使用打印机自己的字体(可能使用网络字体)打印它们,或者我是否知道使用的字体名称?

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

问题是当我打印它们时,扫描仪无法读取它们。我尝试将图像分辨率更改为与打印机的分辨率(203dpi)匹配,也尝试过调整图像大小和格式,但打印后的条形码仍然无法扫描。

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

打印机:Zebra TLP 2844

每页需要条形码:

  • 01 Code39 水平(仅在以非常特定的尺寸和浏览器打印时才可扫描)
  • 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 来实现我的目标,还是不允许这样做? =/

【问题讨论】:

  • 看起来您在下面有一些有希望的答案。只是想补充一点,您不能将 HTML 格式与 ZPL 结合起来。您将需要使用 ZPL 进行整个标签格式化。框、文本和东西有很多选择,所以它是可行的。

标签: printing web barcode


【解决方案1】:

您遇到了一些障碍:

1) 当您通过操作系统安装的打印机驱动程序进行打印时,打印机驱动程序会尝试获取发送给它的数据并(重新)光栅化或缩放输出设备(Zebra 打印机)。由于打印机在 203dpi 时的分辨率相对较低,因此打印驱动程序无需进行太多缩放即可降低条码质量的完整性。这就是使用直接 ZPL 命令生成的条形码更加更可靠的原因。

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

但是,有一种方法可以按照您的描述进行。如果您对访问试图打印到 Zebra 打印机的站点的客户端计算机有一定程度的控制,则必要的步骤通常才会有用。例如,这只会被您公司网络上的机器或愿意安装您需要编写的小型应用程序的客户使用。为此,您需要查看以下步骤:

A) 您需要创建自己的自定义 MIME 类型。这基本上只是您想要使用的任何名称,不会与任何registered MIME types 冲突。

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

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

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

这是对完成您所描述的内容所需执行的操作的概述。一些具体步骤将取决于您使用的 Web 服务器类型以及您的客户端计算机的操作系统。但这是一个高级概述,可让您完成您正在尝试的事情。

【讨论】:

  • 可以在打印机选项上启用的直通模式怎么样?根据 Zebra 手册,只要在设置上启用了该模式,就应该能够从任何 Windows 应用程序访问传递。
  • 即使安装的打印驱动程序确实允许这样做,您仍然会受到浏览器在上面我的回复的#1 中允许您执行的操作的限制。如果这确实有效,那么您的最终用户仍将获得一个他们需要响应并选择正确打印机的打印对话框。不错的权衡,但由于最终用户需要执行额外的步骤,可能仍然容易出错。
  • 我们必须这样做才能打印一次条形码。它是一场噩梦,它是一个应用程序,大多数打印机都有用于此的 API,有些有 Web api,但它们并不总是得到很好的支持。
  • 您有任何使用 linux 实现步骤 D 的参考文档吗?
【解决方案2】:

如果您考虑加载 java 小程序,qz-print(以前的 jzebra)可以完全按照您的描述进行,并且可以与 cmets 中提到的 LP2844 很好地配合使用。

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

【讨论】:

    【解决方案3】:

    我们为我们的网络应用做了什么:

    1) 下载免费打印文件应用程序http://www.lerup.com/printfile/

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

    当您第一次运行 PrintFile 时,进入高级选项并启用“直接发送到打印机”。

    2) 在 windows 中将 ZEBRA 打印机设置为通用文本打印机。

    2) 在 web 应用程序中生成一个 file.prt 文件,它只是一个纯文本 EPL 文件。

    3) 双击下载的文件将立即打印条形码。奇迹般有效。您甚至可以设置 PrintFile,这样您甚至都看不到 gui。

    【讨论】:

      【解决方案4】:

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

      在 QZ Tray 的 demo/js 文件夹中,有三个 JavaScript 文件需要与 QZ Tray 应用程序通信 - 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>
      

      将标签打印到 Zebra 热敏打印机的最简单方法如下所示。

      <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

      【讨论】:

        【解决方案5】:

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

        这是一些用户培训,但如果您无法控制客户端计算机,则可以接受。

        【讨论】:

          【解决方案6】:

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

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

          【讨论】:

          • 您愿意分享您的解决方案的来源吗?我正在考虑开发相同的东西(以及开发 Mac 客户端),如果可能的话,我想开源它。
          • 抱歉,我放弃了那个项目,也没有提交代码。
          【解决方案7】:

          我在我的应用程序中遵循了“Tres Finocchiaro”提出的想法,基于:

          1. ASP.NET 4.0
          2. IIS
          3. Chrome、IExplorer、Firefox
          4. 斑马 TLP 2844
          5. EPL 协议

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

          安装 jzebra

          下载 jzebdra 并从 dist 目录复制到您的目录(例如mydir):

          • 网络
            • 我的目录
              • js
                • ..
                • 部署Java.js
                • ..
              • 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”。

          【讨论】:

          • 您提到的最新版本的插件绕过了整个“Java插件”问题(NPAPI等)并作为桌面应用程序运行github.com/qzind/tray。它还使用 .NET PageMethods 在新的强制签名过程中实现更好的 ASYNC。
          【解决方案8】:

          尝试创建一个 websocket 来控制客户端的打印,并使用 ajax 从页面发送数据到本地主机。

          /// 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^FD0123456789^FS
          ^PQ1^XZ
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-09-14
            • 2020-10-08
            • 1970-01-01
            相关资源
            最近更新 更多