JavaScript: отправка необработанного текста на принтер - без запросов к серверу/вызовов методов, возможность работы в автономном режиме, исключительно на стороне клиента

Мое тщательное исследование в Интернете дало мне несколько идей, но ни одна из них не работает правильно в моем конкретном случае использования. Вот что у меня есть:

1) принтер Zebra, использующий ZPL в качестве языка печати;

2) Строка на javascript, состоящая из 3-х форм ZPL для печати 3-х этикеток.

Наш системный инженер уже проверил правильность синтаксиса 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();

На данный момент (в целях тестирования) theDiv — это контейнер, в который я помещаю строку ZPL. В принципе, я понял, что лучшее решение — открыть новое всплывающее окно, заполнить его строкой ZPL и вызвать thePopupWindow.print(); Затем пользователь выбирает принтер Zebra и нажимает «Печать». Проблема: кажется, что принтер интерпретирует то, что печатается, как HTML-страницу (из-за

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

теги, которые я вижу, например, когда просматриваю всплывающее окно в Chrome) и печатает код ZPL как обычный текст, а не интерпретирует его и печатает метку. Я полагаю, мне нужно что-то вроде thePopupWindow.write(), чтобы избежать записи в свойство документа окна, которое, очевидно, переносит строку в html-код. Чтобы проверить это, я использую драйвер Generic/Text Only и сохраняю то, что «напечатано», в файл .txt.

В Chrome я получаю пустой файл.

В Mozilla, когда я удаляю эту строку: mywindow.document.open('text/plain'); Я получаю ZPL в виде символов, по одному в строке. Когда я добавляю его, я получаю только дату и время, опять же по одному символу в строке.

В IE - я получаю это (с или без mywindow.document.open('text/plain');):

Page 1 o



    ^XA^PW400^LL37^





          12.4.2016

Я нашел различные решения, но они включают использование php, c#, даже java, и я не хочу, чтобы это было на стороне сервера, как указано в заголовке. Любая помощь будет оценена. @forgivenson, спасибо за замечание. Прочитав ваш, я увидел маленький «x», по которому я могу щелкнуть, чтобы удалить свой комментарий, поэтому я добавил комментарий в вопрос. Я упустил очень важную вещь: принтер подключен через USB-порт!


person user2177283    schedule 12.04.2016    source источник
comment
К вашему сведению, вы можете отредактировать свой вопрос, чтобы добавить эту информацию.   -  person forgivenson    schedule 12.04.2016
comment
Интересный вопрос. Когда я столкнулся с похожей проблемой, мне пришлось создать подписанный Java-апплет, единственной функцией которого была отправка байтов на порт принтера. Другой вариант — написать расширение для браузера. Я сомневаюсь, что есть способ отправлять байты непосредственно на принтер, используя только javascript, из соображений безопасности.   -  person Haroldo_OK    schedule 12.04.2016
comment
Видите ли, основная проблема здесь заключается в том, что команды Zebra будут работать только в том случае, если вы можете отправить необработанные, немодифицированные байты непосредственно на порт принтера; к сожалению, браузер не позволит вам это сделать. Вам понадобится какой-то способ получить такой прямой доступ, один из способов — через расширение браузера, чтобы у вас был менее ограниченный доступ к оборудованию; другим вариантом может быть использование апплета Java или приложения JNLP для обеспечения такого доступа.   -  person Haroldo_OK    schedule 12.04.2016


Ответы (5)


При печати на принтер Zebra все до ^XA и после ^XZ игнорируется. HTML-теги вокруг zpl не мешают.

Единственное, что вы должны убедиться, это то, что вы печатаете текст RAW на принтере.

Используйте встроенный драйвер Windows Generic / Text Only для вашего принтера Zebra. Вместо водителя-зебры.

  • 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

Пример на jsfiddle или на gist.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();
}

Протестировано в

  • Край
  • Интернет-проводник
  • Fire Fox

Не работает в:


Выберите драйвер Generic/Text Only в свойствах принтера:

«Принтер

person Lakerfield    schedule 10.05.2016
comment
+1 Спасибо за полезный ответ. Как вы и сказали, теперь мы можем печатать этикетки с помощью принтера Zebra и драйвера Generic/Text Only в Internet Explorer и Firefox. Chrome не печатает, когда мы открываем диалоговое окно системной печати (ctrl + shift + p) и выбираем драйвер Generic / Text Only, и появляется предупреждение об ошибке. Теперь у нас возникла проблема, связанная с кодировкой. Все символы кириллицы преобразуются в '.' (точечный) символ. Это связано с драйвером Generic/Text Only, потому что даже когда я печатаю что-то из блокнота кириллицей, мы получаем количество точек. Любые идеи по этому поводу? - person user2177283; 01.06.2016
comment
Рад слышать, что это сработало для вас. Взгляните на следующий ответ о том, как избежать ошибок кодирования с помощью команды ^FH: stackoverflow.com/a/13041688 - person Lakerfield; 09.06.2016
comment
Спасибо, что предложили команду ^FH! Я действительно наткнулся на эту же тему, когда искал решение проблемы с кодировкой. В документах ZPL от Zebra я нашел команду ^CI, и попытка с ^CI33 помогла. Я не уверен, куда мне его положить. Я просто вставил его перед полями (перед первым ^FD в ZPL). - person user2177283; 11.06.2016
comment
@Lakerfield, должен ли ваш ответ работать и с EPL? У меня есть такая же потребность, как и в этом вопросе, и ваш ответ был очень полезен для меня и действительно помог ZPL. Моя проблема в том, что мне также нужно поддерживать EPL, и простое переключение кода ZPL на код EPL, похоже, не работает. Знаете ли вы, необходимы ли какие-либо изменения для отправки EPL? Спасибо. - person Caio Sant'Anna; 13.07.2018
comment
Вы можете найти драйвер в списке производителей «Универсальный» в левой части диалогового окна свойств принтера Windows. - person Dean; 08.10.2020

Если вы хотите выполнить это последовательно, не открывая всплывающие окна или пользовательские подсказки, вам понадобится приложение, работающее на клиентском ПК, которое будет выступать в качестве посредника между javascript вашего приложения и принтером клиента.

Один из популярных способов сделать это — через плагин для браузера (NPAPI). Но этот подход быстро устаревает, так как многие браузеры начали полностью отказываться от поддержки NPAPI (Chrome, Firefox ).

Другой подход заключается в разработке небольшого приложения, которое запускается на ПК вашего клиента и прослушивает соединения через веб-сокеты. Ваше веб-приложение отправит ZPL через соединение с сервером веб-сокетов клиента, который, в свою очередь, сгенерирует задание на печать.

Третий подход — некоторые принтеры имеют внутренний IP-адрес, на который можно отправить необработанный ZPL. Если вы создадите свое веб-приложение так, чтобы пользователь мог настроить этот IP-адрес, можно было бы отправить ZPL на этот адрес. Однако это не сработает, если ваши пользователи используют принтеры, не поддерживающие эту функцию.

person gmacster    schedule 13.04.2016

Следующий фрагмент работал у меня в Firefox и IE11 с небольшими изменениями в свойствах принтера.

Я использовал этот эмулятор принтера.

В Chrome я получаю сообщение об ошибке от эмулятора при печати из диалогового окна печати Chrome. Использование системного диалога выдает ошибку о сбое печати из Chrome. CTRL + SHIFT + P (сочетание клавиш для пропуска диалогового окна Chrome) без ошибок и ничего не происходит. Все эти ошибки могут быть связаны с эмулятором, но у меня нет настоящего принтера, чтобы проверить его.

В Свойствах принтера я установил следующие параметры:

  • Начать задание на печать: ${
  • Завершить задание на печать: }$

Как вы можете видеть в приведенном ниже скрипте, код 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

person lukbl    schedule 12.04.2016
comment
Спасибо, но, к сожалению, в этот раз не получилось. Я пошел к нашему сервисному инженеру, и мы оба протестировали ваше решение. Он установил эти свойства принтера для начала и завершения задания печати. На этот раз мы получаем строку '${^XA^FO50,100^BXN,10,200^FDYourTextHere^FS^XZ}$', а не настоящую метку. Возможно, это как-то связано с кодировкой нового окна, которое содержит ZPL и где я вызываю theWindow.print(); printWindow.document.open('text/plain') тоже не помог. Я вижу, что мне это как-то нужно как необработанный текст. - person user2177283; 13.04.2016

Zebra создала приложение под названием (BROWSER PRINT), которое они выпустили в апреле 2016 года. Похоже, это локальная служба JAVA, которая работает на вашем компьютере и предоставляет API-интерфейс псевдо-остального. Они предоставляют javascript API, чтобы скрыть детали и упростить использование.

В настоящее время поддерживает (ZD500, ZD410, LP2824+, ZT230, ZT420, QLn320, GX420)

Это позволяет выбрать принтер, если их несколько. Также позволяет двустороннюю связь, где вы можете узнать состояние принтера и получить результат. Недавно они добавили поддержку принтеров, подключенных к Ethernet, но не поддерживают принтеры, подключенные через путь Windows UNC.

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

person Nathan Smith    schedule 30.01.2017

Видите ли, основная проблема здесь заключается в том, что команды Zebra будут работать только в том случае, если вы можете отправить необработанные, немодифицированные байты непосредственно на порт принтера; к сожалению, браузер не позволит вам это сделать.

Вам понадобится какой-то способ получить такой прямой доступ:

  • Один из способов — через расширение браузера, чтобы у вас был менее ограниченный доступ к оборудованию; вы можете сделать это через NPAPI, но Chrome этого не поддерживает, и Mozilla, и IE очень скоро перестанут его поддерживать;; Chrome может разрешить прямой доступ к оборудованию через Native Messaging API; Mozilla может очень скоро поддерживать подобное решение;
  • Другим вариантом может быть использование приложения Java JNLP для предоставления такого доступа, и его можно вызывать из браузера.
person Haroldo_OK    schedule 14.04.2016