При нажатии кнопки печать на термопринтере с использованием JavaScript, angular или Node JS

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

  1. У меня была бы служба, которая отправляет данные, которые я хочу распечатать, в компонент, который отображает данные (фактически создает визуальный документ с данными с сервера), а затем 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());
}
 
  1. Если вы не хотите делать причудливые вещи, вы можете просто упростить
    и выложить то, что вы хотите распечатать, и просто вызвать window.print() из
    компонента:

В HTML

 <button (click)="onPrint()">Print</button>
 

В TS

 onPrint(){
    window.print();
}
 
  1. Вы также можете использовать метод открытия / записи / закрытия всплывающего окна:

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 случаях он открывает всплывающее окно печати, а не автоматически закрывает его, он должен печатать его молча, без всплывающего окна.