typescript - qz no está definido qz_tray
He estado buscando una solución para imprimir desde la web en el lado del cliente, esto (https://medium.com/@yehandjoe/angular-2-raw-printing-service-56614d358754) es lo que he estado siguiendo. Sugiere usar qz tray para obtener acceso a la impresora. He copiado el código tal como está, pero no funciona.
cada vez que se ejecuta la función getprinters() dice "qz no está definido"
He importado paquetes usando estos comandos de npm
npm instalar qz-tray sha ws
npm install rsvp, este es el código de mi servicio de impresora:
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/fromPromise';
import 'rxjs/add/observable/throw';
import 'rxjs/add/operator/map';
declare var qz: any;
@Injectable()
export class PrinterService {
constructor() { }
errorHandler(error: any): Observable<any> {
return Observable.throw(error);
}
// Get list of printers connected
getPrinters(): Observable<string[]> {
return Observable
.fromPromise(qz.websocket.connect().then(() => qz.printers.find()))
.map((printers: string[]) => printers)
.catch(this.errorHandler);
}
// Get the SPECIFIC connected printer
getPrinter(printerName: string): Observable<string> {
return Observable
.fromPromise(qz.websocket.connect().then(() => qz.printers.find(printerName)))
.map((printer: string) => printer)
.catch(this.errorHandler);
}
// Print data to chosen printer
printData(printer: string, data: any): Observable<any> {
// Create a default config for the found printer
const config = qz.configs.create(printer);
return Observable.fromPromise(qz.print(config, data))
.map((anything: any) => anything)
.catch(this.errorHandler);
}
// Disconnect QZ Tray from the browser
removePrinter(): void {
qz.websocket.disconnect();
}
}
Por favor corrígeme si estoy cometiendo algún error o realmente agradecería cualquier otra solución alternativa
Respuesta #1
Parece que necesitas importar qz tray a tu proveedor.
Usé SHA.js: https://www.npmjs.com/package/sha.js para el cifrado y utilicé promesas nativas.
Así que añadí las siguientes líneas al inicio del archivo debajo de las importaciones existentes:
import * as shajs from 'sha.js';
import * as qz from 'qz-tray';
Establecer SHA para QZ
Recuerda decirle a QZ que use el nuevo paquete sha.js con esto:
qz.api.setSha256Type(function (data) {
return shajs('sha256').update(data).digest('hex')
});
Establecer Promesas Nativas para QZ
Recuerda decirle a QZ que use el nuevo paquete sha.js con esto:
qz.api.setPromiseType(function (resolver) {
return new Promise(resolver);
});
Respuesta #2
Yo también necesitaba usar este servicio QZ, parece que es la única manera de comunicarse con una impresora desde una aplicación de JavaScript.
De todos modos, gracias a la respuesta anterior y a algunos artículos, logré hacer una pequeña aplicación Angular 7, que se conecta muy fácilmente con la impresora.
Sentí como compartir este código por si alguien tenía que pasar por el mismo proceso. Y parece que esta es la única publicación sobre QZ Tray. Primero, debes instalar las dependencias necesarias ejecutando:
npm install qz-tray js-sha256 rsvp --save
En segundo lugar, deberías crear un servicio de impresión, aquí está su código:
import { Injectable } from '@angular/core';
import { from as fromPromise, Observable, throwError } from 'rxjs';
import { HttpErrorResponse } from '@angular/common/http';
import { catchError, map } from 'rxjs/operators';
import * as qz from 'qz-tray';
import { sha256 } from 'js-sha256';
@Injectable({
providedIn: 'root'
})
export class PrinterService {
//npm install qz-tray js-sha256 rsvp --save
constructor() {
qz.api.setSha256Type(data => sha256(data));
qz.api.setPromiseType(resolver => new Promise(resolver));
}
// Get the list of printers connected
getPrinters(): Observable<string[]> {
console.log('+++++++++PrinterService+++++');
return fromPromise(
qz.websocket.connect().then(() => qz.printers.find())
)
map((printers: string[]) => printers)
, catchError(this.errorHandler);
}
// Get the SPECIFIC connected printer
getPrinter(printerName: string): Observable<string> {
return fromPromise(
qz.websocket.connect()
.then(() => qz.printers.find(printerName))
)
map((printer: string) => printer)
, catchError(this.errorHandler);
}
// Print data to chosen printer
printData(printer: string, data: any): Observable<any> {
const config = qz.configs.create(printer);
return fromPromise(qz.print(config, data))
map((anything: any) => anything)
, catchError(this.errorHandler);
}
private errorHandler(error: HttpErrorResponse) {
if (error.error instanceof ErrorEvent) {
console.log(error.error);
console.log('An error occurred:', error.status);
return throwError(error.error);
} else {
console.log('An error occurred:', error.status);
console.log(error.error);
return throwError(error.error);
}
};
}
finalmente, solo deberías llamar a tu servicio desde algún componente, y ejecutar las funciones, en este caso, usé el componente app:
import { Component } from '@angular/core';
import { PrinterService } from './printer.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'qz-tray-example';
printers: string[];
constructor(public _printerService: PrinterService) {
}
ngOnInit() {
this.printers = [];
console.log('AppComponent____________');
this._printerService.getPrinters().subscribe(
data => {
console.log(data);
// this.printers = data;
this.print();
},
err => {
console.log(err);
}
);
}
print() {
let content1 = `
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
</head>
<body>
<div>
<h3>Printing Test 1</h3>
</div>
</body>
</html>`;
let content2 = `
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
</head>
<body>
<div>
<h3>Printing Test 2</h3>
</div>
</body>
</html>`;
var data = [{
type: 'html',
format: 'plain', // or 'plain' if the data is raw HTML
data: content1
},
{
type: 'html',
format: 'plain', // or 'plain' if the data is raw HTML
data: content2
}];
data[0].data = content1;
this._printerService.printData('zebra', data).subscribe(
data => {
console.log('ok print');
},
err => {
console.log(err);
}
);
}
}
Espero que esta respuesta ayude a alguien a comenzar con su aplicación, buena suerte ;)
