Alternativa ao QZ Tray: imprimir sem um applet Java em cada posto

O QZ Tray imprime do navegador para uma impressora local. Precisa de Java na máquina e de um certificado de assinatura de código para imprimir em silêncio. Eis quando o deixar para trás.

O QZ Tray resolve bem um problema concreto: uma aplicação web precisa de enviar ESC/POS ou ZPL em bruto para uma impressora ligada fisicamente à máquina onde o navegador corre, sem caixa de diálogo de impressão. Os navegadores não o podem fazer de propósito, por isso o QZ Tray instala localmente uma pequena aplicação Java e a página fala com ela através de um socket.

Resposta curta: o QZ Tray é do lado do cliente por desenho. Exige Java em cada posto e um certificado de assinatura de código se quiser que a impressão aconteça sem janela de confirmação. Se a impressão for despoletada por um evento de negócio e não pela pessoa à frente do ecrã, mover a chamada para o seu servidor elimina os dois requisitos.

Dois modelos, duas superfícies de falha

QZ Tray API de impressão do lado do servidor
Onde nasce a chamada O navegador O seu backend
Instalação local Java + QZ Tray, por posto Nenhuma
Certificado para impressão silenciosa Sim Não
Funciona sem sessão iniciada Não Sim
Funciona em tablet ou telemóvel Não Sim
A impressora tem de estar ligada fisicamente Sim, a esse posto Não, acessível pela internet
ESC/POS e ZPL em bruto Sim Sim

Quando o QZ Tray é a ferramenta certa

Não mude só porque uma lista de requisitos parece longa. O QZ Tray assenta bem quando:

  • Quem despoleta a impressão está fisicamente junto à impressora: um balcão, uma bancada de laboratório, um posto de expedição.
  • Imprime em hardware local que não consegue tornar endereçável em rede, como uma impressora de etiquetas ou de cartões especializada com driver proprietário.
  • O número de postos é pequeno e alguém os administra.

Nesses casos o componente local não é um fardo, é precisamente o objetivo.

Onde começa a doer

O certificado. Sem pedido assinado, o QZ Tray mostra uma caixa de confirmação em cada impressão. Livrar-se dela implica comprar um certificado de assinatura de código, guardar a chave privada no seu servidor, renová-lo e gerir o dia em que expira, o que costuma manifestar-se como "de repente toda a gente recebe um popup".

Java em cada secretária. Um JRE para instalar, manter atualizado e defender numa revisão de segurança. Em organizações que passaram anos a retirar Java dos postos, isto é muitas vezes um bloqueio duro.

O utilizador tem de estar lá. Não se imprime nada quando o navegador está fechado, a sessão expirou, ou a encomenda chega às 3 da manhã. Qualquer fluxo que deva reagir a um evento em vez de a um clique encaixa mal.

Custo de suporte à distância. Se os seus utilizadores são clientes e não colegas, passa a dar apoio a instalações em máquinas que não vê.

Mover a chamada para o servidor

Quando a impressão é consequência de algo que acontece (uma encomenda paga, um envio criado, um ticket atribuído), o sítio natural para a chamada é onde esse evento já é tratado:

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: `encomenda-${orderId}` }),
});

Sem instalação, sem certificado, sem navegador. A impressora é alcançada pela sua própria ligação de saída: ou uma impressora na nuvem, ou uma impressora USB já existente atrás de um adaptador Raspberry Pi, que é o equivalente mais próximo do que o QZ Tray fazia localmente.

Um meio-termo útil

Não tem de escolher de forma global. Muitas equipas mantêm o QZ Tray para as impressões lançadas pelo operador ao balcão, e passam para o servidor as impressões guiadas por eventos (confirmações de encomenda, talões de cozinha, etiquetas de envio geradas por um processo em lote). Os dois convivem sem conflito, e a via do servidor é a que continua a funcionar de noite.

Comece por imprimir um talão de teste no plano gratuito a partir do backend que já trata o evento.

FAQ

Porque é que o QZ Tray precisa de um certificado?

Sem pedido assinado, o utilizador recebe uma caixa de confirmação antes de cada impressão. Um certificado de assinatura de código permite que a sua aplicação assine os pedidos para que a impressão seja silenciosa, o que implica comprar, guardar e renovar esse certificado.

Posso imprimir a partir do navegador sem software local?

ESC/POS em bruto para uma impressora ligada, não: os navegadores bloqueiam isso de propósito. Já pode, no entanto, fazer o seu servidor enviar o trabalho para uma impressora acessível em rede, o que retira o navegador do caminho por completo.

Uma API do lado do servidor suporta ESC/POS e ZPL em bruto?

Sim. Os dados de comando em bruto podem ser enviados pela API de impressão, por isso os formatos de etiqueta e de talão que já gera continuam a funcionar.

Posso manter o QZ Tray para algumas impressões?

Sim, e muitas vezes é o desenho certo. Guarde-o para as impressões lançadas pelo operador ao balcão e passe para o servidor as guiadas por eventos; os dois não entram em conflito.