JavaScript:将原始文本发送到打印机 - 没有服务器请求/方法调用,能够脱机工作,纯客户端

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36570689/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 19:14:14  来源:igfitidea点击:

JavaScript: Send raw text to printer - no server requests/method calls, able to work offline, purely clientside

javascripthtmlprintingzpl

提问by user2177283

My thorough research on the web provided me with a couple of ideas, but none of them seem to work correctly in my particular use case. Here is what I have:

我对网络的深入研究为我提供了一些想法,但在我的特定用例中似乎没有一个可以正常工作。这是我所拥有的:

1) Zebra printer, which uses ZPL as its printing language;

1) Zebra 打印机,使用 ZPL 作为打印语言;

2) A string in javascript which consists of 3 ZPL forms for printing 3 labels.

2) javascript 中的一个字符串,由 3 个 ZPL 表单组成,用于打印 3 个标签。

Our system engineer has verified already, that the ZPL syntax is all correct. What I am trying to achieve is to send the string as plain text for the printer to accept it as ZPL instructions to print labels. The best I have come up with so far looks like this:

我们的系统工程师已经验证,ZPL 语法完全正确。我想要实现的是将字符串作为纯文本发送给打印机,以将其作为 ZPL 指令来打印标签。到目前为止我想出的最好的看起来是这样的:

var mywindow = window.open('', 'Printing', 'width=800,height=600');
//mywindow.write("testDirectWrite"); // not working
mywindow.document.open('text/plain');
////mywindow.document.write('<html><head><title>Printing</title><meta charset="ISO-8859-1">');
///*optional stylesheet*/ //mywindow.document.write('<link rel="stylesheet" href="main.css" type="text/css" />');
////mywindow.document.write('</head><body>');
var theDiv = $(".test-printirane-po-usb");
var printContents = theDiv[0].innerText;
mywindow.document.write(printContents);
////mywindow.document.write('</body></html>');

//mywindow.document.close(); // necessary for IE >= 10
//mywindow.focus(); // necessary for IE >= 10

//mywindow.print();
//mywindow.close();

For now (testing purposes), theDiv is the container where i place the ZPL string. Basically, I understood, that the best solution is to open a new popup window, fill it with the ZPL string and call thePopupWindow.print(); The user then selects the zebra printer and hits 'Print'. The problem:it seems like the printer interprets what's being printed as an html page (because of the

现在(测试目的),theDiv 是我放置 ZPL 字符串的容器。基本上,我明白,最好的解决方案是打开一个新的弹出窗口,用 ZPL 字符串填充它并调用 thePopupWindow.print(); 然后用户选择斑马打印机并点击“打印”。 问题:似乎打印机将打印的内容解释为 html 页面(因为

<html><head></head><body>theZPLString comes here</body></html>

tags, that i see, when I inspect the popup in Chrome, for example) and prints the ZPL code as plain text, rather than interpret it and print a label. I suppose I need something like thePopupWindow.write() to avoid writing to the document property of the window, which obviously wraps the string in html code. In order to test it, I use the Generic/Text Only driver and save what's "printed" into a .txt file.

例如,当我在 Chrome 中检查弹出窗口时看到的标签)并将 ZPL 代码打印为纯文本,而不是解释它并打印标签。我想我需要像 thePopupWindow.write() 这样的东西来避免写入窗口的文档属性,这显然将字符串包装在 html 代码中。为了测试它,我使用 Generic/Text Only 驱动程序并将“打印”的内容保存到 .txt 文件中。

In Chrome I get an empty file.

在 Chrome 中,我得到一个空文件。

In Mozilla, when I remove this line: mywindow.document.open('text/plain'); I get the ZPL as characters, one per line. When I add it, I get only a date and time, again one char per line.

在 Mozilla 中,当我删除这一行时: mywindow.document.open('text/plain'); 我将 ZPL 作为字符,每行一个。当我添加它时,我只得到一个日期和时间,每行一个字符。

In IE - I get this (with or without mywindow.document.open('text/plain');):

在 IE 中 - 我得到这个(有或没有 mywindow.document.open('text/plain');):

Page 1 o



    ^XA^PW400^LL37^





          12.4.2016

I found various solutions, but they involve using php, c#, even java and I don't want it to be server-side, as mentioned in the title. Any help will be appreciated. @forgivenson, thanks for the point. After reading yours, I saw the little 'x', that I can click to delete my comment, so I added the comment within the question. I missed something very important: the printer is connected via USB port!

我找到了各种解决方案,但它们涉及使用 php、c#,甚至 java,而且我不希望它成为服务器端,如标题中所述。任何帮助将不胜感激。@forgivenson,谢谢你的观点。读完你的后,我看到了小“x”,我可以点击它删除我的评论,所以我在问题中添加了评论。我错过了一些非常重要的事情:打印机是通过 USB 端口连接的!

采纳答案by Lakerfield

When printing to a Zebra printer, everything before ^XAand after ^XZis ignored. The html tags around the zpl don't interfere.

打印到 Zebra 打印机时,之前^XA和之后的所有内容都将^XZ被忽略。zpl 周围的 html 标签不会干扰。

The only thing you must ensure is that you print RAW text to the printer.

您唯一必须确保的是将 RAW 文本打印到打印机。

Use the build in windows Generic / Text Onlydriver for your Zebra printer. Instead of the zebra driver.

Generic / Text Only为您的 Zebra 打印机使用内置的 Windows驱动程序。而不是斑马驱动程序。

  • The normal zebra driver: renders the print job to a bitmap
    • result: a slow printed image of your zpl code.
  • The text only driver: sends the zpl code straight to the printer
    • result: a fast printed sticker, from zpl rendered on the printer
  • 普通斑马驱动程序:将打印作业渲染为位图
    • 结果:您的 zpl 代码的缓慢打印图像。
  • 纯文本驱动程序:将 zpl 代码直接发送到打印机
    • 结果:快速打印的贴纸,来自打印机上渲染的 zpl

Example on jsfiddleor on gist.run

实施例上的jsfiddlegist.run

function printZpl(zpl) {
  var printWindow = window.open();
  printWindow.document.open('text/plain')
  printWindow.document.write(zpl);
  printWindow.document.close();
  printWindow.focus();
  printWindow.print();
  printWindow.close();
}


Tested in

测试在

  • Edge
  • Internet Explorer
  • Firefox
  • 边缘
  • IE浏览器
  • 火狐

Not working in:

不工作:



Select the Generic / Text Only driver in your printer properties:

在您的打印机属性中选择 Generic / Text Only 驱动程序:

Zebra printer - Generic / Text Only driver

Zebra 打印机 - 通用/纯文本驱动程序

回答by lukbl

Following snippet worked for me on Firefoxand IE11, with a little change to printer's properties.

以下代码段在FirefoxIE11上对我有用,对打印机的属性进行了一些更改。

I was using thisprinter emulator.

我正在使用打印机模拟器。

In ChromeI get error from emulator when printing from Chrome's Print Dialog. Using system dialog gives error about printing failure from Chrome. CTRL + SHIFT + P(shortcut to skip Chrome dialog) no error and nothing happens. All these errors may be related to emulator, but I don't have real printer to test it.

Chrome 中,我从 Chrome 的打印对话框打印时从模拟器收到错误。使用系统对话框会出现有关 Chrome 打印失败的错误。CTRL + SHIFT + P(跳过 Chrome 对话框的快捷方式)没有错误,也没有任何反应。所有这些错误都可能与模拟器有关,但我没有真正的打印机来测试它。

In Printer's PropertiesI set following options:

打印机的属性中,我设置了以下选项:

  • Begin Print Job : ${
  • End Print Job: }$
  • 开始打印作业: ${
  • 结束打印作业: }$

As you can see in script below ZPL code is wrapped in '${'and '}$'

正如您在下面的脚本中看到的,ZPL 代码被包裹在'${''}$'

<script type="text/javascript">
  function openWin() {
    var printWindow = window.open();
    printWindow.document.open('text/plain')
    printWindow.document.write('${^XA^FO50,100^BXN,10,200^FDYourTextHere^FS^XZ}$');
    printWindow.document.close();
    printWindow.focus();
    printWindow.print();
  }
</script>
<input type="button" value="Print code" onclick="openWin()" />

JSFiddle

JSFiddle

回答by gmacster

If you want to accomplish this consistently without involving the opening of popups or user prompts, you are going to need an application running on the client PC to act as mediator between your application's javascript and the client's printer.

如果您想在不涉及打开弹出窗口或用户提示的情况下始终如一地完成此操作,您将需要在客户端 PC 上运行的应用程序充当应用程序的 javascript 和客户端打印机之间的中介。

One popular way of doing this is via a browser plugin (NPAPI). But this approach is quickly becoming obsolete as many browsers have begun to remove NPAPI support entirely (Chrome, Firefox).

一种流行的方法是通过浏览器插件 (NPAPI)。但是这种方法很快就过时了,因为许多浏览器已经开始完全删除 NPAPI 支持(ChromeFirefox)。

Another approach is to develop a small application that runs on your client's PC which listens for websocket connections. Your web application will send the ZPL through a connection to the client's websocket server, which in turn will generate a print job.

另一种方法是开发一个在客户端 PC 上运行的小型应用程序,用于侦听 websocket 连接。您的 Web 应用程序将通过连接将 ZPL 发送到客户端的 websocket 服务器,后者将生成打印作业。

A third approach - some printers have an internal IP address that can be sent raw ZPL. If you build your web application so that a user can configure this IP address, it would be an option to send the ZPL to that address. However, this won't work if your users are using printers that don't support this functionality.

第三种方法 - 某些打印机具有可以发送原始 ZPL 的内部 IP 地址。如果您构建 Web 应用程序以便用户可以配置此 IP 地址,则可以选择将 ZPL 发送到该地址。但是,如果您的用户使用不支持此功能的打印机,这将不起作用。

回答by Nathan Smith

Zebra created an application called (BROWSER PRINT) they released April 2016. It appears to be a local JAVA service that runs on your computer and exposes a pseudo rest api. They provide a javascript api to hide the details and simplify usage.

Zebra 创建了一个名为 (BROWSER PRINT) 的应用程序,他们于 2016 年 4 月发布。它似乎是一个本地 JAVA 服务,在您的计算机上运行并公开一个伪 rest api。他们提供了一个 javascript api 来隐藏细节并简化使用。

Currently supports (ZD500, ZD410, LP2824+, ZT230, ZT420, QLn320, GX420)

目前支持(ZD500、ZD410、LP2824+、ZT230、ZT420、QLn320、GX420)

It allows you to select the printer if there are multiple. Also allows 2 way communication where you can ask the printer it's status and get the result. They recently added support for printers connected to Ethernet but do not support printers mapped via Windows UNC path.

如果有多个打印机,它允许您选择打印机。还允许 2 路通信,您可以在其中询问打印机的状态并获得结果。他们最近添加了对连接到以太网的打印机的支持,但不支持通过 Windows UNC 路径映射的打印机。

https://www.zebra.com/us/en/products/software/barcode-printers/link-os/browser-print.html

https://www.zebra.com/us/en/products/software/barcode-printers/link-os/browser-print.html

回答by Haroldo_OK

You see, the main problem here is that the Zebra commands will only work if you can send the raw, unmodified bytes directly to the printer port; the browser won't allow you to do that, unfortunately.

你看,这里的主要问题是 Zebra 命令只有在你可以将原始的、未修改的字节直接发送到打印机端口时才能工作;不幸的是,浏览器不允许你这样做。

You will need some way to get such direct acess:

您将需要某种方式来获得这样的直接访问权限:

  • One way would be through a browser extension, so you'd have less restricted access to the hardware; you could do that through NPAPI, but Chrome does not support that, and both Mozilla and IE will cease supporting that really soon;; Chrome can allow direct access to the hardware through the Native Messaging API; Mozilla may support a similar solutionreally soon;
  • Another option would be to use a Java JNLP application to provide such an access, and it can be called from a browser.
  • 一种方法是通过浏览器扩展程序,这样您对硬件的访问限制就会减少;你可以通过 NPAPI 做到这一点,但 Chrome 不支持,而且 Mozilla 和 IE 很快就会停止支持;;Chrome 可以允许通过Native Messaging API直接访问硬件;Mozilla 可能很快就会支持类似的解决方案
  • 另一种选择是使用 Java JNLP 应用程序来提供此类访问,并且可以从浏览器调用它。