CFDI.BuildPdf 2.0.5

There is a newer version of this package available.
See the version list below for details.
dotnet add package CFDI.BuildPdf --version 2.0.5
                    
NuGet\Install-Package CFDI.BuildPdf -Version 2.0.5
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="CFDI.BuildPdf" Version="2.0.5" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="CFDI.BuildPdf" Version="2.0.5" />
                    
Directory.Packages.props
<PackageReference Include="CFDI.BuildPdf" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add CFDI.BuildPdf --version 2.0.5
                    
#r "nuget: CFDI.BuildPdf, 2.0.5"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package CFDI.BuildPdf@2.0.5
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=CFDI.BuildPdf&version=2.0.5
                    
Install as a Cake Addin
#tool nuget:?package=CFDI.BuildPdf&version=2.0.5
                    
Install as a Cake Tool

📦 CFDI.BuildPdf

NuGet NuGet Downloads License: MIT GitHub stars

Descripción general

CFDI.BuildPdf es una librería .NET 6+ que genera una representación impresa en PDF a partir de un XML CFDI 4.0. Detecta automáticamente el tipo de complemento y soporta actualmente:

  • Complemento Carta Porte 3.1
  • Complemento Nómina 1.2

Es cross-platform (Windows, Linux, macOS, contenedores) y no tiene dependencias nativas: usa QuestPDF como motor de renderizado y QRCoder para el código QR del timbre fiscal.

📥 Instalación

dotnet add package CFDI.BuildPdf

🚀 Características

  • ✔️ Soporte para CFDI 4.0 con complementos Carta Porte 3.1 y Nómina 1.2.
  • ✔️ Detección automática del tipo de complemento.
  • ✔️ Múltiples formatos de entrada: ruta de archivo, string, byte[] y Stream.
  • ✔️ Escritura directa a archivo o Stream de salida (ideal para respuestas HTTP).
  • ✔️ Opciones configurables: mostrar/ocultar mercancías, condiciones del contrato, addenda; logotipo en Base64; orientación portrait/landscape.
  • ✔️ Inyección de dependencias con Microsoft.Extensions.DependencyInjection.
  • ✔️ Integración opcional con ILogger para diagnóstico.
  • ✔️ Excepciones de dominio claras (CfdiXmlInvalidoException, CfdiComplementoNoSoportadoException).

📁 Estructura del PDF generado

  • Datos del emisor y receptor.
  • UUID, fecha de certificación y certificados.
  • Totales e impuestos del CFDI.
  • Addenda genérica (si aplica).
  • Complemento Carta Porte: ubicaciones, mercancías (detalle o resumen), autotransporte, seguros, remolques, figuras de transporte, página de condiciones del contrato.
  • Complemento Nómina: datos del empleado, percepciones, deducciones, otros pagos, incapacidades, totales.
  • QR y sellos digitales.

⚠️ Licencia QuestPDF (léeme antes de producción)

Esta librería usa QuestPDF, que tiene licencia dual:

  • Community (gratuita) — apta para la mayoría de proyectos open-source y empresas que cumplan los criterios de elegibilidad vigentes del proveedor.
  • Professional / Enterprise (de pago) — requerida por QuestPDF para el resto de organizaciones.

El consumidor de esta librería es responsable de elegir y adquirir la licencia correcta. Consulta los términos vigentes en https://www.questpdf.com/license/.

Por defecto, CFDI.BuildPdf declara Community. Para cambiarlo:

Con la fachada estática

using CFDI.BuildPdf.Abstractions;
using CFDI.BuildPdf.Service;

// Llamar una sola vez al iniciar el proceso, antes de generar cualquier PDF
CfdiPdf.ConfigureQuestPdfLicense(CfdiPdfLicenseType.Professional);

Con inyección de dependencias

builder.Services.AddCfdiPdfServices(
    configure: opts => opts.MostrarMercancias = true,
    licenseType: CfdiPdfLicenseType.Professional);

📚 Requisitos

  • .NET 6.0 o superior.
  • Sin dependencias nativas (no requiere wkhtmltopdf ni binarios de sistema).

🔵 Uso básico (fachada estática)

Desde una ruta de archivo

using CFDI.BuildPdf.Service;

var pdfBytes = await CfdiPdf.DesdeRutaAsync(@"C:\facturas\cfdi.xml");
await File.WriteAllBytesAsync("cfdi_output.pdf", pdfBytes);

Desde un string XML

var pdfBytes = await CfdiPdf.DesdeXmlStringAsync(xmlString);

Desde bytes

var pdfBytes = await CfdiPdf.DesdeXmlBytesAsync(xmlBytes);

Desde un Stream (por ejemplo, IFormFile en ASP.NET Core)

await using var stream = archivoXml.OpenReadStream();
var pdfBytes = await CfdiPdf.DesdeStreamAsync(stream);

Guardar directamente a archivo

await CfdiPdf.GuardarDesdeRutaAsync(
    rutaXml: @"C:\facturas\cfdi.xml",
    rutaPdfDestino: @"C:\facturas\cfdi.pdf");

Escribir en un Stream de salida (respuesta HTTP)

[HttpPost("generar-pdf")]
public async Task<IActionResult> GenerarPdf(IFormFile xml)
{
    Response.ContentType = "application/pdf";
    await using var xmlStream = xml.OpenReadStream();
    await CfdiPdf.EscribirEnStreamAsync(xmlStream, Response.Body);
    return new EmptyResult();
}

⚙️ Opciones de generación

var options = new CfdiPdfOptions
{
    MostrarMercancias = true,            // Carta Porte: mostrar detalle de mercancías
    MostrarCondicionesContrato = true,   // Carta Porte: incluir página de condiciones
    MostrarAddenda = true,               // Incluir sección de addenda
    LogoBase64 = logoBase64,             // Logo de la empresa (opcional)
    Orientacion = PdfOrientation.Portrait
};

var pdfBytes = await CfdiPdf.DesdeRutaAsync(rutaXml, options);

💉 Uso con inyección de dependencias

Registro de servicios

using CFDI.BuildPdf.Abstractions;
using CFDI.BuildPdf.Configuration;

builder.Services.AddCfdiPdfServices(
    configure: opts =>
    {
        opts.MostrarMercancias = true;
        opts.MostrarCondicionesContrato = true;
    },
    licenseType: CfdiPdfLicenseType.Community);

Consumo desde un servicio

using CFDI.BuildPdf.Abstractions;

public class FacturaService
{
    private readonly ICfdiPdfGenerator _generator;

    public FacturaService(ICfdiPdfGenerator generator)
    {
        _generator = generator;
    }

    public Task<byte[]> GenerarPdfAsync(string rutaXml)
        => _generator.GenerarDesdeRutaAsync(rutaXml);
}

🛑 Manejo de errores

Los métodos públicos lanzan excepciones de dominio específicas para facilitar el diagnóstico:

Excepción Cuándo ocurre
ArgumentNullException / ArgumentException Inputs nulos, vacíos o inválidos.
FileNotFoundException La ruta del XML no existe.
CfdiXmlInvalidoException El contenido no es un XML bien formado.
CfdiComplementoNoSoportadoException El CFDI no contiene Carta Porte 3.1 ni Nómina 1.2.
CfdiPdfException Clase base para cualquier error de dominio de la librería.
try
{
    var pdf = await CfdiPdf.DesdeRutaAsync(ruta);
}
catch (CfdiXmlInvalidoException ex)
{
    logger.LogWarning(ex, "XML no válido: {Mensaje}", ex.Message);
}
catch (CfdiComplementoNoSoportadoException ex)
{
    logger.LogWarning(ex, "Complemento no soportado: {Mensaje}", ex.Message);
}

📝 Licencia

Este proyecto está bajo licencia MIT. Recuerda que QuestPDF (dependencia interna) tiene su propia licencia dual — ver sección arriba.

👤 Autor

Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.0.8 110 4/29/2026
2.0.7 97 4/22/2026
2.0.6 104 4/19/2026
2.0.5 95 4/16/2026
2.0.4 116 4/12/2026
2.0.3 97 4/12/2026
2.0.2 96 4/12/2026
2.0.1 105 4/12/2026
2.0.0 103 4/12/2026
1.0.5 275 6/16/2025
1.0.4 253 5/1/2025
1.0.3 241 4/30/2025
1.0.2 239 4/30/2025
1.0.1 223 4/30/2025
1.0.0 218 4/30/2025