12345. Permite que qualquer aplicação web envie comandos de impressão diretamente para impressoras locais — sem diálogo de impressão do navegador. Substitui o QZ Tray gratuitamente.Pré-requisito: O executável
IZPrint.exe deve estar rodando na máquina do usuário final. Download aqui.
1. Instalação da biblioteca
CDN (recomendado)
Inclua diretamente via CDN, sem precisar copiar arquivos:
<!-- Última versão (sempre atualizada) --> <script src="https://print.iztec.online/cdn/izprint.min.js"></script> <!-- Ou versão específica --> <script src="https://print.iztec.online/cdn/v1/izprint.js"></script>
HTML puro (local)
Copie o arquivo izprint.js para a pasta do seu projeto e inclua no HTML:
<script src="izprint.js"></script>
As classes IZPrint e ESCPOSBuilder ficam disponíveis globalmente em window.
Projetos com módulos (React, Vue, Angular, Svelte, Next.js)
Copie izprint.js para o projeto (ex: src/lib/izprint.js) e importe:
import { IZPrint, ESCPOSBuilder } from './lib/izprint.js';
2. Conexão com o servidor
Conexão básica
const iz = new IZPrint(); await iz.connect();
Com opções personalizadas
const iz = new IZPrint({ host: "localhost", // Host do servidor IZPrint port: 12345, // Porta do WebSocket (padrão: 12345) ssl: false, // true para wss:// (requer certificado) autoReconnect: true, // Reconectar automaticamente reconnectInterval: 3000, // Intervalo entre tentativas (ms) });
Callbacks de eventos
iz.onConnect = () => { console.log("Conectado ao IZPrint!"); }; iz.onDisconnect = (event) => { console.log("Desconectado do IZPrint"); }; iz.onError = (error) => { console.error("Erro no IZPrint:", error); }; await iz.connect();
Verificar status e desconectar
// Verificar se está conectado if (iz.isConnected()) { console.log("Conectado!"); } // Testar comunicação const pong = await iz.ping(); console.log("Servidor respondeu:", pong.timestamp); // Informações do servidor const info = await iz.info(); console.log(info); // { app: "IZPrint", version: "1.0.0", ... } // Desconectar iz.disconnect();
3. Listar impressoras
const printers = await iz.listPrinters(); console.log(printers);
Retorno:
[
{
"name": "EPSON TM-T20",
"driver": "EPSON TM-T20 Receipt",
"port": "USB001",
"status": "READY",
"isDefault": true,
"isNetwork": false
}
]
Status possíveis:
// Apenas a impressora padrão const defaultPrinter = await iz.getDefaultPrinter(); console.log(defaultPrinter); // "EPSON TM-T20"
Montar um <select> de impressoras
const printers = await iz.listPrinters(); const select = document.getElementById("selectImpressora"); select.innerHTML = '<option value="">Impressora Padrão</option>'; printers.forEach(p => { const opt = document.createElement("option"); opt.value = p.name; opt.textContent = p.name + (p.isDefault ? " (Padrão)" : ""); select.appendChild(opt); });
4. Impressão RAW (ESC/POS, ZPL, EPL)
Envia dados binários diretamente para a impressora, sem formatação do Windows. Ideal para impressoras térmicas (cupom, etiquetas).
Texto simples
// Na impressora padrão (null) await iz.printRaw(null, "Texto simples para imprimir\n"); // Em impressora específica await iz.printRaw("EPSON TM-T20", "Texto na EPSON\n");
Dados em base64
const base64Data = btoa("Hello World\n"); await iz.printRaw(null, base64Data);
Comandos ZPL (Zebra)
const zpl = ` ^XA ^CF0,40 ^FO50,50^FDProduto: Widget ABC^FS ^FO50,120^FDCodigo: PRD-001^FS ^FO50,200^BY3^BCN,100,Y,N,N^FD123456789012^FS ^FO50,350^FDPreco: R$ 29,90^FS ^XZ `; await iz.printRaw("Zebra ZD420", zpl);
Comandos EPL (Eltron)
const epl = ` N q812 Q1218,24 A50,50,0,4,1,1,N,"Produto: Widget" B50,100,0,1,2,6,100,B,"123456789012" P1 `; await iz.printRaw("Impressora EPL", epl);
5. Builder ESC/POS — Referência completa
O ESCPOSBuilder facilita a criação de comandos para impressoras térmicas com uma API fluente (encadeável).
const escpos = IZPrint.escpos();
Métodos disponíveis
| Método | Parâmetros | Descrição |
|---|---|---|
| init() | — | Inicializa/reseta a impressora. Sempre chamar primeiro. |
| text(str) | string | Adiciona texto |
| newLine(n) | number (padrão: 1) | Adiciona n quebras de linha |
| feed(n) | number | Alimentar papel n linhas |
| cut(partial) | boolean (padrão: false) | Cortar papel. false=total, true=parcial |
| align(tipo) | "left" / "center" / "right" | Alinhamento do texto |
| bold(on) | boolean | Ativar/desativar negrito |
| underline(on) | boolean | Ativar/desativar sublinhado |
| textSize(w, h) | 1-8, 1-8 | Tamanho do texto. 1=normal, 2=dobro |
| separator(char, width) | string, number | Linha separadora (padrão: "-", 48) |
| textColumns(esq, dir, width) | string, string, number | Texto em 2 colunas |
| barcode(data, type) | string, string | Código de barras (padrão: CODE128) |
| qrCode(data, size) | string, number | QR Code (padrão: size 6) |
| openCashDrawer(pin) | 0 ou 1 | Abrir gaveta de dinheiro |
Tipos de código de barras
Métodos de exportação
| Método | Retorno | Uso |
|---|---|---|
| toBase64() | string | Usar com printRaw() — formato recomendado |
| toArray() | number[] | Array de bytes |
| toUint8Array() | Uint8Array | Buffer binário |
Exemplo completo — Cupom
const escpos = IZPrint.escpos(); escpos .init() .align("center") .bold(true).textSize(2, 2) .text("MINHA LOJA").newLine() .textSize(1, 1).bold(false) .text("Rua Exemplo, 123 - Centro").newLine() .text("CNPJ: 12.345.678/0001-90").newLine(2) .align("left") .separator("=") .textColumns("ITEM", "VALOR") .separator("-") .textColumns("Cafe Expresso x2", "R$ 14,00") .textColumns("Pao de Queijo x3", "R$ 13,50") .separator("-") .bold(true) .textColumns("TOTAL", "R$ 27,50") .bold(false) .separator("=") .newLine() .align("center") .qrCode("https://meusite.com/cupom/123", 5) .newLine() .text("Obrigado pela preferencia!") .newLine(4) .cut(); await iz.printRaw(null, escpos.toBase64());
6. Impressão de PDF
Envia um arquivo PDF para ser impresso. O PDF deve estar em formato base64.
A partir de um <input type="file">
async function imprimirPDF(impressora) { const fileInput = document.getElementById("inputPDF"); if (!fileInput.files.length) { alert("Selecione um arquivo PDF."); return; } const file = fileInput.files[0]; const reader = new FileReader(); reader.onload = async (e) => { const base64 = e.target.result.split(",")[1]; await iz.printPdf(impressora, base64); }; reader.readAsDataURL(file); }
A partir de um fetch/API
const response = await fetch("/api/relatorio/pdf/123"); const blob = await response.blob(); const reader = new FileReader(); reader.onload = async (e) => { const base64 = e.target.result.split(",")[1]; await iz.printPdf(null, base64); }; reader.readAsDataURL(blob);
7. Impressão de HTML
Envia conteúdo HTML para ser impresso. Ideal para relatórios formatados, tabelas, etc.
const html = ` <!DOCTYPE html> <html> <head> <style> body { font-family: Arial; font-size: 12px; } h1 { text-align: center; color: #333; } table { width: 100%; border-collapse: collapse; } th { background: #333; color: white; padding: 8px; } td { border-bottom: 1px solid #ddd; padding: 6px; } </style> </head> <body> <h1>Relatório de Vendas</h1> <table> <tr><th>Produto</th><th>Qtd</th><th>Total</th></tr> <tr><td>Produto A</td><td>10</td><td>R$ 50,00</td></tr> <tr><td>Produto B</td><td>5</td><td>R$ 60,00</td></tr> </table> </body> </html>`; await iz.printHtml(null, html);
8. Impressão de Imagem
Envia uma imagem (PNG, JPG, BMP) em base64 para ser impressa.
A partir de um <canvas>
const canvas = document.getElementById("meuCanvas"); const base64 = canvas.toDataURL("image/png").split(",")[1]; await iz.printImage(null, base64, { fit: true });
A partir de um <input type="file">
const file = document.getElementById("inputImagem").files[0]; const reader = new FileReader(); reader.onload = async (e) => { const base64 = e.target.result.split(",")[1]; await iz.printImage("Impressora Laser", base64); }; reader.readAsDataURL(file);
9. Tratamento de erros
Todas as operações retornam Promises. Use try/catch para capturar erros.
try { await iz.connect(); } catch (error) { alert("IZPrint não encontrado. Verifique se está rodando."); return; } try { await iz.printRaw(null, "teste"); } catch (error) { if (error.message.includes("Não conectado")) { await iz.connect(); } else if (error.message.includes("Timeout")) { alert("Impressora não respondeu."); } else { alert("Erro: " + error.message); } }
Wrapper com retry
async function imprimirComRetry(fn, maxTentativas = 3) { for (let i = 0; i < maxTentativas; i++) { try { if (!iz.isConnected()) await iz.connect(); return await fn(); } catch (error) { console.warn(`Tentativa ${i + 1} falhou:`, error.message); if (i === maxTentativas - 1) throw error; await new Promise(r => setTimeout(r, 1000)); } } } // Uso await imprimirComRetry(() => iz.printRaw(null, "Teste"));
10. Protocolo WebSocket direto
Para integrar sem a biblioteca izprint.js (ex: backend Python, C#, Java, PHP, app mobile, etc).
ws://localhost:12345
Formato de requisição (JSON)
{
"id": "req_001",
"action": "nome_da_acao",
"params": { "chave": "valor" }
}
id— Identificador único da requisição (para correlacionar a resposta)action— Nome da ação a executarparams— Parâmetros da ação (objeto)
Tabela de ações
| Action | Params | Descrição |
|---|---|---|
| ping | — | Teste de conexão. Retorna { pong: true } |
| info | — | Informações do servidor (versão, OS) |
| printers | — | Lista todas as impressoras |
| default_printer | — | Nome da impressora padrão |
| print_raw | printer, data (base64) | Impressão RAW |
| print_pdf | printer, data (base64) | Impressão de PDF |
| print_html | printer, data (HTML) | Impressão de HTML |
| print_image | printer, data (base64) | Impressão de imagem |
Exemplo em Python
import asyncio, json, base64, websockets async def imprimir(): async with websockets.connect("ws://localhost:12345") as ws: # Listar impressoras await ws.send(json.dumps({ "id": "1", "action": "printers", "params": {} })) resp = json.loads(await ws.recv()) print("Impressoras:", resp["data"]["printers"]) # Imprimir RAW texto = base64.b64encode("Teste Python!\n".encode()).decode() await ws.send(json.dumps({ "id": "2", "action": "print_raw", "params": {"printer": None, "data": texto} })) resp = json.loads(await ws.recv()) print("Resultado:", resp) asyncio.run(imprimir())
Exemplo em C#
using System.Net.WebSockets; using System.Text; using System.Text.Json; var ws = new ClientWebSocket(); await ws.ConnectAsync( new Uri("ws://localhost:12345"), CancellationToken.None ); var request = JsonSerializer.Serialize(new { id = "1", action = "printers", @params = new { } }); var bytes = Encoding.UTF8.GetBytes(request); await ws.SendAsync(bytes, WebSocketMessageType.Text, true, CancellationToken.None); var buffer = new byte[4096]; var result = await ws.ReceiveAsync(buffer, CancellationToken.None); var response = Encoding.UTF8.GetString(buffer, 0, result.Count); Console.WriteLine(response);
Exemplo em PHP
$client = new \WebSocket\Client("ws://localhost:12345"); $client->send(json_encode([ "id" => "1", "action" => "printers", "params" => new stdClass() ])); $response = json_decode($client->receive(), true); print_r($response["data"]["printers"]);
11. Exemplos práticos completos
Cupom de venda (PDV)
async function imprimirCupom(venda) { const iz = new IZPrint(); try { await iz.connect(); const e = IZPrint.escpos(); // Cabeçalho e.init() .align("center") .bold(true).textSize(2, 2) .text(venda.empresa.nome).newLine() .textSize(1, 1).bold(false) .text(venda.empresa.endereco).newLine() .text(`CNPJ: ${venda.empresa.cnpj}`).newLine(2); // Itens e.align("left").separator("="); for (const item of venda.itens) { e.textColumns( `${item.qtd}x ${item.nome}`, `R$ ${item.total.toFixed(2)}` ); } // Total e.separator("-") .bold(true) .textColumns("TOTAL", `R$ ${venda.total.toFixed(2)}`) .bold(false) .separator("=") .newLine() .align("center") .text("Obrigado pela preferencia!") .newLine(4) .cut(); await iz.printRaw(venda.impressora || null, e.toBase64()); return { success: true }; } catch (error) { return { success: false, error: error.message }; } finally { iz.disconnect(); } }
Etiqueta de produto (Zebra ZPL)
async function imprimirEtiqueta(produto, impressora) { const iz = new IZPrint(); await iz.connect(); const zpl = ` ^XA ^CF0,30 ^FO50,30^FD${produto.nome}^FS ^FO50,70^CF0,20^FDCod: ${produto.codigo}^FS ^FO50,100^BY2^BCN,80,Y,N,N^FD${produto.ean}^FS ^FO50,210^CF0,40^FDR$ ${produto.preco.toFixed(2)}^FS ^XZ`; await iz.printRaw(impressora, zpl); iz.disconnect(); }
Comanda de cozinha (restaurante)
async function imprimirComanda(pedido) { const iz = new IZPrint(); await iz.connect(); const e = IZPrint.escpos(); e.init() .align("center") .bold(true).textSize(2, 2) .text("** COZINHA **").newLine() .textSize(1, 1) .text(`Mesa: ${pedido.mesa}`).newLine() .bold(false) .separator("="); for (const item of pedido.itens) { e.bold(true).textSize(1, 2) .text(`${item.qtd}x ${item.nome}`).newLine() .textSize(1, 1).bold(false); if (item.obs) { e.text(` OBS: ${item.obs}`).newLine(); } } e.separator("=").newLine(3).cut(); await iz.printRaw(pedido.impressoraCozinha, e.toBase64()); iz.disconnect(); }
Abrir gaveta de dinheiro
async function abrirGaveta(impressora) { const iz = new IZPrint(); await iz.connect(); const e = IZPrint.escpos(); e.init().openCashDrawer(0); // pin 0 ou 1 await iz.printRaw(impressora, e.toBase64()); iz.disconnect(); }
12. Integração com frameworks
React (Hook personalizado)
import { useEffect, useRef, useState } from 'react'; import { IZPrint } from '../lib/izprint.js'; function usePrinter() { const izRef = useRef(null); const [connected, setConnected] = useState(false); const [printers, setPrinters] = useState([]); useEffect(() => { const iz = new IZPrint(); izRef.current = iz; iz.onConnect = () => setConnected(true); iz.onDisconnect = () => setConnected(false); iz.connect() .then(() => iz.listPrinters()) .then(setPrinters) .catch(console.error); return () => iz.disconnect(); }, []); return { connected, printers, iz: izRef }; }
Vue 3 (Composition API)
<script setup> import { ref, onMounted, onUnmounted } from 'vue'; import { IZPrint } from '../lib/izprint.js'; const iz = new IZPrint(); const connected = ref(false); const printers = ref([]); iz.onConnect = () => { connected.value = true; }; iz.onDisconnect = () => { connected.value = false; }; onMounted(async () => { await iz.connect(); printers.value = await iz.listPrinters(); }); onUnmounted(() => iz.disconnect()); </script> <template> <p>{{ connected ? 'Conectado' : 'Desconectado' }}</p> </template>
Angular (Service)
import { Injectable, OnDestroy } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class PrinterService implements OnDestroy { private iz = new IZPrint(); connected$ = new BehaviorSubject<boolean>(false); printers$ = new BehaviorSubject<any[]>([]); constructor() { this.iz.onConnect = () => this.connected$.next(true); this.iz.onDisconnect = () => this.connected$.next(false); this.init(); } private async init() { await this.iz.connect(); const printers = await this.iz.listPrinters(); this.printers$.next(printers); } ngOnDestroy() { this.iz.disconnect(); } }
13. FAQ e Troubleshooting
Verifique se o
IZPrint.exe está rodando (ícone na bandeja do sistema). Verifique se a porta 12345 não está bloqueada pelo firewall ou em uso por outro programa.
Verifique se a impressora está instalada no Windows (Painel de Controle > Dispositivos e Impressoras). Use
iz.listPrinters() para ver o nome exato — deve ser idêntico ao que aparece no Windows.
Verifique se está usando comandos ESC/POS compatíveis com o modelo. Sempre chame
.init() antes de outros comandos. Verifique a largura (48 ou 42 caracteres) e ajuste width em separator() e textColumns().
O Windows precisa ter um leitor de PDF instalado (Adobe Reader, Foxit, etc.). O PDF é impresso via
ShellExecute, que usa o leitor padrão do sistema.
Porta personalizada
Se precisar usar outra porta, inicie o IZPrint com:
IZPrint.exe --port 9999
E no JavaScript:
const iz = new IZPrint({ port: 9999 });
Múltiplas impressões em sequência
// Manter uma única conexão aberta const iz = new IZPrint(); await iz.connect(); // Imprimir vários cupons for (const venda of vendas) { await imprimirCupom(iz, venda); } iz.disconnect();
Resumo rápido
// 1. Incluir izprint.js no HTML ou importar no módulo // 2. Conectar const iz = new IZPrint(); await iz.connect(); // 3. Listar impressoras const printers = await iz.listPrinters(); // 4. Imprimir (escolha o método) await iz.printRaw(null, "texto"); // RAW await iz.printRaw(null, escpos.toBase64()); // ESC/POS await iz.printPdf(null, pdfBase64); // PDF await iz.printHtml(null, "<h1>Oi</h1>"); // HTML await iz.printImage(null, imgBase64); // Imagem // 5. Desconectar iz.disconnect();