Como imprimir DANFEs e NFSe Nacional no Flutter usando um único package centralizado
Quem já precisou imprimir documentos fiscais em Flutter, principalmente em ambientes de PDV, POS, kiosks ou impressoras térmicas ESC/POS, sabe o quanto isso pode virar um pesadelo rapidamente.
Cada tipo de documento tem seu layout, cada município tem sua NFSe, cada impressora se comporta de um jeito… e quando você soma tudo isso, o código vira uma mistura difícil de manter.
Caso queiram ver um teste online e colocar seus xmls
https://danfe.brasizza.com
Pensando exatamente nesse cenário nasceu o package DANFE, que centraliza parse, normalização, renderização e impressão de documentos fiscais eletrônicos em Flutter, incluindo:
- DANFE (NFC-e, SAT e NFe)
- NFSe Nacional
- Conversão para buffer ESC/POS
- Renderização como Widget Flutter
- Geração de Imagem
- Possibilidade de layouts customizados
Tudo isso usando um único package, com uma API consistente.
Qual problema esse package resolve?
Antes de entrar no código, vale entender o problema real.
Normalmente, projetos que imprimem documentos fiscais sofrem com:
- Código duplicado para cada tipo de documento
- Diferenças entre SAT, NFC-e, NFe e NFSe
- Layouts amarrados à impressora
- Dificuldade de pré-visualizar o documento na tela
- Impressões inconsistentes entre modelos de POS
O objetivo do package DANFE é resolver isso criando uma camada única de normalização, onde o XML vira um objeto padronizado e, a partir dele, você escolhe como quer renderizar ou imprimir.
O que exatamente o package faz?
De forma resumida, o fluxo funciona assim:
- Você fornece um XML
- O package identifica o tipo do documento
- Normaliza tudo em um modelo único
- A partir desse modelo, você pode:
- Imprimir direto em ESC/POS
- Gerar Widget Flutter
- Gerar imagem
- Criar layouts customizados
Funcionalidades principais
- Parse automático de SAT, NFC-e e NFe
- Suporte a NFSe Nacional (Beta)
- Criação de buffer ESC/POS (List<int>)
- Conversão para Widget Flutter
- Conversão para imagem
- Layouts customizados
- Exemplo completo no projeto
Trabalhando com DANFE (NFC-e, SAT e NFe)
Parseando o XML
Tudo começa transformando o XML em um objeto Danfe.
import 'package:danfe/danfe.dart';
Danfe? danfe = DanfeParser.readFromString(xml);
O parser identifica automaticamente se o XML é SAT, NFC-e ou NFe e já normaliza os dados.
Gerando buffer ESC/POS para impressão
Aqui é onde o package começa a brilhar em ambientes de POS.
import 'package:danfe/danfe.dart';
import 'package:esc_pos_utils_plus/esc_pos_utils_plus.dart';
DanfePrinter danfePrinter = DanfePrinter(PaperSize.mm80);
List<int> dados = await danfePrinter.bufferDanfe(danfe);
Esse buffer já vem com um layout padrão pensado para impressoras térmicas.
Imprimindo em impressora de rede
final profile = await CapabilityProfile.load();
NetworkPrinter printer = NetworkPrinter(PaperSize.mm80, profile);
await printer.connect('192.168.5.29', port: 9100);
printer.rawBytes(dados);
printer.disconnect();
Simples, direto e reutilizável.
Visualizando o DANFE como Widget Flutter
Uma das grandes vantagens do package é não ficar preso à impressão.
Você pode transformar o DANFE em JSON normativo e renderizar direto na UI:
DanfePrinter danfePrinter = DanfePrinter(PaperSize.mm80);
String jsonDanfe = danfePrinter.normativeJsonDanfe(danfe);
ImageDanfe imageDanfe = ImageDanfe(
jsonData: jsonDanfe,
paperSize: DanfePaperSize.mm80,
);
Widget danfeWidget = await imageDanfe.toWidget(context);Isso permite:
- Preview antes de imprimir
- Compartilhamento
- Debug visual
- Uso em Flutter Web
Convertendo DANFE em imagem
Uint8List imageBytes = await imageDanfe.toImage(context);Perfeito para:
- Salvar no dispositivo
- Enviar para API
- Mostrar preview em tela cheia
- Imprimir como imagem
Imprimindo DANFE via imagem (ESC/POS)
Em alguns casos, imprimir como imagem gera resultados ainda mais consistentes entre impressoras.
List<Uint8List> imageParts = await imageDanfe.toEscPosPrinter(
context,
maxHeight: 2000,
maxWidth: 576,
margin: 0,
fixedRatio: 1.0,
);
Depois é só enviar cada parte para a impressora usando esc_pos_utils_plus.
Criando layouts personalizados
Se o layout padrão não atende seu negócio, você pode criar o seu próprio:
final CustomPrinter custom = CustomPrinter(PaperSize.mm80);
List<int> dados = await custom.layoutCustom(danfe);Isso é ideal para:
- Branding próprio
- Informações adicionais
- Ajustes específicos de PDV
Trabalhando com NFSe Nacional
O package também suporta NFSe Nacional, seguindo o padrão unificado.
⚠️ Importante: apenas NFSe Nacional é suportada.
O XML é identificado pelo campo versaoAplicativo contendo a palavra “Nacional”.
Parseando NFSe Nacional
Nfse? nfse = NfseParser.readFromString(xmlNfse);
Verificando rapidamente se o XML é NFSe Nacional
Map<String, String>? info = NfseParser.extractBasicInfo(xmlNfse);
if (info != null) {
print(info['tipo']); // NFSe Nacional
print(info['versao']);
print(info['numero']);
}
Imprimindo NFSe Nacional
NfsePrinter nfsePrinter = NfsePrinter(PaperSize.mm80);
List<int> dados = await nfsePrinter.bufferNfse(nfse);
E a impressão segue exatamente o mesmo fluxo do DANFE.
NFSe como Widget ou Imagem
O processo é idêntico ao DANFE, reaproveitando a mesma infraestrutura:
String jsonNfse = nfsePrinter.normativeJsonNfse(nfse);Por que centralizar tudo em um único package?
Em projetos reais de PDV, essa abordagem traz vantagens enormes:
- Menos código duplicado
- Menos bugs
- Layout consistente
- Facilidade de manutenção
- Possibilidade de evoluir o layout sem quebrar impressão
- Preview em tela antes de imprimir
É exatamente o tipo de solução que escala bem conforme o sistema cresce.


