33

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

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

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

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

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

打印机:斑马 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 来实现我的目标,还是不允许这样做?=/

4

8 回答 8

26

您遇到了一些障碍:

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

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

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

A) 您需要制作自己的自定义 MIME 类型。这基本上只是您想使用的任何名称,不会与任何已注册的 MIME 类型发生冲突。

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

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

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

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

于 2012-06-11T22:44:08.823 回答
8

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

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

于 2014-01-26T20:27:41.653 回答
5

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

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。

于 2015-06-12T16:37:55.163 回答
5

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

在 QZ Tray 的文件夹中有与demo/jsQZ Tray 应用程序通信所需的三个 JavaScript 文件 -dependencies/rsvp-3.1.0.min.js和.dependencies/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>

有关详细信息,请参阅如何将标签从网页打印到 Zebra 热敏打印机

于 2018-02-28T06:23:57.767 回答
4

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

它有点用户培训,但如果您无法控制客户端计算机,则可能是可以接受的。

于 2012-12-17T18:17:57.600 回答
3

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

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

于 2012-10-14T20:04:50.520 回答
2

我遵循“Tres Finocchiaro”在我的申请中提出的想法,基于:

  1. ASP.NET 4.0
  2. IIS
  3. 铬,IExplorer,火狐
  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”。

于 2014-11-20T20:03:05.960 回答
0

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

/// 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
于 2017-10-13T17:49:30.877 回答