Saltar al pie de página
USANDO IRONPDF

Cómo crear una API PDF en .NET Usando IronPDF

Al trabajar con aplicaciones modernas, los desarrolladores de .NET como usted pueden encontrarse necesitando construir un servicio centralizado de generación de PDF. Ya sea que esté generando facturas, informes, certificados o contratos, tener una API dedicada de PDF para .NET puede ser beneficioso para gestionar de manera eficiente archivos PDF. ¿Entonces, cómo puede mejorar sus tareas de generación de PDF? Lo hace proporcionando consistencia, mantenibilidad y escalabilidad en sus aplicaciones de escritorio y web. Nunca antes ha sido tan fácil gestionar el contenido de documentos, las páginas PDF y los campos de formularios PDF.

En este tutorial, aprenderá cómo construir una API de PDF lista para producción utilizando ASP.NET Core e IronPDF, una potente biblioteca PDF para .NET. Crearemos endpoints RESTful que pueden generar PDF a partir de HTML, fusionar documentos, añadir marcas de agua y manejar diversos escenarios de generación de PDF en su API web.

¿Por qué crear una API PDF dedicada?

Antes de sumergirnos en el código, entendamos por qué tiene sentido crear una API dedicada de PDF:

  • Lógica Centralizada: Toda la lógica de generación de PDF vive en un solo lugar, lo que facilita el mantenimiento y las actualizaciones
  • Arquitectura de Microservicios: Perfecta para arquitecturas orientadas a servicios donde diferentes aplicaciones necesitan capacidades de PDF
  • Optimización del Rendimiento: Más fácil de escalar y optimizar un servicio dedicado para archivos PDF grandes, múltiples páginas y datos dinámicos.
  • Agnóstico al Lenguaje: Cualquier aplicación cliente puede consumir la API independientemente del lenguaje de programación
  • Resultado Consistente: Garantiza que todos los documentos PDF en su organización mantengan un diseño de documento consistente, formato de párrafo y contenido PDF.

¿Listo para empezar a construir? Descargue la prueba gratuita de IronPDF y siga este tutorial para crear archivos PDF programáticamente en sus proyectos de .NET Framework.

IronPDF: La biblioteca PDF .NET completa

IronPDF destaca como la principal biblioteca de PDF para desarrolladores de .NET, ofreciendo un conjunto integral de características que hacen que la generación de PDF en proyectos API web sea sencilla y confiable. Está construida sobre un motor de renderizado de Chrome, lo que garantiza conversión HTML a PDF con precisión de píxel, a menudo en solo unas pocas líneas de código. Hace todo esto manteniendo todos los estilos, ejecución de JavaScript y diseños responsivos.

Las capacidades clave que hacen que IronPDF sea ideal para el desarrollo de API de PDF para .NET:

  • Renderizado Basado en Chrome: Aprovecha el motor de renderizado de Google Chrome para convertir documentos PDF a partir de contenido HTML con precisión, con soporte completo para imágenes integradas y otros recursos web
  • Conjunto de Características Ricas: Soporta la edición de documentos nuevos y existentes con firmas digitales, formularios PDF, anotaciones, cifrado, compresión y más
  • Crear Documentos PDF Seguros: Gestione contenido PDF sensible con cifrado, firmas digitales y protección de documentos.
  • Múltiples Formatos de Entrada: Use HTML, URLs, imágenes y documentos de Office para crear documentos PDF
  • Manipulación Avanzada: Fusione páginas PDF, divida documentos, aplique marcas de agua, cree formularios PDF interactivos y manipule archivos PDF programáticamente.
  • Soporte Multiplataforma: Funciona en Windows, Linux, macOS, Docker y plataformas en la nube
  • Rendimiento Optimizado: Operaciones asincrónicas, gestión eficiente de memoria y renderizado rápido

¿Cómo configurar su proyecto de API de documentos PDF?

Comencemos creando un nuevo proyecto API web de ASP.NET Core e instalando los paquetes necesarios.

Prerrequisitos

  • SDK de .NET 6.0 o posterior
  • Visual Studio 2022 or Visual Studio Code
  • Postman o una herramienta similar de prueba de API para probar su API REST de PDF

Creación del proyecto

Primero, cree el proyecto en el cual construiremos nuestra herramienta de generación de PDF.

dotnet new webapi -n PdfApiService
cd PdfApiService

Instalación de IronPDF

El siguiente paso es añadir IronPDF a su proyecto a través de NuGet:

dotnet add package IronPdf

O, utilizando el Consola del Administrador de Paquetes de NuGet en Visual Studio:

Install-Package IronPdf

Estructura del proyecto

Un aspecto esencial del desarrollo en C# es mantener una carpeta del proyecto limpia y bien estructurada. Por ejemplo:

¿Cómo crear su primer punto final PDF?

Construyamos un endpoint simple que convierta HTML al formato PDF. Primero, cree la interfaz del servicio y la implementación:

Creación del servicio PDF

Primero, añadiremos lo siguiente a nuestro archivo IPdfService.cs:

public interface IPdfService
{
    byte[] GeneratePdfFromHtml(string htmlContent);
    byte[] GeneratePdfFromUrl(string url);
}
public interface IPdfService
{
    byte[] GeneratePdfFromHtml(string htmlContent);
    byte[] GeneratePdfFromUrl(string url);
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

En el archivo PdfService.cs, añadiremos esto:

using IronPdf;
public class PdfService : IPdfService
{
    private readonly ChromePdfRenderer _renderer;
    public PdfService()
    {
        _renderer = new ChromePdfRenderer();
        // Configure rendering options for optimal PDF generation in .NET
        _renderer.RenderingOptions.MarginTop = 20;
        _renderer.RenderingOptions.MarginBottom = 20;
        _renderer.RenderingOptions.PrintHtmlBackgrounds = true;
    }
    public byte[] GeneratePdfFromHtml(string htmlContent)
    {
        // Generate PDF from HTML using the .NET PDF API
        var pdf = _renderer.RenderHtmlAsPdf(htmlContent);
        return pdf.BinaryData;
    }
    public byte[] GeneratePdfFromUrl(string url)
    {
        // Convert URL to PDF in the REST API
        var pdf = _renderer.RenderUrlAsPdf(url);
        return pdf.BinaryData;
    }
}
using IronPdf;
public class PdfService : IPdfService
{
    private readonly ChromePdfRenderer _renderer;
    public PdfService()
    {
        _renderer = new ChromePdfRenderer();
        // Configure rendering options for optimal PDF generation in .NET
        _renderer.RenderingOptions.MarginTop = 20;
        _renderer.RenderingOptions.MarginBottom = 20;
        _renderer.RenderingOptions.PrintHtmlBackgrounds = true;
    }
    public byte[] GeneratePdfFromHtml(string htmlContent)
    {
        // Generate PDF from HTML using the .NET PDF API
        var pdf = _renderer.RenderHtmlAsPdf(htmlContent);
        return pdf.BinaryData;
    }
    public byte[] GeneratePdfFromUrl(string url)
    {
        // Convert URL to PDF in the REST API
        var pdf = _renderer.RenderUrlAsPdf(url);
        return pdf.BinaryData;
    }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

El servicio de PDF maneja el proceso central de convertir HTML en PDF. Utilizando el ChromePdfRenderer de IronPDF, esta clase está configurada con valores predeterminados razonables como márgenes de página y renderizado de fondo para producir un documento final pulido.

Cuando el controlador pasa HTML sin procesar, el servicio utiliza IronPDF para renderizarlo en un PDF de calidad profesional y devuelve el resultado como datos byte, listos para descargar. Además, también puede manejar páginas web enteras convirtiendo una URL directamente en un PDF.

Creación del controlador

Ahora es el momento de crear el controlador para nuestra API. Esto proporcionará un endpoint API capaz de generar archivos PDF desde HTML. Luego podrá descargar y guardar documentos PDF en su sistema para un mayor uso o compartición.

// Controllers/PdfController.cs
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/[controller]")]
public class PdfController : ControllerBase
{
    private readonly IPdfService _pdfService;
    public PdfController(IPdfService pdfService)
    {
        _pdfService = pdfService;
    }
    [HttpPost("html-to-pdf")]
    public IActionResult ConvertHtmlToPdf([FromBody] HtmlRequest request)
    {
        try
        {
            var pdfBytes = _pdfService.GeneratePdfFromHtml(request.HtmlContent);
            // Return as downloadable file
            return File(pdfBytes, "application/pdf", "document.pdf");
        }
        catch (Exception ex)
        {
            return BadRequest($"Error generating PDF: {ex.Message}");
        }
    }
}
// Controllers/PdfController.cs
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/[controller]")]
public class PdfController : ControllerBase
{
    private readonly IPdfService _pdfService;
    public PdfController(IPdfService pdfService)
    {
        _pdfService = pdfService;
    }
    [HttpPost("html-to-pdf")]
    public IActionResult ConvertHtmlToPdf([FromBody] HtmlRequest request)
    {
        try
        {
            var pdfBytes = _pdfService.GeneratePdfFromHtml(request.HtmlContent);
            // Return as downloadable file
            return File(pdfBytes, "application/pdf", "document.pdf");
        }
        catch (Exception ex)
        {
            return BadRequest($"Error generating PDF: {ex.Message}");
        }
    }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

Luego, en el archivo HtmlRequest.cs, añadiremos esto:

// Models/HtmlRequest.cs
public class HtmlRequest
{
    public string HtmlContent { get; set; }
    public string FileName { get; set; } = "document.pdf";
}
// Models/HtmlRequest.cs
public class HtmlRequest
{
    public string HtmlContent { get; set; }
    public string FileName { get; set; } = "document.pdf";
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

En el primer archivo, configuramos un endpoint API sencillo que convierte HTML en un PDF descargable. Cuando alguien envía contenido HTML a la ruta api/pdf/html-to-pdf con una simple solicitud POST, el PdfController le pasa el trabajo de convertirlo en un PDF a un servicio dedicado.

Una vez que se crea el PDF, el controlador se lo devuelve al usuario como un archivo listo para descargar. La solicitud está estructurada utilizando el modelo HtmlRequest, que lleva tanto el HTML sin procesar como un nombre de archivo opcional para el documento final. En resumen, esta configuración facilita que los clientes envíen HTML y reciban instantáneamente un PDF pulido a cambio.

Registro de servicios

Actualice su Program.cs para registrar el servicio de PDF:

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
// Register PDF service
builder.Services.AddSingleton<IPdfService, PdfService>();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.MapControllers();
app.Run();
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
// Register PDF service
builder.Services.AddSingleton<IPdfService, PdfService>();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.MapControllers();
app.Run();
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

¿Cómo manejar diferentes tipos de respuesta?

Su API debería soportar diferentes formas de devolver PDFs en función de las necesidades del cliente:

[HttpPost("generate")]
 public IActionResult GeneratePdf([FromBody] PdfRequest request)
 {
     var pdfBytes = _pdfService.GeneratePdfFromHtml(request.HtmlContent);
     switch (request.ResponseType?.ToLower())
     {
         case "base64":
             return Ok(new
             {
                 data = Convert.ToBase64String(pdfBytes),
                 filename = request.FileName
             });
         case "inline":
             return File(pdfBytes, "application/pdf");
         default: // download
             return File(pdfBytes, "application/pdf", request.FileName);
     }
 }
[HttpPost("generate")]
 public IActionResult GeneratePdf([FromBody] PdfRequest request)
 {
     var pdfBytes = _pdfService.GeneratePdfFromHtml(request.HtmlContent);
     switch (request.ResponseType?.ToLower())
     {
         case "base64":
             return Ok(new
             {
                 data = Convert.ToBase64String(pdfBytes),
                 filename = request.FileName
             });
         case "inline":
             return File(pdfBytes, "application/pdf");
         default: // download
             return File(pdfBytes, "application/pdf", request.FileName);
     }
 }
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

Aquí, hemos añadido un endpoint de generación de PDF más flexible al controlador. En lugar de siempre forzar una descarga de archivo, el método GeneratePdf permite al cliente elegir cómo quieren que se devuelva el resultado. Esta opción ofrece flexibilidad, permitiendo que los PDFs se muestren en varios formatos: como archivo descargable, directamente en el navegador o codificado como una cadena Base64 para uso fácil en APIs.

La solicitud está definida por el modelo PdfRequest, que se basa en el anterior HtmlRequest y añade una opción ResponseType. En resumen, esto les da a los usuarios más control sobre cómo reciben sus PDFs, haciendo que la API sea más versátil y fácil de usar.

Ahora, cuando ejecutamos nuestro programa, veremos este resultado en Swagger.

¡Cómo crear una API de PDF para .NET utilizando IronPDF: Figura 4 - Swagger UI

¿Cómo implementar operaciones PDF comunes?

Ampliemos nuestro servicio para manejar varios escenarios de generación de PDF:

Conversión de URL a PDF

[HttpPost("url-to-pdf")]
public async Task<IActionResult> ConvertUrlToPdf([FromBody] UrlRequest request)
{
    try
    {
        var pdfBytes = await Task.Run(() => 
            _pdfService.GeneratePdfFromUrl(request.Url));
        return File(pdfBytes, "application/pdf", 
            $"{request.FileName ?? "website"}.pdf");
    }
    catch (Exception ex)
    {
        return BadRequest($"Failed to convert URL: {ex.Message}");
    }
}
public class UrlRequest
{
    public string Url { get; set; }
    public string FileName { get; set; }
}
[HttpPost("url-to-pdf")]
public async Task<IActionResult> ConvertUrlToPdf([FromBody] UrlRequest request)
{
    try
    {
        var pdfBytes = await Task.Run(() => 
            _pdfService.GeneratePdfFromUrl(request.Url));
        return File(pdfBytes, "application/pdf", 
            $"{request.FileName ?? "website"}.pdf");
    }
    catch (Exception ex)
    {
        return BadRequest($"Failed to convert URL: {ex.Message}");
    }
}
public class UrlRequest
{
    public string Url { get; set; }
    public string FileName { get; set; }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

Este endpoint permite a los clientes enviar una URL y obtener un PDF listo para descargar de esa página web. Cuando llega una solicitud POST /api/pdf/url-to-pdf, el controlador utiliza _pdfService para convertir la URL dada en bytes de PDF en segundo plano, luego los devuelve como una descarga de archivo. Si algo sale mal durante la conversión, responde de manera elegante con un mensaje de error claro.

Probemos usando la URL "https://www.apple.com/nz" y probemos la solicitud POST. A continuación se muestra el resultado que obtuvimos.

Resultado

¡Cómo crear una API de PDF para .NET utilizando IronPDF: Figura 5 - Salida de PDF de URL

Añadir marcas de agua personalizadas

public byte[] AddWatermarkFromFile(string filePath, string watermarkText)
{
    // Load PDF directly from file
    var pdf = PdfDocument.FromFile(filePath);
    pdf.ApplyWatermark(
        $"<h1 style='color:red;font-size:72px;'>{watermarkText}</h1>",
        75,
        IronPdf.Editing.VerticalAlignment.Middle,
        IronPdf.Editing.HorizontalAlignment.Center
    );
    return pdf.BinaryData;
}
public byte[] AddWatermarkFromFile(string filePath, string watermarkText)
{
    // Load PDF directly from file
    var pdf = PdfDocument.FromFile(filePath);
    pdf.ApplyWatermark(
        $"<h1 style='color:red;font-size:72px;'>{watermarkText}</h1>",
        75,
        IronPdf.Editing.VerticalAlignment.Middle,
        IronPdf.Editing.HorizontalAlignment.Center
    );
    return pdf.BinaryData;
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

Aquí, solo estamos cargando manualmente un archivo local para propósitos de prueba. Sin embargo, puede ajustar esto para que su API de PDF genere un documento PDF y luego aplique una marca de agua personalizada con facilidad.

Salida de la marca de agua

¡Cómo crear una API de PDF para .NET utilizando IronPDF: Figura 6 - Salida de marca de agua del ejemplo de código anterior

Cómo añadir datos dinámicos con plantillas

Para aplicaciones del mundo real, a menudo necesitará generar PDFs a partir de plantillas con datos dinámicos:

[HttpPost("from-template")]
public IActionResult GenerateFromTemplate([FromBody] TemplateRequest request)
{
    // Simple template replacement
    var html = request.Template;
    foreach (var item in request.Data)
    {
        html = html.Replace($"{{{{{item.Key}}}}}", item.Value);
    }
    var pdfBytes = _pdfService.GeneratePdfFromHtml(html);
    return File(pdfBytes, "application/pdf", request.FileName);
}
public class TemplateRequest
{
    public string Template { get; set; }
    public Dictionary<string, string> Data { get; set; }
    public string FileName { get; set; } = "document.pdf";
}
[HttpPost("from-template")]
public IActionResult GenerateFromTemplate([FromBody] TemplateRequest request)
{
    // Simple template replacement
    var html = request.Template;
    foreach (var item in request.Data)
    {
        html = html.Replace($"{{{{{item.Key}}}}}", item.Value);
    }
    var pdfBytes = _pdfService.GeneratePdfFromHtml(html);
    return File(pdfBytes, "application/pdf", request.FileName);
}
public class TemplateRequest
{
    public string Template { get; set; }
    public Dictionary<string, string> Data { get; set; }
    public string FileName { get; set; } = "document.pdf";
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

Para escenarios de plantillas más avanzados con Razor, Handlebars u otros motores, consulte la documentación de HTML a PDF de IronPDF. También puede explorar la conversión de CSHTML a PDF para aplicaciones MVC y Razor a PDF para aplicaciones Blazor.

¿Cómo optimizar el rendimiento?

Al construir una API de PDF de producción, el rendimiento es crucial. Aquí hay estrategias clave de optimización:

Operaciones asíncronas

Al construir proyectos que involucren el uso de operaciones de I/O, es prudente utilizar la codificación asincrónica. Esto es especialmente útil si su contenido PDF proviene de recursos externos como:

  • Descargando páginas HTML (RenderUrlAsPdf)
  • Recuperando imágenes, CSS o fuentes a través de HTTP
  • Leyendo/escribiendo archivos en disco o almacenamiento en la nube

Estas operaciones pueden entonces bloquear un hilo, pero el uso de async evita que su hilo API espere inactivo.

Ejemplo:

public async Task<byte[]> GeneratePdfFromHtmlAsync(string htmlContent)
{
    return await Task.Run(() => 
    {
        var pdf = _renderer.RenderHtmlAsPdf(htmlContent);
        return pdf.BinaryData;
    });
}
public async Task<byte[]> GeneratePdfFromHtmlAsync(string htmlContent)
{
    return await Task.Run(() => 
    {
        var pdf = _renderer.RenderHtmlAsPdf(htmlContent);
        return pdf.BinaryData;
    });
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

Opciones de renderización

Configure IronPDF para un rendimiento óptimo:

_renderer.RenderingOptions.EnableJavaScript = false; // If JS not needed
_renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Print;
_renderer.RenderingOptions.RenderDelay = 0; // Remove if no JS
_renderer.RenderingOptions.Timeout = 30; // Set reasonable timeout
_renderer.RenderingOptions.EnableJavaScript = false; // If JS not needed
_renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Print;
_renderer.RenderingOptions.RenderDelay = 0; // Remove if no JS
_renderer.RenderingOptions.Timeout = 30; // Set reasonable timeout
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

¿Cómo proteger su API PDF?

La seguridad es esencial para cualquier API de producción. Aquí hay un enfoque simple de autenticación con clave API:

// Middleware/ApiKeyMiddleware.cs
public class ApiKeyMiddleware
{
    private readonly RequestDelegate _next;
    private const string ApiKeyHeader = "X-API-Key";
    public ApiKeyMiddleware(RequestDelegate next)
    {
        _next = next;
    }
    public async Task InvokeAsync(HttpContext context)
    {
        if (!context.Request.Headers.TryGetValue(ApiKeyHeader, out var apiKey))
        {
            context.Response.StatusCode = 401;
            await context.Response.WriteAsync("API Key required");
            return;
        }
        // Validate API key (in production, check against database)
        var validApiKey = context.RequestServices
            .GetRequiredService<IConfiguration>()["ApiKey"];
        if (apiKey != validApiKey)
        {
            context.Response.StatusCode = 403;
            await context.Response.WriteAsync("Invalid API Key");
            return;
        }
        await _next(context);
    }
}
// In Program.cs
app.UseMiddleware<ApiKeyMiddleware>();
// Middleware/ApiKeyMiddleware.cs
public class ApiKeyMiddleware
{
    private readonly RequestDelegate _next;
    private const string ApiKeyHeader = "X-API-Key";
    public ApiKeyMiddleware(RequestDelegate next)
    {
        _next = next;
    }
    public async Task InvokeAsync(HttpContext context)
    {
        if (!context.Request.Headers.TryGetValue(ApiKeyHeader, out var apiKey))
        {
            context.Response.StatusCode = 401;
            await context.Response.WriteAsync("API Key required");
            return;
        }
        // Validate API key (in production, check against database)
        var validApiKey = context.RequestServices
            .GetRequiredService<IConfiguration>()["ApiKey"];
        if (apiKey != validApiKey)
        {
            context.Response.StatusCode = 403;
            await context.Response.WriteAsync("Invalid API Key");
            return;
        }
        await _next(context);
    }
}
// In Program.cs
app.UseMiddleware<ApiKeyMiddleware>();
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

Para escenarios de autenticación más avanzados, considere:

Ejemplo del mundo real: API de generación de facturas

Construyamos un endpoint práctico de generación de facturas que demuestre una implementación completa. Este ejemplo muestra cómo una API de PDF de producción para .NET puede generar facturas profesionales con datos dinámicos.

Empiece con IronPDF ahora.
green arrow pointer

Primero, crearemos un nuevo archivo en nuestra carpeta de Modelos. Aquí, he llamado al mío Invoice.cs. Luego, añada el siguiente código a su nuevo archivo.

public class Invoice
{
    public string InvoiceNumber { get; set; }
    public DateTime Date { get; set; }
    public string CustomerName { get; set; }
    public string CustomerAddress { get; set; }
    public List<InvoiceItem> Items { get; set; }
    public decimal Tax { get; set; }
}
public class InvoiceItem
{
    public string Description { get; set; }
    public int Quantity { get; set; }
    public decimal UnitPrice { get; set; }
    public decimal Total => Quantity * UnitPrice;
}
public class Invoice
{
    public string InvoiceNumber { get; set; }
    public DateTime Date { get; set; }
    public string CustomerName { get; set; }
    public string CustomerAddress { get; set; }
    public List<InvoiceItem> Items { get; set; }
    public decimal Tax { get; set; }
}
public class InvoiceItem
{
    public string Description { get; set; }
    public int Quantity { get; set; }
    public decimal UnitPrice { get; set; }
    public decimal Total => Quantity * UnitPrice;
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

Luego, necesitaremos crear un nuevo archivo de servicio para nuestro generador de facturas. En su carpeta de Servicios, añada el siguiente código. Por mi parte, hice un nuevo archivo llamado InvoiceService.cs. Este código manejará el estilo y diseño de nuestro archivo PDF de Factura.

public class InvoiceService
{
    private readonly ChromePdfRenderer _renderer;
    public InvoiceService()
    {
        _renderer = new ChromePdfRenderer();
        _renderer.RenderingOptions.MarginTop = 10;
        _renderer.RenderingOptions.MarginBottom = 10;
        _renderer.RenderingOptions.PrintHtmlBackgrounds = true;
    }
    public byte[] GenerateInvoice(Invoice invoice)
{
    var html = BuildInvoiceHtml(invoice);
    // Add footer with page numbers
    _renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
    {
        MaxHeight = 15,
        HtmlFragment = "<center><i>{page} of {total-pages}</i></center>",
        DrawDividerLine = true
    };
    var pdf = _renderer.RenderHtmlAsPdf(html);
    return pdf.BinaryData;
}
    private string BuildInvoiceHtml(Invoice invoice)
    {
        var subtotal = invoice.Items.Sum(i => i.Total);
        var taxAmount = subtotal * (invoice.Tax / 100);
        var total = subtotal + taxAmount;
        var itemsHtml = string.Join("", invoice.Items.Select(item => 
            $@"<tr>
                <td>{item.Description}</td>
                <td class='text-center'>{item.Quantity}</td>
                <td class='text-right'>${item.UnitPrice:F2}</td>
                <td class='text-right'>${item.Total:F2}</td>
            </tr>"));
        return $@"
        <!DOCTYPE html>
        <html>
        <head>
            <style>
                body {{ font-family: Arial, sans-serif; }}
                .invoice-header {{ 
                    background-color: #f8f9fa; 
                    padding: 20px; 
                    margin-bottom: 20px; 
                }}
                table {{ 
                    width: 100%; 
                    border-collapse: collapse; 
                }}
                th, td {{ 
                    padding: 10px; 
                    border-bottom: 1px solid #ddd; 
                }}
                th {{ 
                    background-color: #007bff; 
                    color: white; 
                }}
                .text-right {{ text-align: right; }}
                .text-center {{ text-align: center; }}
                .total-section {{ 
                    margin-top: 20px; 
                    text-align: right; 
                }}
            </style>
        </head>
        <body>
            <div class='invoice-header'>
                <h1>Invoice #{invoice.InvoiceNumber}</h1>
                <p>Date: {invoice.Date:yyyy-MM-dd}</p>
            </div>   
            <div>
                <h3>Bill To:</h3>
                <p>{invoice.CustomerName}<br/>{invoice.CustomerAddress}</p>
            </div>    
            <table>
                <thead>
                    <tr>
                        <th>Description</th>
                        <th>Quantity</th>
                        <th>Unit Price</th>
                        <th>Total</th>
                    </tr>
                </thead>
                <tbody>
                    {itemsHtml}
                </tbody>
            </table>
            <div class='total-section'>
                <p>Subtotal: ${subtotal:F2}</p>
                <p>Tax ({invoice.Tax}%): ${taxAmount:F2}</p>
                <h3>Total: ${total:F2}</h3>
            </div>
        </body>
        </html>";
    }
}
public class InvoiceService
{
    private readonly ChromePdfRenderer _renderer;
    public InvoiceService()
    {
        _renderer = new ChromePdfRenderer();
        _renderer.RenderingOptions.MarginTop = 10;
        _renderer.RenderingOptions.MarginBottom = 10;
        _renderer.RenderingOptions.PrintHtmlBackgrounds = true;
    }
    public byte[] GenerateInvoice(Invoice invoice)
{
    var html = BuildInvoiceHtml(invoice);
    // Add footer with page numbers
    _renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
    {
        MaxHeight = 15,
        HtmlFragment = "<center><i>{page} of {total-pages}</i></center>",
        DrawDividerLine = true
    };
    var pdf = _renderer.RenderHtmlAsPdf(html);
    return pdf.BinaryData;
}
    private string BuildInvoiceHtml(Invoice invoice)
    {
        var subtotal = invoice.Items.Sum(i => i.Total);
        var taxAmount = subtotal * (invoice.Tax / 100);
        var total = subtotal + taxAmount;
        var itemsHtml = string.Join("", invoice.Items.Select(item => 
            $@"<tr>
                <td>{item.Description}</td>
                <td class='text-center'>{item.Quantity}</td>
                <td class='text-right'>${item.UnitPrice:F2}</td>
                <td class='text-right'>${item.Total:F2}</td>
            </tr>"));
        return $@"
        <!DOCTYPE html>
        <html>
        <head>
            <style>
                body {{ font-family: Arial, sans-serif; }}
                .invoice-header {{ 
                    background-color: #f8f9fa; 
                    padding: 20px; 
                    margin-bottom: 20px; 
                }}
                table {{ 
                    width: 100%; 
                    border-collapse: collapse; 
                }}
                th, td {{ 
                    padding: 10px; 
                    border-bottom: 1px solid #ddd; 
                }}
                th {{ 
                    background-color: #007bff; 
                    color: white; 
                }}
                .text-right {{ text-align: right; }}
                .text-center {{ text-align: center; }}
                .total-section {{ 
                    margin-top: 20px; 
                    text-align: right; 
                }}
            </style>
        </head>
        <body>
            <div class='invoice-header'>
                <h1>Invoice #{invoice.InvoiceNumber}</h1>
                <p>Date: {invoice.Date:yyyy-MM-dd}</p>
            </div>   
            <div>
                <h3>Bill To:</h3>
                <p>{invoice.CustomerName}<br/>{invoice.CustomerAddress}</p>
            </div>    
            <table>
                <thead>
                    <tr>
                        <th>Description</th>
                        <th>Quantity</th>
                        <th>Unit Price</th>
                        <th>Total</th>
                    </tr>
                </thead>
                <tbody>
                    {itemsHtml}
                </tbody>
            </table>
            <div class='total-section'>
                <p>Subtotal: ${subtotal:F2}</p>
                <p>Tax ({invoice.Tax}%): ${taxAmount:F2}</p>
                <h3>Total: ${total:F2}</h3>
            </div>
        </body>
        </html>";
    }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

Finalmente, necesitará crear un nuevo Controlador para poder acceder y crear una nueva factura utilizando la API.

[ApiController]
[Route("api/[controller]")]
public class InvoiceController : ControllerBase
{
    private readonly InvoiceService _invoiceService;
    public InvoiceController(InvoiceService invoiceService)
    {
        _invoiceService = invoiceService;
    }
    [HttpPost("generate")]
    public IActionResult GenerateInvoice([FromBody] Invoice invoice)
    {
        try
        {
            var pdfBytes = _invoiceService.GenerateInvoice(invoice);
            var fileName = $"Invoice_{invoice.InvoiceNumber}.pdf";
            return File(pdfBytes, "application/pdf", fileName);
        }
        catch (Exception ex)
        {
            return StatusCode(500, $"Error generating invoice: {ex.Message}");
        }
    }
}
[ApiController]
[Route("api/[controller]")]
public class InvoiceController : ControllerBase
{
    private readonly InvoiceService _invoiceService;
    public InvoiceController(InvoiceService invoiceService)
    {
        _invoiceService = invoiceService;
    }
    [HttpPost("generate")]
    public IActionResult GenerateInvoice([FromBody] Invoice invoice)
    {
        try
        {
            var pdfBytes = _invoiceService.GenerateInvoice(invoice);
            var fileName = $"Invoice_{invoice.InvoiceNumber}.pdf";
            return File(pdfBytes, "application/pdf", fileName);
        }
        catch (Exception ex)
        {
            return StatusCode(500, $"Error generating invoice: {ex.Message}");
        }
    }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

Facturación

¡Cómo crear una API de PDF para .NET utilizando IronPDF: Figura 7 - Salida de Factura PDF

Consideraciones sobre el despliegue de contenedores

Aunque este tutorial se enfoca en el desarrollo local, aquí hay una breve descripción de cómo contenerizar su API de PDF:

Dockerfile básico

FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["PdfApiService.csproj", "."]
RUN dotnet restore
COPY . .
RUN dotnet build -c Release -o /app/build
FROM build AS publish
RUN dotnet publish -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
# IronPDF requires additional dependencies on Linux
RUN apt-get update && apt-get install -y \
    libgdiplus \
    libc6-dev \
    libx11-dev \
    && rm -rf /var/lib/apt/lists/*     
ENTRYPOINT ["dotnet", "PdfApiService.dll"]
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["PdfApiService.csproj", "."]
RUN dotnet restore
COPY . .
RUN dotnet build -c Release -o /app/build
FROM build AS publish
RUN dotnet publish -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
# IronPDF requires additional dependencies on Linux
RUN apt-get update && apt-get install -y \
    libgdiplus \
    libc6-dev \
    libx11-dev \
    && rm -rf /var/lib/apt/lists/*     
ENTRYPOINT ["dotnet", "PdfApiService.dll"]
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

Para guías de despliegue detalladas para su API de PDF de .NET, vea:

Mejores prácticas en la gestión de errores

Para un programa más tolerante a fallos, las mejores prácticas son implementar un manejador de errores global para respuestas de error consistentes, como a continuación:

// Middleware/ErrorHandlingMiddleware.cs
public class ErrorHandlingMiddleware
{
    private readonly RequestDelegate _next;
    public ErrorHandlingMiddleware(RequestDelegate next)
    {
        _next = next;
    }
    public async Task InvokeAsync(HttpContext context)
    {
        try
        {
            await _next(context);
        }
        catch (Exception ex)
        {
            await HandleExceptionAsync(context, ex);
        }
    }
    private static async Task HandleExceptionAsync(HttpContext context, Exception ex)
    {
        context.Response.ContentType = "application/json";
        context.Response.StatusCode = 500;
        var response = new
        {
            error = "An error occurred processing your request",
            message = ex.Message
        };
        await context.Response.WriteAsync(JsonSerializer.Serialize(response));
    }
}
// Middleware/ErrorHandlingMiddleware.cs
public class ErrorHandlingMiddleware
{
    private readonly RequestDelegate _next;
    public ErrorHandlingMiddleware(RequestDelegate next)
    {
        _next = next;
    }
    public async Task InvokeAsync(HttpContext context)
    {
        try
        {
            await _next(context);
        }
        catch (Exception ex)
        {
            await HandleExceptionAsync(context, ex);
        }
    }
    private static async Task HandleExceptionAsync(HttpContext context, Exception ex)
    {
        context.Response.ContentType = "application/json";
        context.Response.StatusCode = 500;
        var response = new
        {
            error = "An error occurred processing your request",
            message = ex.Message
        };
        await context.Response.WriteAsync(JsonSerializer.Serialize(response));
    }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

Para escenarios específicos de solución de problemas de IronPDF, consulte la guía de solución de problemas de IronPDF.

Conclusión

Ahora ha construido una API robusta de PDF para .NET usando ASP.NET Core e IronPDF que puede manejar varios escenarios de generación de documentos. Esta API REST proporciona una base sólida para operaciones centralizadas de PDF en sus aplicaciones.

Conclusiones clave:

  • IronPDF hace que la generación de PDF en proyectos API web sea sencilla con su renderizado basado en Chrome
  • Puede ajustar fácilmente su API web para editar documentos PDF existentes con las herramientas avanzadas de edición de IronPDF
  • Los principios de diseño RESTful garantizan que su API de PDF sea intuitiva y mantenible
  • El manejo de errores adecuado y las medidas de seguridad son esenciales para la producción
  • La optimización del rendimiento a través de operaciones asincrónicas y almacenamiento en caché mejora la escalabilidad
  • Tendrá soporte para aplicaciones de escritorio y web con soluciones de documentos escalables

IronPDF permite a los desarrolladores crear documentos PDF, guardar archivos PDF y convertir HTML de manera eficiente, convirtiéndolo en la esencial API de documentos PDF para aplicaciones modernas de .NET Framework.

Siguientes pasos

¿Listo para implementar IronPDF en su API de PDF de producción para .NET? Aquí están sus próximas acciones:

  1. Comience su prueba gratuita - Pruebe IronPDF con toda su funcionalidad en su entorno de desarrollo
  2. Explore características avanzadas - Consulte firmas digitales, formularios PDF y otras características avanzadas de PDF
  3. Escale con confianza - Revise opciones de licenciamiento para sus necesidades de API de producción

¡Construya su API de PDF para .NET hoy y optimice la generación de documentos en todo su ecosistema de aplicaciones con IronPDF!

Preguntas Frecuentes

¿Qué es una API PDF de .NET?

Una API PDF de .NET es una biblioteca que permite a los desarrolladores crear, editar y extraer contenido PDF dentro de aplicaciones .NET. Simplifica tareas complejas de PDF y asegura una gestión eficiente de archivos PDF.

¿Cómo puede una API PDF de .NET beneficiar a mi aplicación?

Una API PDF de .NET puede mejorar su aplicación proporcionando consistencia, mantenibilidad y escalabilidad en la gestión de archivos PDF, como generar facturas, informes, certificados o contratos.

¿Cuáles son algunos casos de uso comunes para una API PDF de .NET?

Los casos de uso comunes para una API PDF de .NET incluyen generar facturas, crear informes, producir certificados y gestionar contratos dentro de aplicaciones de escritorio y web.

¿Cómo simplifica IronPDF las tareas de generación de PDF?

IronPDF simplifica las tareas de generación de PDF ofreciendo una biblioteca robusta que permite una fácil gestión de contenido de documentos, páginas de PDF y campos de formularios, facilitando el mantenimiento y la escalabilidad de aplicaciones.

¿Puede IronPDF manejar campos de formularios en PDF?

Sí, IronPDF puede gestionar eficientemente campos de formularios en PDF, permitiendo a los desarrolladores crear, completar y extraer datos de formularios dentro de documentos PDF.

¿Es IronPDF adecuado tanto para aplicaciones de escritorio como web?

Absolutamente, IronPDF está diseñado para funcionar sin problemas en aplicaciones de escritorio y web, proporcionando una solución consistente y escalable para la gestión de PDF.

¿Qué hace de IronPDF una opción confiable para desarrolladores .NET?

IronPDF es una opción confiable para desarrolladores .NET debido a su facilidad de uso, características completas y capacidad para simplificar tareas de PDF, lo que mejora la productividad y el rendimiento de la aplicación.

¿IronPDF admite capacidades de extracción de PDF?

Sí, IronPDF admite capacidades de extracción de PDF, permitiéndole extraer texto, imágenes y otros datos de documentos PDF de manera eficiente.

¿Cómo mejora IronPDF la escalabilidad en la gestión de PDFs?

IronPDF mejora la escalabilidad proporcionando un servicio centralizado de generación de PDF que puede manejar demandas crecientes sin sacrificar el rendimiento, siendo ideal para aplicaciones en crecimiento.

¿Qué tipo de soporte ofrece IronPDF para aplicaciones .NET?

IronPDF ofrece soporte extenso para aplicaciones .NET, incluyendo documentación detallada, código de muestra y un equipo de soporte receptivo para asistir a los desarrolladores en la integración de funcionalidades PDF.

¿IronPDF es totalmente compatible con .NET 10?

Sí, IronPDF es totalmente compatible con .NET 10. Admite todas las mejoras de rendimiento, lenguaje y tiempo de ejecución que .NET 10 introduce y funciona de inmediato en proyectos .NET 10, tal como lo hacía con versiones anteriores como .NET 6, 7, 8 y 9.

Curtis Chau
Escritor Técnico

Curtis Chau tiene una licenciatura en Ciencias de la Computación (Carleton University) y se especializa en el desarrollo front-end con experiencia en Node.js, TypeScript, JavaScript y React. Apasionado por crear interfaces de usuario intuitivas y estéticamente agradables, disfruta trabajando con frameworks modernos y creando manuales bien ...

Leer más