Búsqueda de sitios web

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 ;)

Artículos relacionados