@mmachadosantos/nfe-danfe-pdf 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/README.md +719 -0
  2. package/lib/application/helpers/generate-pdf/fontes/Times New Roman Bold Italic.ttf +0 -0
  3. package/lib/application/helpers/generate-pdf/fontes/Times New Roman Bold.ttf +0 -0
  4. package/lib/application/helpers/generate-pdf/fontes/Times New Roman Italic.ttf +0 -0
  5. package/lib/application/helpers/generate-pdf/fontes/Times New Roman.ttf +0 -0
  6. package/lib/application/helpers/generate-pdf/fontes/barlow-condensed/BarlowCondensed-Black.ttf +0 -0
  7. package/lib/application/helpers/generate-pdf/fontes/barlow-condensed/BarlowCondensed-BlackItalic.ttf +0 -0
  8. package/lib/application/helpers/generate-pdf/fontes/barlow-condensed/BarlowCondensed-Bold.ttf +0 -0
  9. package/lib/application/helpers/generate-pdf/fontes/barlow-condensed/BarlowCondensed-BoldItalic.ttf +0 -0
  10. package/lib/application/helpers/generate-pdf/fontes/barlow-condensed/BarlowCondensed-ExtraBold.ttf +0 -0
  11. package/lib/application/helpers/generate-pdf/fontes/barlow-condensed/BarlowCondensed-ExtraBoldItalic.ttf +0 -0
  12. package/lib/application/helpers/generate-pdf/fontes/barlow-condensed/BarlowCondensed-ExtraLight.ttf +0 -0
  13. package/lib/application/helpers/generate-pdf/fontes/barlow-condensed/BarlowCondensed-ExtraLightItalic.ttf +0 -0
  14. package/lib/application/helpers/generate-pdf/fontes/barlow-condensed/BarlowCondensed-Italic.ttf +0 -0
  15. package/lib/application/helpers/generate-pdf/fontes/barlow-condensed/BarlowCondensed-Light.ttf +0 -0
  16. package/lib/application/helpers/generate-pdf/fontes/barlow-condensed/BarlowCondensed-LightItalic.ttf +0 -0
  17. package/lib/application/helpers/generate-pdf/fontes/barlow-condensed/BarlowCondensed-Medium.ttf +0 -0
  18. package/lib/application/helpers/generate-pdf/fontes/barlow-condensed/BarlowCondensed-MediumItalic.ttf +0 -0
  19. package/lib/application/helpers/generate-pdf/fontes/barlow-condensed/BarlowCondensed-Regular.ttf +0 -0
  20. package/lib/application/helpers/generate-pdf/fontes/barlow-condensed/BarlowCondensed-SemiBold.ttf +0 -0
  21. package/lib/application/helpers/generate-pdf/fontes/barlow-condensed/BarlowCondensed-SemiBoldItalic.ttf +0 -0
  22. package/lib/application/helpers/generate-pdf/fontes/barlow-condensed/BarlowCondensed-Thin.ttf +0 -0
  23. package/lib/application/helpers/generate-pdf/fontes/barlow-condensed/BarlowCondensed-ThinItalic.ttf +0 -0
  24. package/lib/application/helpers/generate-pdf/fontes/roboto-condensed/RobotoCondensed-Bold.ttf +0 -0
  25. package/lib/application/helpers/generate-pdf/fontes/roboto-condensed/RobotoCondensed-BoldItalic.ttf +0 -0
  26. package/lib/application/helpers/generate-pdf/fontes/roboto-condensed/RobotoCondensed-Italic.ttf +0 -0
  27. package/lib/application/helpers/generate-pdf/fontes/roboto-condensed/RobotoCondensed-Light.ttf +0 -0
  28. package/lib/application/helpers/generate-pdf/fontes/roboto-condensed/RobotoCondensed-LightItalic.ttf +0 -0
  29. package/lib/application/helpers/generate-pdf/fontes/roboto-condensed/RobotoCondensed-Regular.ttf +0 -0
  30. package/lib/application/helpers/generate-pdf/nfe/campo.d.ts +2 -0
  31. package/lib/application/helpers/generate-pdf/nfe/campo.js +15 -0
  32. package/lib/application/helpers/generate-pdf/nfe/cria-layout.d.ts +2 -0
  33. package/lib/application/helpers/generate-pdf/nfe/cria-layout.js +149 -0
  34. package/lib/application/helpers/generate-pdf/nfe/default.d.ts +23 -0
  35. package/lib/application/helpers/generate-pdf/nfe/default.js +26 -0
  36. package/lib/application/helpers/generate-pdf/nfe/gerar-itens.d.ts +2 -0
  37. package/lib/application/helpers/generate-pdf/nfe/gerar-itens.js +291 -0
  38. package/lib/application/helpers/generate-pdf/nfe/get-dados-adicionais.d.ts +2 -0
  39. package/lib/application/helpers/generate-pdf/nfe/get-dados-adicionais.js +269 -0
  40. package/lib/application/helpers/generate-pdf/nfe/get-dados-emitente.d.ts +2 -0
  41. package/lib/application/helpers/generate-pdf/nfe/get-dados-emitente.js +319 -0
  42. package/lib/application/helpers/generate-pdf/nfe/get-destinatario-remetente.d.ts +2 -0
  43. package/lib/application/helpers/generate-pdf/nfe/get-destinatario-remetente.js +154 -0
  44. package/lib/application/helpers/generate-pdf/nfe/get-fatura-duplicata.d.ts +2 -0
  45. package/lib/application/helpers/generate-pdf/nfe/get-fatura-duplicata.js +118 -0
  46. package/lib/application/helpers/generate-pdf/nfe/get-homologacao.d.ts +2 -0
  47. package/lib/application/helpers/generate-pdf/nfe/get-homologacao.js +36 -0
  48. package/lib/application/helpers/generate-pdf/nfe/get-imposto.d.ts +2 -0
  49. package/lib/application/helpers/generate-pdf/nfe/get-imposto.js +219 -0
  50. package/lib/application/helpers/generate-pdf/nfe/get-iss.d.ts +2 -0
  51. package/lib/application/helpers/generate-pdf/nfe/get-iss.js +73 -0
  52. package/lib/application/helpers/generate-pdf/nfe/get-menu-itens.d.ts +2 -0
  53. package/lib/application/helpers/generate-pdf/nfe/get-menu-itens.js +199 -0
  54. package/lib/application/helpers/generate-pdf/nfe/get-nota-cancelada.d.ts +2 -0
  55. package/lib/application/helpers/generate-pdf/nfe/get-nota-cancelada.js +16 -0
  56. package/lib/application/helpers/generate-pdf/nfe/get-recibo.d.ts +2 -0
  57. package/lib/application/helpers/generate-pdf/nfe/get-recibo.js +101 -0
  58. package/lib/application/helpers/generate-pdf/nfe/get-transporte.d.ts +2 -0
  59. package/lib/application/helpers/generate-pdf/nfe/get-transporte.js +179 -0
  60. package/lib/application/helpers/generate-pdf/nfe/italico.d.ts +2 -0
  61. package/lib/application/helpers/generate-pdf/nfe/italico.js +16 -0
  62. package/lib/application/helpers/generate-pdf/nfe/linha-horizontal-tracejada.d.ts +2 -0
  63. package/lib/application/helpers/generate-pdf/nfe/linha-horizontal-tracejada.js +7 -0
  64. package/lib/application/helpers/generate-pdf/nfe/linha-horizontal.d.ts +2 -0
  65. package/lib/application/helpers/generate-pdf/nfe/linha-horizontal.js +26 -0
  66. package/lib/application/helpers/generate-pdf/nfe/linha-vertical.d.ts +2 -0
  67. package/lib/application/helpers/generate-pdf/nfe/linha-vertical.js +14 -0
  68. package/lib/application/helpers/generate-pdf/nfe/load-fontes.d.ts +2 -0
  69. package/lib/application/helpers/generate-pdf/nfe/load-fontes.js +30 -0
  70. package/lib/application/helpers/generate-pdf/nfe/negrito.d.ts +2 -0
  71. package/lib/application/helpers/generate-pdf/nfe/negrito.js +16 -0
  72. package/lib/application/helpers/generate-pdf/nfe/normal.d.ts +2 -0
  73. package/lib/application/helpers/generate-pdf/nfe/normal.js +16 -0
  74. package/lib/application/helpers/generate-pdf/nfe/options-doc.d.ts +10 -0
  75. package/lib/application/helpers/generate-pdf/nfe/options-doc.js +14 -0
  76. package/lib/application/helpers/generate-pdf/nfe/secao.d.ts +2 -0
  77. package/lib/application/helpers/generate-pdf/nfe/secao.js +16 -0
  78. package/lib/application/helpers/generate-pdf/nfe/titulo.d.ts +2 -0
  79. package/lib/application/helpers/generate-pdf/nfe/titulo.js +17 -0
  80. package/lib/application/helpers/xml/deserialize.d.ts +2 -0
  81. package/lib/application/helpers/xml/deserialize.js +24 -0
  82. package/lib/application/helpers/xml/index.d.ts +1 -0
  83. package/lib/application/helpers/xml/index.js +17 -0
  84. package/lib/domain/use-cases/pdf/index.d.ts +2 -0
  85. package/lib/domain/use-cases/pdf/index.js +25 -0
  86. package/lib/domain/use-cases/pdf/pdf-NFCe.d.ts +2 -0
  87. package/lib/domain/use-cases/pdf/pdf-NFCe.js +687 -0
  88. package/lib/domain/use-cases/pdf/pdf-NFe.d.ts +2 -0
  89. package/lib/domain/use-cases/pdf/pdf-NFe.js +54 -0
  90. package/lib/domain/use-cases/utils/clean-html-entities.d.ts +2 -0
  91. package/lib/domain/use-cases/utils/clean-html-entities.js +45 -0
  92. package/lib/domain/use-cases/utils/current-date.d.ts +1 -0
  93. package/lib/domain/use-cases/utils/current-date.js +7 -0
  94. package/lib/domain/use-cases/utils/format-cnpj.d.ts +1 -0
  95. package/lib/domain/use-cases/utils/format-cnpj.js +8 -0
  96. package/lib/domain/use-cases/utils/format-cpf.d.ts +1 -0
  97. package/lib/domain/use-cases/utils/format-cpf.js +8 -0
  98. package/lib/domain/use-cases/utils/format-date-time.d.ts +1 -0
  99. package/lib/domain/use-cases/utils/format-date-time.js +10 -0
  100. package/lib/domain/use-cases/utils/format-date.d.ts +1 -0
  101. package/lib/domain/use-cases/utils/format-date.js +9 -0
  102. package/lib/domain/use-cases/utils/format-key.d.ts +1 -0
  103. package/lib/domain/use-cases/utils/format-key.js +6 -0
  104. package/lib/domain/use-cases/utils/format-number.d.ts +1 -0
  105. package/lib/domain/use-cases/utils/format-number.js +6 -0
  106. package/lib/domain/use-cases/utils/format-phone.d.ts +1 -0
  107. package/lib/domain/use-cases/utils/format-phone.js +20 -0
  108. package/lib/domain/use-cases/utils/format-plate.d.ts +1 -0
  109. package/lib/domain/use-cases/utils/format-plate.js +16 -0
  110. package/lib/domain/use-cases/utils/format-postal-code.d.ts +1 -0
  111. package/lib/domain/use-cases/utils/format-postal-code.js +8 -0
  112. package/lib/domain/use-cases/utils/format-protocol.d.ts +1 -0
  113. package/lib/domain/use-cases/utils/format-protocol.js +8 -0
  114. package/lib/domain/use-cases/utils/format-state-registration.d.ts +1 -0
  115. package/lib/domain/use-cases/utils/format-state-registration.js +152 -0
  116. package/lib/domain/use-cases/utils/format-time.d.ts +1 -0
  117. package/lib/domain/use-cases/utils/format-time.js +8 -0
  118. package/lib/domain/use-cases/utils/index.d.ts +15 -0
  119. package/lib/domain/use-cases/utils/index.js +31 -0
  120. package/lib/domain/use-cases/utils/return-font-size-carrier.d.ts +1 -0
  121. package/lib/domain/use-cases/utils/return-font-size-carrier.js +23 -0
  122. package/lib/index.d.ts +1 -0
  123. package/lib/index.js +5 -0
  124. package/lib/tsconfig.tsbuildinfo +1 -0
  125. package/lib/types/generate-pdf.d.ts +266 -0
  126. package/lib/types/generate-pdf.js +2 -0
  127. package/lib/types/index.d.ts +3 -0
  128. package/lib/types/index.js +19 -0
  129. package/lib/types/nfe-proc.d.ts +42 -0
  130. package/lib/types/nfe-proc.js +2 -0
  131. package/lib/types/schema.d.ts +876 -0
  132. package/lib/types/schema.js +2 -0
  133. package/lib/utils/index.d.ts +1 -0
  134. package/lib/utils/index.js +6 -0
  135. package/package.json +59 -0
package/README.md ADDED
@@ -0,0 +1,719 @@
1
+ # 🧾 NFe DANFE PDF
2
+
3
+ > **Biblioteca robusta e completa para geração de DANFE (NF-e e NFC-e) em PDF para aplicações Node.js**
4
+
5
+ [![NPM Version](https://img.shields.io/npm/v/nfe-danfe-pdf.svg)](https://www.npmjs.com/package/nfe-danfe-pdf)
6
+ [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
8
+
9
+ ## 🚀 **Funcionalidades Principais**
10
+
11
+ ### ✅ **Suporte Completo**
12
+
13
+ - **NF-e (Modelo 55)**: Documentos fiscais eletrônicos com layout profissional
14
+ - **NFC-e (Modelo 65)**: Cupom fiscal eletrônico otimizado
15
+ - **Conformidade 100%**: Atende às especificações técnicas da Receita Federal (MOC)
16
+ - **TypeScript Nativo**: Tipagem completa e IntelliSense
17
+
18
+ ### 🎨 **Recursos Avançados**
19
+
20
+ - **Layout Responsivo**: Adapta-se automaticamente ao conteúdo
21
+ - **Quebra Inteligente de Texto**: Processa informações complementares longas
22
+ - **Logos Personalizadas**: Suporte a imagens em diferentes formatos
23
+ - **Código de Barras**: Geração automática conforme padrões oficiais
24
+ - **QR Code**: Para NFC-e com validação automática
25
+ - **Múltiplas Páginas**: Suporte a documentos com muitos itens
26
+
27
+ ### 🛡️ **Qualidade e Conformidade**
28
+
29
+ - **Validação XML**: Parser robusto com tratamento de erros
30
+ - **Campos Obrigatórios**: Verificação automática de dados essenciais
31
+ - **Formatação Automática**: CNPJ, CPF, CEP, datas e valores monetários
32
+ - **Notas Canceladas**: Marcação visual clara para documentos cancelados
33
+ - **Homologação**: Marca d'água automática para ambiente de testes
34
+
35
+ ---
36
+
37
+ ## 📦 **Instalação**
38
+
39
+ ```bash
40
+ # NPM
41
+ npm install nfe-danfe-pdf
42
+
43
+ # Yarn
44
+ yarn add nfe-danfe-pdf
45
+
46
+ # PNPM
47
+ pnpm add nfe-danfe-pdf
48
+ ```
49
+
50
+ ---
51
+
52
+ ## 🎯 **Uso Básico**
53
+
54
+ ### **Exemplo Simples**
55
+
56
+ ```typescript
57
+ import { gerarPDF } from 'nfe-danfe-pdf';
58
+ import fs from 'fs';
59
+
60
+ async function main() {
61
+ try {
62
+ // Carregando XML da NFe
63
+ const xmlContent = fs.readFileSync('./nota-fiscal.xml', 'utf8');
64
+
65
+ // Gerando PDF
66
+ const pdfDoc = await gerarPDF(xmlContent);
67
+
68
+ // Salvando arquivo
69
+ const writeStream = fs.createWriteStream('./danfe.pdf');
70
+ pdfDoc.pipe(writeStream);
71
+
72
+ // Aguardar finalização do arquivo
73
+ await new Promise<void>((resolve, reject) => {
74
+ writeStream.on('finish', () => {
75
+ console.log('PDF gerado com sucesso!');
76
+ resolve();
77
+ });
78
+
79
+ writeStream.on('error', reject);
80
+ pdfDoc.on('error', reject);
81
+ });
82
+ } catch (error) {
83
+ console.error('Erro:', error);
84
+ }
85
+ }
86
+
87
+ main();
88
+ ```
89
+
90
+ ### **Exemplo Avançado**
91
+
92
+ ```typescript
93
+ import { gerarPDF } from 'nfe-danfe-pdf';
94
+ import fs from 'fs';
95
+
96
+ const xmlContent = fs.readFileSync('./nfe.xml', 'utf8');
97
+
98
+ // Opções personalizadas
99
+ const opcoes = {
100
+ pathLogo: './assets/logo-empresa.png', // Logo da empresa
101
+ cancelada: false, // Nota não cancelada
102
+ textoRodape: 'Meu Sistema Danfe' // Texto personalizado no rodapé
103
+ };
104
+
105
+ const pdfDoc = await gerarPDF(xmlContent, opcoes);
106
+
107
+ // Salvando com callback
108
+ pdfDoc.pipe(fs.createWriteStream('./danfe-personalizado.pdf'));
109
+ pdfDoc.on('end', () => {
110
+ console.log('✅ DANFE gerado com sucesso!');
111
+ });
112
+ pdfDoc.end();
113
+ ```
114
+
115
+ ---
116
+
117
+ ## ⚙️ **API Completa**
118
+
119
+ ### **`gerarPDF(xml, opcoes?)`**
120
+
121
+ **Parâmetros:**
122
+
123
+ - **`xml`** `string`: Conteúdo XML da NF-e/NFC-e
124
+ - **`opcoes`** `OpcoesPDF` _(opcional)_: Configurações personalizadas
125
+
126
+ **Retorna:** `Promise<PDFKit.PDFDocument>`
127
+
128
+ ### **Tipo `OpcoesPDF`**
129
+
130
+ ```typescript
131
+ type OpcoesPDF = {
132
+ pathLogo?: string; // Caminho para logo da empresa
133
+ cancelada?: boolean; // Marcar nota como cancelada
134
+ textoRodape?: string; // Texto personalizado no rodapé do documento
135
+ };
136
+ ```
137
+
138
+ #### **Detalhes dos Parâmetros:**
139
+
140
+ - **`pathLogo`**: Caminho para arquivo de imagem da logo da empresa (PNG, JPG, etc.)
141
+ - **`cancelada`**: Define se a nota deve ser marcada visualmente como cancelada
142
+ - **`textoRodape`**: Texto personalizado que aparece no rodapé direito do documento (ex: "Meu Sistema Danfe")
143
+
144
+ #### **Exemplo com Rodapé Personalizado:**
145
+
146
+ ```typescript
147
+ import { gerarPDF } from 'nfe-danfe-pdf';
148
+ import fs from 'fs';
149
+
150
+ const xmlContent = fs.readFileSync('./nfe.xml', 'utf8');
151
+
152
+ // Opções com texto personalizado no rodapé
153
+ const opcoes = {
154
+ pathLogo: './assets/logo-empresa.png',
155
+ cancelada: false,
156
+ textoRodape: 'Meu Sistema Danfe' // Texto que aparece no canto inferior direito
157
+ };
158
+
159
+ const pdfDoc = await gerarPDF(xmlContent, opcoes);
160
+ pdfDoc.pipe(fs.createWriteStream('./danfe-com-rodape.pdf'));
161
+ ```
162
+
163
+ **💡 Resultado Visual do Rodapé:**
164
+
165
+ ```
166
+ Impresso em 27/09/2025 às 15:30:45 Meu Sistema Danfe
167
+ ↑ (lado esquerdo) ↑ (lado direito)
168
+ ```
169
+
170
+ ---
171
+
172
+ ## 🎨 **Recursos Visuais**
173
+
174
+ ### **Layout Profissional**
175
+
176
+ - ✅ Cabeçalho com dados do emitente e logo
177
+ - ✅ Seções organizadas e bem delimitadas
178
+ - ✅ Tabela de itens com colunas alinhadas
179
+ - ✅ Informações fiscais destacadas
180
+ - ✅ Dados adicionais com altura dinâmica
181
+ - ✅ **Rodapé personalizado** com data/hora e texto customizável
182
+
183
+ ### **Formatações Automáticas**
184
+
185
+ - 📄 **CNPJ/CPF**: `12.345.678/0001-90` | `123.456.789-00`
186
+ - 📅 **Datas**: `26/09/2025 15:30:45`
187
+ - 💰 **Valores**: `R$ 1.234,56`
188
+ - 📮 **CEP**: `12345-678`
189
+ - 🔑 **Chave NFe**: `1234 5678 9012 3456 7890 1234 5678 9012 3456 7890 1234`
190
+
191
+ ### **Tratamento Inteligente**
192
+
193
+ - 📝 **Textos Longos**: Quebra automática em múltiplas linhas
194
+ - 🔄 **Altura Dinâmica**: Seções expandem conforme o conteúdo
195
+ - 🎯 **Alinhamentos**: Centro, esquerda, direita, justificado
196
+ - 🎨 **Fontes**: Times New Roman e Barlow Condensed incluídas
197
+
198
+ ---
199
+
200
+ ## 📋 **Campos Suportados**
201
+
202
+ ### **Identificação**
203
+
204
+ - ✅ Dados do emitente (razão social, CNPJ, endereço)
205
+ - ✅ Destinatário/remetente completo
206
+ - ✅ Dados da nota (número, série, data, chave)
207
+ - ✅ Protocolo de autorização
208
+
209
+ ### **Produtos/Serviços**
210
+
211
+ - ✅ Tabela completa de itens
212
+ - ✅ Código, descrição, quantidade, valor unitário
213
+ - ✅ Valores de ICMS, IPI, PIS, COFINS
214
+ - ✅ Classificação fiscal (NCM, CEST)
215
+
216
+ ### **Valores e Impostos**
217
+
218
+ - ✅ Totais da nota (produtos, impostos, desconto)
219
+ - ✅ Tributos aproximados (Lei da Transparência)
220
+ - ✅ Informações de ICMS, ISS, substituição tributária
221
+ - ✅ Modalidades de pagamento
222
+
223
+ ### **Informações Adicionais**
224
+
225
+ - ✅ Fatura e duplicatas (com vencimentos)
226
+ - ✅ Dados de transporte (transportadora, volumes)
227
+ - ✅ Informações complementares (campo livre)
228
+ - ✅ Informações do fisco
229
+
230
+ ---
231
+
232
+ ## 🔧 **Integração com Frameworks**
233
+
234
+ ### **Express.js**
235
+
236
+ ```typescript
237
+ import express from 'express';
238
+ import { gerarPDF } from 'nfe-danfe-pdf';
239
+
240
+ const app = express();
241
+
242
+ app.post('/gerar-danfe', async (req, res) => {
243
+ try {
244
+ const { xml, pathLogo, textoRodape } = req.body;
245
+ const pdfDoc = await gerarPDF(xml, { pathLogo, textoRodape });
246
+
247
+ res.setHeader('Content-Type', 'application/pdf');
248
+ res.setHeader('Content-Disposition', 'attachment; filename="danfe.pdf"');
249
+
250
+ pdfDoc.pipe(res);
251
+ pdfDoc.end();
252
+ } catch (error) {
253
+ res.status(500).json({ erro: 'Erro ao gerar DANFE' });
254
+ }
255
+ });
256
+ ```
257
+
258
+ ### **NestJS**
259
+
260
+ ```typescript
261
+ import { Controller, Post, Body, Res, HttpStatus } from '@nestjs/common';
262
+ import { Response } from 'express';
263
+ import { gerarPDF } from 'nfe-danfe-pdf';
264
+
265
+ @Controller('danfe')
266
+ export class DanfeController {
267
+ @Post('gerar')
268
+ async gerarDanfe(
269
+ @Body('xml') xml: string,
270
+ @Body('pathLogo') pathLogo?: string,
271
+ @Body('textoRodape') textoRodape?: string,
272
+ @Res() res: Response
273
+ ) {
274
+ try {
275
+ const pdfDoc = await gerarPDF(xml, { pathLogo, textoRodape });
276
+
277
+ res.setHeader('Content-Type', 'application/pdf');
278
+ pdfDoc.pipe(res);
279
+ pdfDoc.end();
280
+ } catch (error) {
281
+ res.status(HttpStatus.INTERNAL_SERVER_ERROR).json({ message: 'Erro ao gerar DANFE' });
282
+ }
283
+ }
284
+ }
285
+ ```
286
+
287
+ ---
288
+
289
+ ## 🌐 **Implementação em Projetos Front-end**
290
+
291
+ ### **React + TypeScript**
292
+
293
+ Para usar em projetos React, você precisa de um endpoint backend que gere o PDF:
294
+
295
+ ```tsx
296
+ import React, { useState } from 'react';
297
+ import axios from 'axios';
298
+
299
+ interface DanfeGeneratorProps {
300
+ xmlContent: string;
301
+ }
302
+
303
+ const DanfeGenerator: React.FC<DanfeGeneratorProps> = ({ xmlContent }) => {
304
+ const [isGenerating, setIsGenerating] = useState(false);
305
+
306
+ const gerarDanfe = async () => {
307
+ setIsGenerating(true);
308
+ try {
309
+ const response = await axios.post(
310
+ '/api/gerar-danfe',
311
+ {
312
+ xml: xmlContent,
313
+ pathLogo: '/assets/logo.png',
314
+ textoRodape: 'Meu Sistema Danfe'
315
+ },
316
+ {
317
+ responseType: 'blob' // Importante para receber PDF
318
+ }
319
+ );
320
+
321
+ // Criar URL do blob e fazer download
322
+ const blob = new Blob([response.data], { type: 'application/pdf' });
323
+ const url = window.URL.createObjectURL(blob);
324
+
325
+ // Criar link de download
326
+ const link = document.createElement('a');
327
+ link.href = url;
328
+ link.download = 'danfe.pdf';
329
+ document.body.appendChild(link);
330
+ link.click();
331
+
332
+ // Cleanup
333
+ document.body.removeChild(link);
334
+ window.URL.revokeObjectURL(url);
335
+ } catch (error) {
336
+ console.error('Erro ao gerar DANFE:', error);
337
+ alert('Erro ao gerar DANFE');
338
+ } finally {
339
+ setIsGenerating(false);
340
+ }
341
+ };
342
+
343
+ return (
344
+ <button
345
+ onClick={gerarDanfe}
346
+ disabled={isGenerating}
347
+ className="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 disabled:opacity-50"
348
+ >
349
+ {isGenerating ? 'Gerando...' : 'Gerar DANFE'}
350
+ </button>
351
+ );
352
+ };
353
+
354
+ export default DanfeGenerator;
355
+ ```
356
+
357
+ ### **Vue.js + TypeScript**
358
+
359
+ ```vue
360
+ <template>
361
+ <div>
362
+ <button
363
+ @click="gerarDanfe"
364
+ :disabled="isGenerating"
365
+ class="px-4 py-2 bg-green-500 text-white rounded hover:bg-green-600 disabled:opacity-50"
366
+ >
367
+ {{ isGenerating ? 'Gerando...' : 'Gerar DANFE' }}
368
+ </button>
369
+ </div>
370
+ </template>
371
+
372
+ <script setup lang="ts">
373
+ import { ref } from 'vue';
374
+ import axios from 'axios';
375
+
376
+ interface Props {
377
+ xmlContent: string;
378
+ logoPath?: string;
379
+ }
380
+
381
+ const props = defineProps<Props>();
382
+ const isGenerating = ref(false);
383
+
384
+ const gerarDanfe = async () => {
385
+ isGenerating.value = true;
386
+
387
+ try {
388
+ const response = await axios.post(
389
+ '/api/gerar-danfe',
390
+ {
391
+ xml: props.xmlContent,
392
+ pathLogo: props.logoPath
393
+ },
394
+ {
395
+ responseType: 'blob'
396
+ }
397
+ );
398
+
399
+ // Download do PDF
400
+ const blob = new Blob([response.data], { type: 'application/pdf' });
401
+ const url = URL.createObjectURL(blob);
402
+
403
+ const link = document.createElement('a');
404
+ link.href = url;
405
+ link.download = 'danfe.pdf';
406
+ link.click();
407
+
408
+ URL.revokeObjectURL(url);
409
+ } catch (error) {
410
+ console.error('Erro ao gerar DANFE:', error);
411
+ } finally {
412
+ isGenerating.value = false;
413
+ }
414
+ };
415
+ </script>
416
+ ```
417
+
418
+ ### **Angular + TypeScript**
419
+
420
+ **Serviço (danfe.service.ts):**
421
+
422
+ ```typescript
423
+ import { Injectable } from '@angular/core';
424
+ import { HttpClient, HttpHeaders } from '@angular/common/http';
425
+ import { Observable } from 'rxjs';
426
+
427
+ @Injectable({
428
+ providedIn: 'root'
429
+ })
430
+ export class DanfeService {
431
+ constructor(private http: HttpClient) {}
432
+
433
+ gerarDanfe(xmlContent: string, logoPath?: string): Observable<Blob> {
434
+ const headers = new HttpHeaders({
435
+ 'Content-Type': 'application/json'
436
+ });
437
+
438
+ return this.http.post(
439
+ '/api/gerar-danfe',
440
+ {
441
+ xml: xmlContent,
442
+ pathLogo: logoPath
443
+ },
444
+ {
445
+ headers,
446
+ responseType: 'blob'
447
+ }
448
+ );
449
+ }
450
+
451
+ downloadPdf(blob: Blob, filename: string = 'danfe.pdf'): void {
452
+ const url = window.URL.createObjectURL(blob);
453
+ const link = document.createElement('a');
454
+ link.href = url;
455
+ link.download = filename;
456
+ document.body.appendChild(link);
457
+ link.click();
458
+ document.body.removeChild(link);
459
+ window.URL.revokeObjectURL(url);
460
+ }
461
+ }
462
+ ```
463
+
464
+ **Componente (danfe.component.ts):**
465
+
466
+ ```typescript
467
+ import { Component } from '@angular/core';
468
+ import { DanfeService } from './danfe.service';
469
+
470
+ @Component({
471
+ selector: 'app-danfe',
472
+ template: `
473
+ <button
474
+ (click)="gerarDanfe()"
475
+ [disabled]="isGenerating"
476
+ class="px-4 py-2 bg-purple-500 text-white rounded hover:bg-purple-600 disabled:opacity-50"
477
+ >
478
+ {{ isGenerating ? 'Gerando...' : 'Gerar DANFE' }}
479
+ </button>
480
+ `
481
+ })
482
+ export class DanfeComponent {
483
+ isGenerating = false;
484
+
485
+ constructor(private danfeService: DanfeService) {}
486
+
487
+ gerarDanfe(): void {
488
+ this.isGenerating = true;
489
+
490
+ this.danfeService.gerarDanfe(this.xmlContent).subscribe({
491
+ next: (blob) => {
492
+ this.danfeService.downloadPdf(blob);
493
+ this.isGenerating = false;
494
+ },
495
+ error: (error) => {
496
+ console.error('Erro ao gerar DANFE:', error);
497
+ this.isGenerating = false;
498
+ }
499
+ });
500
+ }
501
+
502
+ // Propriedade que deve ser definida com o XML
503
+ xmlContent = ''; // Seu XML aqui
504
+ }
505
+ ```
506
+
507
+ ### **Next.js (App Router)**
508
+
509
+ **API Route (app/api/gerar-danfe/route.ts):**
510
+
511
+ ```typescript
512
+ import { gerarPDF } from 'nfe-danfe-pdf';
513
+ import { NextRequest, NextResponse } from 'next/server';
514
+
515
+ export async function POST(request: NextRequest) {
516
+ try {
517
+ const { xml, pathLogo } = await request.json();
518
+
519
+ const pdfDoc = await gerarPDF(xml, { pathLogo });
520
+
521
+ // Converter PDFKit document para Buffer
522
+ const chunks: Buffer[] = [];
523
+
524
+ return new Promise((resolve) => {
525
+ pdfDoc.on('data', (chunk) => chunks.push(chunk));
526
+ pdfDoc.on('end', () => {
527
+ const pdfBuffer = Buffer.concat(chunks);
528
+
529
+ resolve(
530
+ new NextResponse(pdfBuffer, {
531
+ status: 200,
532
+ headers: {
533
+ 'Content-Type': 'application/pdf',
534
+ 'Content-Disposition': 'attachment; filename="danfe.pdf"'
535
+ }
536
+ })
537
+ );
538
+ });
539
+ pdfDoc.end();
540
+ });
541
+ } catch (error) {
542
+ return NextResponse.json({ error: 'Erro ao gerar DANFE' }, { status: 500 });
543
+ }
544
+ }
545
+ ```
546
+
547
+ **Cliente (components/DanfeButton.tsx):**
548
+
549
+ ```tsx
550
+ 'use client';
551
+
552
+ import { useState } from 'react';
553
+
554
+ interface DanfeButtonProps {
555
+ xmlContent: string;
556
+ logoPath?: string;
557
+ }
558
+
559
+ export default function DanfeButton({ xmlContent, logoPath }: DanfeButtonProps) {
560
+ const [isGenerating, setIsGenerating] = useState(false);
561
+
562
+ const handleDownload = async () => {
563
+ setIsGenerating(true);
564
+
565
+ try {
566
+ const response = await fetch('/api/gerar-danfe', {
567
+ method: 'POST',
568
+ headers: {
569
+ 'Content-Type': 'application/json'
570
+ },
571
+ body: JSON.stringify({
572
+ xml: xmlContent,
573
+ pathLogo: logoPath,
574
+ textoRodape: 'Meu Sistema Danfe'
575
+ })
576
+ });
577
+ if (!response.ok) {
578
+ throw new Error('Erro ao gerar DANFE');
579
+ }
580
+
581
+ const blob = await response.blob();
582
+ const url = URL.createObjectURL(blob);
583
+
584
+ const link = document.createElement('a');
585
+ link.href = url;
586
+ link.download = 'danfe.pdf';
587
+ link.click();
588
+
589
+ URL.revokeObjectURL(url);
590
+ } catch (error) {
591
+ console.error('Erro:', error);
592
+ alert('Erro ao gerar DANFE');
593
+ } finally {
594
+ setIsGenerating(false);
595
+ }
596
+ };
597
+
598
+ return (
599
+ <button
600
+ onClick={handleDownload}
601
+ disabled={isGenerating}
602
+ className="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 disabled:opacity-50"
603
+ >
604
+ {isGenerating ? 'Gerando DANFE...' : 'Download DANFE'}
605
+ </button>
606
+ );
607
+ }
608
+ ```
609
+
610
+ ### **🔑 Pontos Importantes para Front-end**
611
+
612
+ #### **Segurança**
613
+
614
+ - ⚠️ **Nunca processe XMLs no cliente**: Sempre use um backend
615
+ - 🔐 **Validação**: Valide XMLs no servidor antes do processamento
616
+ - 🛡️ **Autenticação**: Proteja endpoints de geração de PDF
617
+
618
+ #### **UX/UI**
619
+
620
+ - ⏳ **Loading States**: Sempre mostre feedback durante geração
621
+ - 📱 **Responsivo**: Considere diferentes dispositivos
622
+ - 💾 **Download Automático**: Use `Content-Disposition: attachment`
623
+ - ❌ **Tratamento de Erros**: Exiba mensagens claras ao usuário
624
+
625
+ #### **Performance**
626
+
627
+ - 🚀 **Cache**: Considere cache de PDFs gerados recentemente
628
+ - 📊 **Limite**: Implemente rate limiting nos endpoints
629
+ - 🔄 **Timeout**: Configure timeouts adequados para requisições
630
+
631
+ ---
632
+
633
+ ## 🧪 **Requisitos e Compatibilidade**
634
+
635
+ ### **Node.js**
636
+
637
+ - ✅ **Versão Mínima**: Node.js 14+
638
+ - ✅ **Recomendado**: Node.js 18+ LTS
639
+ - ✅ **TypeScript**: 4.0+
640
+
641
+ ### **Formatos XML Suportados**
642
+
643
+ - ✅ **NFe Processada**: `<nfeProc>` (com protocolo)
644
+ - ✅ **NFCe Processada**: `<nfceProc>` (com protocolo)
645
+ - ✅ **Encoding**: UTF-8, ISO-8859-1
646
+ - ✅ **Versões**: Layout 4.00 (atual)
647
+
648
+ ### **Dependências Principais**
649
+
650
+ - **PDFKit**: Geração de PDF de alta qualidade
651
+ - **xml2js**: Parser XML robusto
652
+ - **date-fns**: Manipulação de datas
653
+ - **qrcode**: Geração de QR codes
654
+ - **bwip-js**: Códigos de barras
655
+
656
+ ---
657
+
658
+ ## 📊 **Performance**
659
+
660
+ - ⚡ **Velocidade**: ~500ms para NFe média (20 itens)
661
+ - 💾 **Memória**: ~10MB para documentos complexos
662
+ - 📄 **Tamanho**: PDFs otimizados (~50KB-200KB)
663
+ - 🔄 **Concorrência**: Suporte a múltiplas instâncias simultâneas
664
+
665
+ ---
666
+
667
+ ## 🛠️ **Desenvolvimento**
668
+
669
+ ### **Scripts Disponíveis**
670
+
671
+ ```bash
672
+ npm run build # Compilar TypeScript
673
+ npm run test # Executar testes
674
+ npm run prettier # Formatar código
675
+ npm run type # Verificar tipos
676
+ ```
677
+
678
+ ### **Estrutura do Projeto**
679
+
680
+ ```
681
+ src/
682
+ ├── domain/ # Lógica de negócio
683
+ ├── application/ # Casos de uso
684
+ ├── types/ # Definições TypeScript
685
+ └── utils/ # Utilitários
686
+ ```
687
+
688
+ ---
689
+
690
+ ## 📄 **Licença**
691
+
692
+ Este projeto está licenciado sob a **MIT License** - veja o arquivo [LICENSE](LICENSE) para detalhes.
693
+
694
+ ---
695
+
696
+ ## 🤝 **Contribuição**
697
+
698
+ Contribuições são bem-vindas! Por favor:
699
+
700
+ 1. Faça um fork do projeto
701
+ 2. Crie sua feature branch (`git checkout -b feature/nova-funcionalidade`)
702
+ 3. Commit suas mudanças (`git commit -am 'Adiciona nova funcionalidade'`)
703
+ 4. Push para a branch (`git push origin feature/nova-funcionalidade`)
704
+ 5. Abra um Pull Request
705
+
706
+ ---
707
+
708
+ ## 📞 **Suporte**
709
+
710
+ - 🐛 **Issues**: [GitHub Issues](https://github.com/flaviosoliver/nfe-danfe-pdf/issues)
711
+ - 📧 **Email**: [flavsoliver@gmail.com](mailto:flavsoliver@gmail.com)
712
+
713
+ ---
714
+
715
+ <div align="center">
716
+
717
+ **⭐ Se este projeto te ajudou, considere dar uma estrela no repositório! ⭐**
718
+
719
+ </div>