#javascript #node.js #angular #thermal-printer
Вопрос:
Я создал на NodeJS API, который я вызываю по нажатию кнопки в приложении angular.
Хотите распечатать квитанции о покупке одним нажатием кнопки, с помощью термопринтера. Без какого-либо диалогового окна сохранения или печати PDF, непосредственно он должен печатать.
Я попробовал этот код NodeJS, но похоже, что он работает для настольных приложений, а не для Интернета. У меня есть пользовательский интерфейс и код в другом репозитории кодовой базы.
Я пробую этот код:
'use strict';
const { PosPrinter } = require("electron-pos-printer");
class SeriesPrinter {
constructor() { }
printSr() {
console.log("Inside print function");
const print_data = [
{ type: 'text', value: 'Sample text', style: 'text-align:center;font-weight: bold' },
{ type: 'text', value: 'Another text', style: 'color: #fff' },
];
// returns promise<any>
PosPrinter.print(print_data, {
printerName: 'POS-80C',
preview: false,
width: '170px', // width of content body
margin: '0 0 0 0', // margin of content body
copies: 1, // The number of copies to print
})
.then(() => {
// some code ...
})
.catch((error) => {
console.error(error);
});
}
}
module.exports = SeriesPrinter;
выдает ошибку:
Inside print function
TypeError: BrowserWindow is not a constructor
node_moduleselectron-pos-printerdistpost-printer.js:87:30
at new Promise (<anonymous>)
node_moduleselectron-pos-p
Любые идеи по исправлению этого или любого другого решения (на стороне пользовательского интерфейса или на стороне NodeJS любой будет работать, он должен печатать беззвучно)
Комментарии:
1. Я сомневаюсь, что можно печатать без получения разрешения от пользователя, то есть всплывающего окна какого-либо рода.
2. Согласно README of
electron-pos-printer
, для этого требуется electron. Если вы не знакомы с electron, это node.js фреймворк для настольных приложений, который ожидает существования определенных файлов. Вы можете увидеть пример приложения electron, на которое ссылается README по адресу github.com/fssonca/electron-printer . Вероятно, вы можете получить желаемую функциональность, добавив сервер API в пример приложения, но это может быть немного громоздким.3. @sandip, простое использование
require("electron-pos-printer")
не означает, что вы используете свой node.js приложение в виде электронного приложения. Скорее, это библиотека, которая ожидает запуска в контексте electron. Ваша ошибка указывает на то, что он не может получитьBrowserWindow
экземплярelectron
. Вы можете увидеть, где это добавляется здесь4. Создайте настольный сервер nodejs, который взаимодействует с термопринтером и предоставляет API на localhost, доступ к которому можно получить через вашу веб-страницу.
5. @sandip то, что @steve пытается сказать, правильно. вы используете для этого неправильную библиотеку. вы импортировали
electron-pos-printer
файл, в котором естьelectron
слово, так что это означает, что он может быть использован только электронными приложениями. удалитеelectron-pos-printer
и попробуйте другие библиотеки , такие какESCPOS
илиnode-thermal-printer
. Я не думаю, что это возможно напрямую из Angular, поэтому вам нужно сосредоточиться на бэкэнде и делать это оттуда.
Ответ №1:
Вы получаете ошибку типа: BrowserWindow не является конструктором, потому что вы используете его в неэлектронной среде (браузере).
Что бы я сделал, поскольку вы упомянули Angular:
- У меня была бы служба, которая отправляет данные, которые я хочу распечатать, в компонент, который отображает данные (фактически создает визуальный документ с данными с сервера), а затем window.print() .
Услуга будет выглядеть так:
export class PrintService {
isPrinting = false;
constructor(private router: Router) { }
printDocument(documentName: string, documentData: string[]) {
this.isPrinting = true;
this.router.navigate(['/',
{ outlets: {
'print': ['print', documentName, documentData.join()]
}}]);
}
onDataReady() {
setTimeout(() => {
window.print();
this.isPrinting = false;
this.router.navigate([{ outlets: { print: null }}]);
});
}
}
и вы могли бы использовать его в таком компоненте, как InvoiceComponent:
ngOnInit() {
this.invoiceDetails = this.invoiceIds
.map(id => this.getInvoiceDetails(id));
Promise.all(this.invoiceDetails)
.then(() => this.printService.onDataReady());
}
- Если вы не хотите делать причудливые вещи, вы можете просто упростить
и выложить то, что вы хотите распечатать, и просто вызвать window.print() из
компонента:
В HTML
<button (click)="onPrint()">Print</button>
В TS
onPrint(){
window.print();
}
- Вы также можете использовать метод открытия / записи / закрытия всплывающего окна:
HTML
<div id="printSectionId" >
.......
<button (click)="printToCart('printSectionId')" class="button">Print</button>
...
</div>
ТС
export class Component{
constructor(){}
printToCart(printSectionId: string){
let popupWinindow
let innerContents = document.getElementById(printSectionId).innerHTML;
popupWinindow = window.open('', '_blank', 'width=600,height=700,scrollbars=no,menubar=no,toolbar=no,location=no,status=no,titlebar=no');
popupWinindow.document.open();
popupWinindow.document.write('<html><head><link rel="stylesheet" type="text/css" href="style.css" /></head><body onload="window.print()">' innerContents '</html>');
popupWinindow.document.close();
}
}
Комментарии:
1. спасибо, что добавили, поделились своими идеями, во всех 3 случаях он открывает всплывающее окно печати, а не автоматически закрывает его, он должен печатать его молча, без всплывающего окна.