Gera o PDF do DANFSe v2.0 a partir do XML da NFS-e Nacional, no mesmo leiaute que o portal nacional imprime.
Desde 15/07/2026 a API do ADN que devolvia o PDF está suspensa (NT 008 v1.01, item 1: a API "será sobrestada (suspensa) na data de 15 de julho de 2026"), e cada emissor passa a gerar o próprio DANFSe. Esta biblioteca lê o XML com a nfse, monta os campos e compõe o PDF em uma página, sem depender de serviço externo.
Só depende de nfse, typst e eqrcode.
Instalação
def deps do
[
{:nfse_danfse, "~> 0.1.0"}
]
endRequer Elixir 1.18 ou mais novo. O pacote typst traz o compilador como NIF pré-compilado, então não é preciso instalar Rust.
Exemplo
O DANFSe de uma nota do "Studio Ana", como voltou da Sefin ou do ADN:
xml = File.read!("nota-studio-ana.xml")
{:ok, pdf} = NfseDanfse.render(xml)
File.write!("danfse.pdf", pdf)A NFS-e não diz que foi cancelada, porque o cancelamento é um evento à parte. Quem chama informa a situação, e o PDF sai com a marca d'água:
{:ok, pdf} = NfseDanfse.render(xml, situation: :cancelled)Toda falha volta como {:error, %NfseDanfse.Error{}}, com kind :invalid_xml (o XML não é uma NFS-e legível), :invalid_option (opção desconhecida ou inválida) ou :render (a composição do PDF falhou).
Opções
| Opção | Valores | Efeito |
|---|---|---|
:situation | :cancelled, :replaced | Imprime a marca d'água "CANCELADA" ou "SUBSTITUÍDA", em corpo 72 pt como o portal. Sem a opção, não há marca. |
:fonts_dir | caminho de uma pasta | Usa as fontes reais da NT: Arial, Arial Bold e Microsoft Sans Serif. Cada uma é achada pelo nome gravado dentro dos arquivos da pasta, então servem os arquivos do macOS (Arial.ttf) e os do Windows (arial.ttf). Sem a opção, usa a Liberation Sans embutida. Uma pasta sem alguma das três fontes devolve {:error, %NfseDanfse.Error{kind: :invalid_option}}. Veja o guia Fontes. |
O que a biblioteca garante
- Segue a NT 008 v1.01 (SE/CGNFS-e, 30/06/2026). Onde o PDF do governo e a NT divergem, a biblioteca segue o PDF do governo, que é o que o contribuinte vê no portal. Por exemplo: o campo "Valor Líquido da NFS-e + IBS/CBS" de uma nota do Simples Nacional sai "R$ 0,00", como no portal; o QR Code codifica
https://www.nfse.gov.br/ConsultaPublica?tpc=1&chave=<chave>, sem a barra antes do?que o texto da NT traz; e a marca d'água tem 72 pt. - Em comparação com dois PDFs do portal, e com as fontes reais (Arial e Microsoft Sans Serif), a biblioteca difere em 0,008% dos pixels a 150 dpi, e toda palavra fica a até 0,014 pt da posição do governo.
- A página é sempre uma só (NT §2.2). A descrição do serviço e as informações complementares que passam do quadro são cortadas com "..." no fim.
- Os dados do cliente entram no PDF como dados, nunca como marcação: um nome com
#,*ou<aparece literal. Letras fora da Windows-1252 (como "ł", "ő" e emoji) são removidas, e um nome com elas sai sem elas.
Desempenho
Medido num notebook com Apple Silicon: cerca de 170 ms por nota simples e 230 ms por uma nota completa. O primeiro render leva cerca de 0,5 s, porque o Typst varre as fontes do sistema. O NIF do Typst guarda um só conjunto de fontes por vez, então alternar entre fonts_dir e as fontes embutidas no mesmo app faz a varredura de novo, cerca de 300 ms a cada troca.
Por que não há logo da empresa
Não existe opção para colocar a logo do emitente, e isso é de propósito. Três itens da NT 008 impedem a logo:
- O item 2.1 só permite imprimir o que consta do XML da NFS-e, e o XML não traz logo.
- O item 2.2.4 torna obrigatório o modelo do Anexo I, em que o canto esquerdo do cabeçalho é a logo da NFS-e.
- O item 2.3 lista as únicas supressões e modificações permitidas, e a logo da empresa não está entre elas.
Um DANFSe com a logo da empresa deixaria de ser o documento que a norma descreve. Por isso a biblioteca não aceita a opção, e um pedido nesse sentido não será atendido. A NT está em gov.br/nfse. Esse arquivo é a versão 1.0; a 1.01 (30/06/2026) mudou só a data de suspensão da API de geração do DANFSe, como diz o histórico de versões da própria NT.
Para quem contribui
A tarefa mix nfse_danfse.compare compara o PDF gerado com o PDF do governo para a mesma nota, por palavras (posição em pt) e por pixels (150 dpi). Ela existe só em desenvolvimento e exige o Poppler (pdftotext, pdftoppm) e o ImageMagick 7 (magick):
mix nfse_danfse.compare --xml nota.xml --reference governo.pdf --fonts-dir ~/fontes-da-nt
O XML e o PDF do portal usados na comparação ficam fora do repositório. Notas reais nunca entram nele: nem XML, nem PDF, nem snapshot. Os testes usam só o Studio Ana, com o CNPJ de teste 11222333000181 e a tomadora fictícia Ana Souza.
Guias
Licença
MIT. A Liberation Sans embutida segue a SIL Open Font License 1.1 (veja priv/fonts/LICENSE).