bluetooth_pos_printer_utils 1.0.5
bluetooth_pos_printer_utils: ^1.0.5 copied to clipboard
This package is a fork of flutter_esc_pos_utils customized for bluetooth_pos_printer.
Bluetooth POS Printer Utils #
Classes base em Flutter/Dart para impressão em impressoras térmicas ESC/POS. Esta biblioteca é um fork turbinado da clássica flutter_esc_pos_utils, trazendo otimizações massivas de performance e um sistema revolucionário de renderização de imagem para recibos.
Esta é a biblioteca "base" responsável por gerar os comandos binários. Para enviar esses comandos para a impressora via Bluetooth, utilize o plugin de conexão em conjunto:
🚀 Os Dois Mundos de Impressão #
Esta biblioteca fornece duas classes principais para você gerar os seus recibos, dependendo da sua necessidade:
ImageGenerator(Recomendado ⭐): Constrói o recibo renderizando uma imagem de alta qualidade (inclusive com Widgets do Flutter). Acaba de vez com problemas de formatação, letras embaralhadas, e incompatibilidade deCodeTables.Generator(Tradicional): Envia comandos de texto puro (byte a byte) para a impressora. Útil para impressoras muito antigas ou se você precisa do máximo extremo de velocidade, mas exige configuração de CodeTables.
🌟 1. Imprimir como Imagem (ImageGenerator) #
A forma mais confiável e moderna de imprimir recibos complexos, caracteres internacionais (como €, ç, ã) e designs ricos em impressoras térmicas é renderizar o recibo inteiro como uma única imagem.
O ImageGenerator utiliza Isolates (processamento em background) e o protocolo nativo GS v 0 (Rasterização Ultra Rápida) da Epson. O resultado? Recibos complexos processados em menos de 50 milissegundos sem congelar a tela do seu App!
Como usar o ImageGenerator #
import 'package:bluetooth_pos_printer_utils/bluetooth_pos_printer_utils.dart';
import 'package:flutter/material.dart';
Future<List<int>> generateTicketAsImage() async {
// 1. Defina o tamanho do papel da sua impressora (58mm ou 80mm)
final profile = await CapabilityProfile.load();
final generator = ImageGenerator(PaperSize.mm58, profile);
// 2. Adicione Textos
generator.text('SUPERMERCADO', styles: const PosStyles(bold: true, align: PosAlign.center));
// 3. Adicione Linha Divisória
generator.hr();
// 4. Renderize Tabelas Alinhadas
generator.row([
PosColumn(text: 'Item 1 - Produto', width: 6),
PosColumn(text: '€ 10.00', width: 6, styles: const PosStyles(align: PosAlign.right)),
]);
// 5. Inserir WIDGETS DO FLUTTER! (A maior vantagem do ImageGenerator)
generator.widget(
Container(
padding: const EdgeInsets.all(8),
color: Colors.black, // Fundo preto inverte a cor no papel térmico
child: const Text('WIDGET CUSTOMIZADO', style: TextStyle(color: Colors.white)),
)
);
// 6. Códigos de Barras e QR Codes
generator.barcode(Barcode.code128('123456789'));
generator.qrcode('https://example.com');
// 7. Adicione Imagens com Dithering (Meio Tom) e Cache Automático
final data = await rootBundle.load('assets/logo.png');
generator.image(
data.buffer.asUint8List(),
width: 200,
halftone: true, // true = pontilhado de foto, false = Preto/Branco puro
);
// 8. Corte o papel
generator.cut();
// 9. Construa os bytes em background (Isolate)
// O parâmetro threshold (opcional, padrão 127) controla o quão escuro o recibo fica (0-255)
final bytes = await generator.buildImageBytes(threshold: 150);
return bytes;
}
Funcionalidades do ImageGenerator #
generator.text(): Suporta os estilos de alinhamento (align), negrito (bold), invertido (reverse) e tamanho 2x, 3x (height,width).generator.row(): Recebe uma lista dePosColumn(A soma das larguras das colunas deve ser 12).generator.hr(): Imprime uma linha horizontal tracejada (-).generator.image(): Possui cache automático! Se você imprimir a mesma logotipo em 50 recibos seguidos, ela só será processada (decode/dithering) no primeiro recibo! O argumentohalftone: trueaplica o algoritmo de Floyd-Steinberg para garantir que fotos e logos fiquem bonitas na impressora térmica.generator.widget(Widget widget): Renderiza qualquer componente do Flutter diretamente.generator.emptyLines(int n)/generator.feed(int n): Pula linhas.generator.cut(): Adiciona o comando de guilhotina (corte de papel).generator.buildImageBytes({int threshold = 127}): Gera os bytes do recibo. O parâmetrothreshold(0-255) controla o contraste: valores maiores deixam a impressão mais escura.
📜 2. Imprimir Textos (Método Tradicional: Generator) #
Se você quer mandar comandos nativos, byte a byte. Pode sofrer com problemas de caracteres acentuados dependendo da procedência da impressora chinesa, exigindo a injeção manual de CodeTables.
Como usar o Generator Tradicional #
List<int> testTicket() {
final profile = await CapabilityProfile.load();
final generator = Generator(PaperSize.mm80, profile);
List<int> bytes = [];
// Texto normal
bytes += generator.text('Teste de Impressão');
// Texto com acentos (pode exigir configuração de CodeTable)
bytes += generator.text('Atenção: Açaí €', styles: PosStyles(codeTable: PosCodeTable.westEur));
// Estilização Completa
bytes += generator.text('Negrito', styles: PosStyles(bold: true));
bytes += generator.text('Invertido', styles: PosStyles(reverse: true));
bytes += generator.text('Sublinhado', styles: PosStyles(underline: true));
bytes += generator.text('Centro', styles: PosStyles(align: PosAlign.center));
bytes += generator.text('Tamanho Duplo', styles: PosStyles(height: PosTextSize.size2, width: PosTextSize.size2));
// Imagens Nativas (Recomendado usar o comando GS v 0 que é o mais rápido)
// final img = decodeImage(bytes);
// bytes += generator.imageRaster(img);
// Gaveta de Dinheiro
bytes += generator.drawer();
// Bip da impressora
bytes += generator.beep();
bytes += generator.cut();
return bytes;
}
Funcionalidades Específicas do Generator #
Além das lógicas de layout (text, row, hr), o modo binário clássico suporta comandos eletrônicos de hardware que não fazem sentido no modo de imagem:
generator.drawer(): Abre a gaveta de dinheiro conectada à impressora via RJ11.generator.beep(): Faz a impressora apitar (útil para sistema de cozinha).generator.setGlobalCodeTable('CP1252'): Força a impressora a utilizar um mapa de caracteres específico para corrigir acentos (á, ç, õ). A disponibilidade dessas tabelas varia de impressora para impressora.
Resolvendo problemas de Caracteres Estranhos (Code Tables) #
Se os caracteres com acento estão saindo como "???" ou símbolos estranhos no modo Generator, você precisa forçar a CodeTable correta. Você pode procurar a CodeTable certa imprimindo a folha de teste da impressora:
// Exemplo: Configurando perfil para uma Xprinter XP-N160I
final profile = await CapabilityProfile.load('XP-N160I');
final generator = Generator(PaperSize.mm80, profile);
bytes += generator.setGlobalCodeTable('CP1252');
Dica: Se a dor de cabeça com acentos continuar, migre a sua impressão para o ImageGenerator.
🖨️ Testando o App de Exemplo (Example) #
Este pacote acompanha um aplicativo de exemplo completo (example/lib/main.dart) que simula a conexão com impressoras Bluetooth e imprime:
- Um recibo completo no formato tradicional de Bytes (onde você pode testar se a sua impressora suporta acentuação).
- Um recibo completo idêntico no formato de Imagem (onde você pode conferir a perfeição do alinhamento e suporte nativo ao Flutter).
Para testar:
cd example
flutter run
🤝 Como Contribuir #
- Adicionar Perfis: Tem uma impressora com quirks (defeitos) específicos? Adicione o perfil dela no arquivo
lib/resources/capabilities.json. - Issues e PRs: Sinta-se livre para abrir issues reportando bugs ou enviar Pull Requests com otimizações de código.