Alternativa a QZ Tray: imprimir sin un applet Java en cada puesto

QZ Tray imprime desde el navegador a una impresora local. Necesita Java en la máquina y un certificado de firma de código para imprimir en silencio. Aquí está cuándo dejarlo atrás.

QZ Tray resuelve bien un problema concreto: una aplicación web necesita enviar ESC/POS o ZPL en crudo a una impresora conectada físicamente a la máquina donde corre el navegador, sin diálogo de impresión. Los navegadores no pueden hacerlo a propósito, así que QZ Tray instala una pequeña aplicación Java en local y la página habla con ella por un socket.

Respuesta corta: QZ Tray es de lado cliente por diseño. Exige Java en cada puesto, y un certificado de firma de código si quieres que la impresión ocurra sin ventana de confirmación. Si la impresión la dispara un evento de negocio y no la persona que está delante de la pantalla, mover la llamada a tu servidor elimina ambos requisitos.

Dos modelos, dos superficies de fallo

QZ Tray API de impresión de servidor
Dónde nace la llamada El navegador Tu backend
Instalación local Java + QZ Tray, por puesto Ninguna
Certificado para impresión silenciosa No
Funciona sin sesión iniciada No
Funciona en tableta o móvil No
La impresora debe estar conectada físicamente Sí, a ese puesto No, accesible por internet
ESC/POS y ZPL en crudo

Cuándo QZ Tray es la herramienta correcta

No cambies solo porque una lista de requisitos parezca larga. QZ Tray encaja bien cuando:

  • La persona que dispara la impresión está físicamente junto a la impresora: un mostrador, una mesa de laboratorio, un puesto de expedición.
  • Imprimes en hardware local que no puedes hacer direccionable en red, como una impresora de etiquetas o de tarjetas especializada con driver propietario.
  • El número de puestos es pequeño y alguien los administra.

En esos casos el componente local no es una carga, es justamente el punto.

Dónde empieza a doler

El certificado. Sin petición firmada, QZ Tray muestra un diálogo de confirmación en cada impresión. Quitarlo implica comprar un certificado de firma de código, guardar la clave privada en tu servidor, renovarlo y gestionar el día en que caduca, que suele manifestarse como "de repente a todo el mundo le sale un aviso".

Java en cada escritorio. Un JRE que instalar, mantener actualizado y defender en una revisión de seguridad. En organizaciones que llevan años quitando Java de los puestos, esto suele ser un bloqueo duro.

El usuario tiene que estar ahí. No se imprime nada cuando el navegador está cerrado, la sesión ha caducado, o el pedido entra a las 3 de la madrugada. Cualquier flujo que deba reaccionar a un evento en vez de a un clic encaja mal.

Coste de soporte a distancia. Si tus usuarios son clientes y no compañeros, pasas a dar soporte a instalaciones en máquinas que no ves.

Mover la llamada al servidor

Cuando la impresión es consecuencia de que algo ocurre (un pedido pagado, un envío creado, un ticket asignado), el sitio natural de la llamada es donde ya se gestiona ese evento:

await fetch(`https://www.expedy.fr/api/v2/printers/${printerUid}/print`, {
  method: 'POST',
  headers: {
    Authorization: `${process.env.API_SID}:${process.env.API_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ printer_msg: ticket, origin: `pedido-${orderId}` }),
});

Sin instalación, sin certificado, sin navegador. A la impresora se llega por su propia conexión saliente: o bien una impresora en la nube, o bien una impresora USB existente detrás de un adaptador Raspberry Pi, que es el equivalente más cercano a lo que QZ Tray hacía en local.

Un término medio útil

No hace falta elegir de forma global. Muchos equipos mantienen QZ Tray para las impresiones que lanza el operador en el mostrador, y mueven al servidor las impresiones dirigidas por eventos (confirmaciones de pedido, tickets de cocina, etiquetas de envío generadas por un proceso por lotes). Los dos conviven sin conflicto, y la vía de servidor es la que sigue funcionando de noche.

Empieza por imprimir un ticket de prueba con el plan gratuito desde el backend que ya gestiona el evento.

FAQ

¿Por qué QZ Tray necesita un certificado?

Sin petición firmada, el usuario recibe un diálogo de confirmación antes de cada impresión. Un certificado de firma de código permite que tu aplicación firme las peticiones para que la impresión sea silenciosa, lo que implica comprar, guardar y renovar ese certificado.

¿Puedo imprimir desde el navegador sin software local?

ESC/POS en crudo a una impresora conectada, no: los navegadores lo bloquean a propósito. Lo que sí puedes es hacer que tu servidor envíe el trabajo a una impresora accesible por red, lo que saca al navegador del camino por completo.

¿Una API de servidor admite ESC/POS y ZPL en crudo?

Sí. Los datos de comandos en crudo se pueden enviar por la API de impresión, así que los formatos de etiqueta y de ticket que ya generas siguen funcionando.

¿Puedo quedarme con QZ Tray para algunas impresiones?

Sí, y a menudo es el diseño correcto. Consérvalo para las impresiones que lanza el operador en el mostrador y mueve al servidor las dirigidas por eventos; los dos no entran en conflicto.