Como manter suas impressões idênticas em todos os devices com o printer_gateway
Impressão térmica é aquele tipo de dor que todo mundo que trabalha com PDV, delivery, fiscal e automação comercial já sentiu: você manda o mesmo cupom, mas ele sai diferente em cada dispositivo.
- Em uma impressora a fonte fica mais “gordinha”
- Em outra, o espaçamento muda
- Em outra, o SDK “interpreta” comandos de um jeito diferente
- E no final… o seu layout vira loteria 😅
Foi exatamente pra resolver isso que eu publiquei o printer_gateway: um package Flutter que transforma seu recibo em uma imagem única e padronizada, garantindo que o resultado impresso fique idêntico em qualquer device — independente de modelo, fabricante ou SDK.
O problema real: imprimir linha a linha não é confiável
A abordagem tradicional costuma ser:
- Montar strings linha a linha
- Mandar comandos (ESC/POS, SDK do fabricante, “printText”, etc.)
- Torcer pra ficar igual em todas as impressoras
Só que na prática, cada impressora tem suas particularidades:
- Fontes diferentes
- Margens e espaçamentos variando
- Renderização inconsistente do mesmo comando
- Comportamentos específicos por SDK
Ou seja: você até “imprime”, mas não garante consistência.
A solução: gerar uma imagem única do cupom e imprimir a imagem
O printer_gateway segue uma ideia simples e poderosa:
Em vez de imprimir comandos, você gera um layout, renderiza isso como imagem, e imprime a imagem.
Isso elimina a variabilidade. O cupom “vira” um bitmap, então a impressora só recebe pixels. Resultado:
✅ Mesmo layout em qualquer device
✅ Mesmo espaçamento, alinhamento e fonte renderizada
✅ Melhor previsibilidade em produção
✅ Adeus “essa impressora ficou diferente”
Live Demo (pra testar agora)
Você consegue ver o package funcionando em tempo real aqui:
A ideia é você colar um JSON e já visualizar como o recibo fica renderizado.
https://gist.github.com/brasizza/2f9063c95e39a38d57b88fb46d698d17
O que o package faz
O printer_gateway converte JSON → recibo formatado e permite exportar esse recibo em 4 formatos:
- JSON → Widget (preview no app)
- JSON → Image (Uint8List) (imagem única do cupom)
- JSON → POS printer (List) (quebra automática em partes)
- JSON → ESC/POS printer (List<img.Image>) (pronto pra raster)
Além disso, ele suporta:
- Texto com estilo (bold, italic, tamanho, alinhamento)
- Divisórias
- Tabelas (header + itens)
- Colunas (ex.: label/valor)
- QR Code
- Header/Footer com imagem
- Conteúdo sensível ofuscado automaticamente
Instalação
No seu pubspec.yaml:
dependencies:
printer_gateway: latestDepois
flutter pub get
Começando rápido
import 'package:printer_gateway/printer_gateway.dart';
final printerGateway = PrinterGateway(
jsonData: jsonString,
);
// Opcional: adicionar imagens no header e footer
printerGateway.addHeaderImage(headerImageBytes);
printerGateway.addFooterImage(footerImageBytes);1) Preview no app com toWidget()
Perfeito pra validar layout antes de imprimir.
Widget receiptWidget = printerGateway.toWidget(
maxWidth: 576,
margin: 10,
);
@override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: receiptWidget,
),
);
}
Dica: use isso como “modo designer” do seu cupom. Ajusta no JSON, vê no widget, só depois imprime.
2) Gerar a imagem única com toImage()
Esse é o coração do package: gerar uma imagem final idêntica em todo lugar.
Uint8List imageBytes = await printerGateway.toImage(
context,
maxWidth: 576,
margin: 0,
fixedRatio: 2.0,
);- fixedRatio maior = mais qualidade (ótimo pra impressão)
- você pode salvar em arquivo, enviar via API, cachear, etc.
3) POS printers com toPosPrinter()
Algumas impressoras têm limite de altura, então o package já resolve isso:
✅ gera imagem
✅ quebra automaticamente em “fatias”
✅ retorna List<Uint8List> pronta pra imprimir
List<Uint8List> parts = await printerGateway.toPosPrinter(
context,
maxHeight: 2000,
maxWidth: 384,
);
for (final part in parts) {
await yourPrinterService.printImage(part);
}4) ESC/POS com toEscPosPrinter()
Pra quem usa libs ESC/POS que trabalham com image package:
import 'package:image/image.dart' as img;
List<img.Image> rasterImages = await printerGateway.toEscPosPrinter(
context,
maxHeight: 2000,
maxWidth: 384,
);
for (final rasterImage in rasterImages) {
await escPosPrinter.printRaster(rasterImage);
}A “linguagem” do cupom: JSON
O layout do cupom é um array, onde cada item representa uma “linha”.
Texto simples
[
{
"line": {
"customization": {
"font_style": { "bold": true, "italic": false },
"font_size": 18,
"alignment": 1
},
"content": "MY TEXT HERE"
}
}
]alignment:
- 0 esquerda
- 1 centro
- 2 direita
- 3 justificado
Divisor (linha horizontal)
{ "line": { "divider": true } }
QR Code
{
"line": {
"qrcode": {
"size": 150,
"content": "https://example.com/receipt/12345",
"level": "L"
}
}
}
Espaçamento (linhas em branco)
{ "line": { "jump": 2 } }
Duas colunas (ótimo pra “Total / Valor”)
{
"line": {
"column": [
{ "row": { "customization": { "font_size": 12, "alignment": 0, "font_style": { "bold": false, "italic": false } }, "content": "Total", "size": null } },
{ "row": { "customization": { "font_size": 12, "alignment": 2, "font_style": { "bold": false, "italic": false } }, "content": "47,80", "size": 10 } }
]
}
}Tabela com header + itens (perfeito pra listagem de produtos)
O JSON suporta tabela com header e rows (igual no README), ideal pra cupons com muitos itens.
Conteúdo sensível? Ofusca automaticamente
Isso aqui é ouro pra segurança e LGPD: você manda o dado real em sensive_content e o package mascara automaticamente.
{
"line": {
"customization": { "font_size": 12, "alignment": 0, "font_style": { "bold": false, "italic": false } },
"content": "Card Number: ",
"sensive_content": "1234567890123456"
}
}Saída:
Card Number: 123**********56
Boas práticas (do mundo real)
- Largura:
- 58mm: maxWidth: 384
- 80mm: maxWidth: 576
- Qualidade: fixedRatio: 2.0 ou maior
- Cupons longos: prefira toPosPrinter() / toEscPosPrinter() (quebra automática)
- Workflow ideal:
- montar JSON
- validar com toWidget()
- imprimir via imagem
Links úteis
- Pub.dev: https://pub.dev/packages/printer_gateway
- Demo: https://printer.brasizza.com/
- GitHub: https://github.com/brasizza/printer_gateway
- Issues: https://github.com/brasizza/printer_gateway/issues


