IZPrint

IZPrint

/ Manual de Integração
O que é: Servidor de impressão local (Windows) que roda na bandeja do sistema e expõe um WebSocket na porta 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:

html
<!-- Ú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:

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:

javascript
import { IZPrint, ESCPOSBuilder } from './lib/izprint.js';

2. Conexão com o servidor

Conexão básica

javascript
const iz = new IZPrint();
await iz.connect();

Com opções personalizadas

javascript
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

javascript
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

javascript
// 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

javascript
const printers = await iz.listPrinters();
console.log(printers);

Retorno:

json
[
    {
        "name": "EPSON TM-T20",
        "driver": "EPSON TM-T20 Receipt",
        "port": "USB001",
        "status": "READY",
        "isDefault": true,
        "isNetwork": false
    }
]

Status possíveis:

READY OFFLINE ERROR PAUSED PRINTING BUSY PAPER_OUT PAPER_JAM TONER_LOW DOOR_OPEN
javascript
// Apenas a impressora padrão
const defaultPrinter = await iz.getDefaultPrinter();
console.log(defaultPrinter); // "EPSON TM-T20"

Montar um <select> de impressoras

javascript
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

javascript
// 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

javascript
const base64Data = btoa("Hello World\n");
await iz.printRaw(null, base64Data);

Comandos ZPL (Zebra)

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

javascript
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).

javascript
const escpos = IZPrint.escpos();

Métodos disponíveis

MétodoParâmetrosDescrição
init()Inicializa/reseta a impressora. Sempre chamar primeiro.
text(str)stringAdiciona texto
newLine(n)number (padrão: 1)Adiciona n quebras de linha
feed(n)numberAlimentar 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)booleanAtivar/desativar negrito
underline(on)booleanAtivar/desativar sublinhado
textSize(w, h)1-8, 1-8Tamanho do texto. 1=normal, 2=dobro
separator(char, width)string, numberLinha separadora (padrão: "-", 48)
textColumns(esq, dir, width)string, string, numberTexto em 2 colunas
barcode(data, type)string, stringCódigo de barras (padrão: CODE128)
qrCode(data, size)string, numberQR Code (padrão: size 6)
openCashDrawer(pin)0 ou 1Abrir gaveta de dinheiro

Tipos de código de barras

UPC-A UPC-E EAN13 EAN8 CODE39 ITF CODABAR CODE128

Métodos de exportação

MétodoRetornoUso
toBase64()stringUsar com printRaw() — formato recomendado
toArray()number[]Array de bytes
toUint8Array()Uint8ArrayBuffer binário

Exemplo completo — Cupom

javascript
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">

javascript
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

javascript
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.

javascript
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>

javascript
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">

javascript
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.

javascript
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

javascript
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).

Endereço: ws://localhost:12345

Formato de requisição (JSON)

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 executar
  • params — Parâmetros da ação (objeto)

Tabela de ações

ActionParamsDescrição
pingTeste de conexão. Retorna { pong: true }
infoInformações do servidor (versão, OS)
printersLista todas as impressoras
default_printerNome da impressora padrão
print_rawprinter, data (base64)Impressão RAW
print_pdfprinter, data (base64)Impressão de PDF
print_htmlprinter, data (HTML)Impressão de HTML
print_imageprinter, data (base64)Impressão de imagem

Exemplo em Python

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#

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

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)

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

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

javascript
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

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

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

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

typescript
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

"Falha ao conectar ao IZPrint"
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.
"Impressora não encontrada"
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.
"Dados não imprimem corretamente na térmica"
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().
"PDF não imprime"
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:

shell
IZPrint.exe --port 9999

E no JavaScript:

javascript
const iz = new IZPrint({ port: 9999 });
Dica: Você também pode alterar a porta diretamente pelo menu da bandeja do sistema (clique com botão direito no ícone IZPrint > Alterar Porta).

Múltiplas impressões em sequência

javascript
// 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

javascript
// 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();