简体   繁体   English

从网页打印条形码到Zebra打印机

[英]Print barcodes from web page to Zebra printer

We're trying to print barcodes from a web page to our Zebra printer. 我们正在尝试将条形码从网页打印到我们的Zebra打印机。

I'm wondering if there's a way to print them using the printer's own font perhaps using web fonts or if I knew the font name used? 我想知道是否有办法使用打印机自己的字体打印它们,也许使用网络字体或者我知道使用的字体名称?

I have been trying to use php barcode generators, that basically generates images containing the barcode. 我一直在尝试使用php条形码生成器,它基本上生成包含条形码的图像。 I have in fact been trying this approach for a few days already, without success. 事实上,我已经尝试了几天,但没有成功。

The problem is when I print them it's not readable by the scanners. 问题是当我打印它们时扫描仪无法读取。 I have tried to change the image resolution to match that of the printer (203dpi), also tried playing with the image size and formats, but the barcodes after printed still can't be scanned. 我试图改变图像分辨率以匹配打印机的图像分辨率(203dpi),也尝试使用图像大小和格式进行播放,但打印后的条形码仍然无法扫描。

So does anybody have experience with this? 那么有人有这方面的经验吗?

Printer: Zebra TLP 2844 打印机:Zebra TLP 2844

Barcodes required per page: 每页需要条形码:

  • 01 Code39 horizontal (scanable only if printed at very specific size and browser) 01 Code39水平(仅在非常特定的尺寸和浏览器下打印时可扫描)
  • 01 Code128 vertical (still can't get it to work, print is always very blurry and won't get scanned) 01 Code128垂直(仍然无法使其工作,打印总是非常模糊,不会被扫描)

=========== ===========

I've made a little bit of progress, I found out this printer supports EPL2 language, so I'm trying to use it to print out the barcodes. 我已经取得了一些进展,我发现这台打印机支持EPL2语言,所以我试图用它来打印出条形码。

First I needed to enable pass through mode, I did that on Printer Options > Advanced Setup > Miscellaneous. 首先我需要启用传递模式,我在打印机选项>高级设置>杂项上执行了此操作。

Now I'm able to print barcodes impeccably using the printer's built-in font :D using this command: 现在我可以使用打印机的内置字体无可挑剔地打印条形码:D使用此命令:

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

But I can only print it from Notepad, I'm still unable to print this from a browser... It's probably a problem with LF being replaced with CR+LF... 但是我只能用记事本打印它,我仍然无法从浏览器中打印出来......这可能是LF被CR + LF取代的问题......

How to overcome this problem?? 如何克服这个问题?

=========== ===========

The label I'm trying to print actually has a bit of text before the barcode, with some html tables formatting it nicely. 我正在尝试打印的标签实际上在条形码之前有一些文字,一些html表格很好地格式化。 So I need to print this first, and in the middle I need to stick in a nice label and then add some more text. 所以我需要首先打印它,在中间我需要粘贴一个漂亮的标签,然后再添加一些文本。

So I can't use pure EPL2 to print the whole thing, I'm wondering if I can use some of both html + EPL2 + html to achieve my goal or is that not allowed?? 所以我不能用纯EPL2来打印整个东西,我想知道我是否可以使用html + EPL2 + html来实现我的目标或者是不允许的? =/ = /

You are running into a few obstacles: 你遇到了一些障碍:

1) When you print through the OS installed printer driver, the printer driver is trying to take the data that is sent to it and (re)rasterize or scale it for the output device (the Zebra printer). 1)当您通过操作系统安装的打印机驱动程序进行打印时,打印机驱动程序正在尝试获取发送给它的数据并(重新)光栅化或缩放它以用于输出设备(Zebra打印机)。 Since the printer is a relatively low resolution at 203dpi, then it does not take too much for the scaling the print driver is having to do for it to loose some integrity in the quality of the barcode. 由于打印机在203dpi时的分辨率相对较低,因此打印驱动程序不必花费太大的时间来缩放打印机,因为它会使条形码的质量失去一定的完整性。 This is why barcodes generated using the direct ZPL commands are much more reliable. 这就是为什么使用直接ZPL命令生成的条形码是可靠。

2) Due to the security that web browsers purposefully provide by not allowing access to the client computer, you cannot directly communicate with the client connected printer. 2)由于Web浏览器不允许访问客户端计算机而有目的地提供安全性,因此无法直接与客户端连接的打印机进行通信。 This sandboxing is what helps to protect users from malware so that nefarious websites cannot do things like write files to the client machine or send output directly to devices such as printers. 此沙箱有助于保护用户免受恶意软件的侵害,因此恶意网站无法执行将文件写入客户端计算机或将输出直接发送到打印机等设备的操作。 So you are not able to directly send the ZPL commands through the browser to the client connected printer. 因此,您无法通过浏览器直接将ZPL命令发送到客户端连接的打印机。

However, there is a way to do what you describe. 但是,有一种方法可以按照您的描述进行操作。 The steps necessary are typically only going to be useful if you have some degree of control over the client computer accessing the site that is trying to print to the Zebra printers. 如果您对访问尝试打印到Zebra打印机的站点的客户端计算机有一定程度的控制,则所需的步骤通常才有用。 For example this is only going to be used by machines on your company network, or by clients who are willing to install a small application that you need to write. 例如,这只会由公司网络上的计算机使用,或者由愿意安装您需要编写的小型应用程序的客户使用。 To do this, you will need to look at the following steps: 为此,您需要查看以下步骤:

A) You need to make up your own custom MIME type. A)您需要编写自己的自定义MIME类型。 This is basically just any name you want to use that is not going to collide with any registered MIME types . 这基本上只是您要使用的任何名称,不会与任何已注册的MIME类型发生冲突。

B) Next you will define a filename extension that will map to your custom MIME type. B)接下来,您将定义一个文件扩展名,该扩展名将映射到您的自定义MIME类型。 To do this, you typically will need to configure your web server (steps for this depend on what web server you are using) to allow the new MIME type you want to define and what file extension is used for these types of files. 为此,您通常需要配置Web服务器(此步骤取决于您使用的Web服务器)以允许您要定义的新MIME类型以及用于这些类型文件的文件扩展名。

C) Then on your web application, when you want to output the ZPL data, you write it to a file using a filename extension that is mapped to your new MIME type. C)然后在您的Web应用程序上,当您想要输出ZPL数据时,使用映射到新MIME类型的文件扩展名将其写入文件。 Then once the file is generated, you can either provide an HTML link to it, or redirect the client browser to the file. 然后,一旦生成文件,您可以提供HTML链接,或将客户端浏览器重定向到该文件。 You can test if your file is working correctly at this point by manually copying the file you created directly to the raw printer port. 此时,您可以通过手动将直接创建的文件复制到原始打印机端口来测试文件是否正常工作。

D) Next you need to write a small application which can be installed on the client. D)接下来,您需要编写一个可以安装在客户端上的小应用程序。 When the application is installed, you need to have it register itself as a valid consuming application for your custom MIME type. 安装应用程序后,您需要将其自身注册为自定义MIME类型的有效消费应用程序。 If a browser detects that there is an installed application for a file of the specified MIME type, it simply writes the file to a temporary directory on the client machine and then attempts to launch the application of the same registered MIME type with the temporary file as a parameter to the application. 如果浏览器检测到已安装的应用程序用于指定MIME类型的文件,它只是将该文件写入客户端计算机上的临时目录,然后尝试使用临时文件启动相同的已注册MIME类型的应用程序。应用程序的参数。 Thus your application now just reads the file that the browser passed to it and then it attempts to dump it directly to the printer. 因此,您的应用程序现在只读取浏览器传递给它的文件,然后尝试将其直接转储到打印机。

This is an overview of what you need to do in order to accomplish what you are describing. 这是为了完成您所描述的内容而概述您需要执行的操作。 Some of the specific steps will depend on what type of web server you are using and what OS your clients machines are. 某些具体步骤取决于您使用的Web服务器类型以及客户端所使用的操作系统。 But this is the high level overview that will let you accomplish what you are attempting. 但这是高级概述,可以让您完成您的尝试。

If you'd consider loading a java applet, qz-print (previously jzebra) can do exactly what you are describing and works nicely with the LP2844 mentioned in the comments. 如果你考虑加载一个java applet,qz-print(以前的jzebra)可以完全按照你所描述的那样做,并且可以很好地与评论中提到的LP2844一起使用。

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

What we did for our web app : 我们为我们的网络应用做了什么:

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

"PrintFile is a freeware MS Windows utility program that will enable you to print files fast and easily. The program recognizes plain text, PostScript, Encapsulated PostScript (EPS) and binary formats. Using this program can save you a lot of paper and thereby also saving valuable natural resources." “PrintFile是一个免费的MS Windows实用程序,可以让您快速轻松地打印文件。该程序可识别纯文本,PostScript,封装PostScript(EPS)和二进制格式。使用此程序可以为您节省大量纸张,从而也节约宝贵的自然资源。“

When you first run PrintFile, go into the advanced options and enable "send to printer directly". 首次运行PrintFile时,请进入高级选项并启用“直接发送到打印机”。

2) Setup the ZEBRA printer in windows as a Generic Text Printer. 2)在Windows中将ZEBRA打印机设置为通用文本打印机。

2) Generate a file.prt file in the web app which is just a plain text EPL file. 2)在Web应用程序中生成一个file.prt文件,该文件只是一个纯文本EPL文件。

3) Double clicking on the downloaded file will instantly print the barcode. 3)双击下载的文件将立即打印条形码。 Works like a charm. 奇迹般有效。 You can even setup PrintFile so that you don't even see a gui. 您甚至可以设置PrintFile,这样您甚至不会看到gui。

I'm developing something similar here. 我在这里开发类似的东西。 I need to print in a LP2844 from my webapp. 我需要从我的webapp打印到LP2844。 The problem is that my webapp is in a remote server in the cloud (Amazon EC2) and the printer is going to be in a warehouse desk. 问题是我的webapp位于云端的远程服务器(Amazon EC2)中,打印机将位于仓库中。

My solution: The webapp generates the EPL2 code for the label with the barcodes, then publish a PubNub message . 我的解决方案:webapp使用条形码为标签生成EPL2代码 ,然后发布PubNub消息 I wrote a little C# program that runs in the computer where the printer is connected. 我写了一个小的C#程序,它运行在连接打印机的计算机上。 The program receives the message and then send the code to the printer. 程序接收消息,然后将代码发送到打印机。

You can also send the ZPL commands in a text file (you can pack multiple labels in a single file) and have the user open and print the file via windows notepad. 您还可以在文本文件中发送ZPL命令(您可以在单个文件中打包多个标签)并让用户打开并通过Windows记事本打印文件。 The only caveat is that they have to remove the default header and footer (File --> Page Setup). 唯一需要注意的是,他们必须删除默认的页眉和页脚(文件 - >页面设置)。

Its a bit of user training, but may be acceptable if you don't have control over the client machines. 它是一些用户培训,但如果您无法控制客户端计算机,则可以接受。

I followed the idea proposed by "Tres Finocchiaro" on my application based on: 我在我的申请基础上遵循了“Tres Finocchiaro”提出的想法:

  1. ASP.NET 4.0 ASP.NET 4.0
  2. IIS IIS
  3. Chrome, IExplorer, Firefox Chrome,IExplorer,Firefox
  4. Zebra TLP 2844 Zebra TLP 2844
  5. EPL protocolo EPL协议

Unfortunatly the jzebra needs some improvements to work corectly due to the issues of security of current browser. 不幸的是,由于当前浏览器的安全性问题, jzebra需要一些改进以进行核心工作。

Installing jzebra 安装jzebra

Downlod jzebdra and from dist directory I copy into your directory (eg. mydir ): Downlod jzebdra和dist目录我复制到你的目录(例如mydir ):

  • web 卷筒纸
    • mydir MYDIR
      • js JS
        • .. ..
        • deployJava.js deployJava.js
      • lib LIB
        • .. ..
      • qz-print.jar QZ-print.jar
      • qz-print_jnlp.jnlp QZ-print_jnlp.jnlp

Create your print.html 创建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>

the code provided is based on "jzebra_installation/dist/sample.html". 提供的代码基于“jzebra_installation / dist / sample.html”。

I am using QZ Tray to print labels from a web page to Zebra thermal printer. 我正在使用QZ Tray将网页上的标签打印到Zebra热敏打印机。

In the demo/js folder of QZ Tray there are three JavaScript files that are required to communicate with QZ Tray application - dependencies/rsvp-3.1.0.min.js , dependencies/sha-256.min.js and qz-tray.js . 在QZ Tray的demo/js文件夹中,有三个JavaScript文件需要与QZ Tray应用程序通信 - dependencies/rsvp-3.1.0.min.jsdependencies/sha-256.min.jsdependencies/sha-256.min.js qz-tray.js

Include these JavaScript files in your project as follows: 在项目中包含这些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>

The most simple way to print a label to Zebra thermal printer is shown below. 将标签打印到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>

See How to print labels from a web page to Zebra thermal printer for more information. 有关详细信息,请参阅如何将网页中的标签打印到Zebra热敏打印机

try creating a websocket that controls the print on the client side and send data with ajax from the page to localhost. 尝试创建一个控制客户端打印的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; } = "";
    }
}

raw Print: 原始打印:

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 page: 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>

then send a ZPL code from html(write this on textarea code); 然后从html发送一个ZPL代码(在textarea代码上写这个);

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM