Cómo generar PDF dinámicamente en .NET con IronPDF
La generación dinámica de PDF permite que sus aplicaciones .NET produzcan facturas personalizadas, informes de datos en tiempo real y certificados personalizados a pedido, todo sin tocar una sola plantilla estática. IronPDF hace que esto sea sencillo al exponer un motor de renderizado basado en Chrome que convierte HTML, CSS y JavaScript directamente en documentos PDF con píxeles perfectos, para que usted pueda concentrarse en la lógica empresarial en lugar de en los detalles internos del PDF de bajo nivel.
Esta guía lo guiará a través de cada técnica principal para producir archivos PDF basados en datos en .NET: instalar la biblioteca, aplicar plantillas de marcador de posición, crear tablas mediante programación, usar bloques de contenido condicional y ejecutar JavaScript antes de renderizar. Cada sección incluye un ejemplo de código C# funcional y una explicación de cuándo aplicar esa estrategia en particular. Al finalizar, tendrá suficientes conocimientos prácticos para construir un sistema completo de generación de PDF dinámico adaptado a los requisitos específicos de su aplicación.

¿Qué es la generación dinámica de PDF en .NET?
La generación dinámica de PDF significa crear documentos PDF en tiempo de ejecución donde cada pieza de contenido (nombres, figuras, fechas, tablas, gráficos) proviene de datos en vivo en lugar de un diseño fijo. La estructura del documento puede permanecer igual, pero su carga útil cambia con cada solicitud.
Estos son los escenarios en los que este enfoque ofrece el mayor valor:
- Generación de facturas : los artículos de línea, los totales, las tasas de impuestos y las condiciones de pago difieren para cada transacción
- Informes financieros : gráficos y tablas de resumen extraídos de una base de datos que se actualiza durante todo el día
- Certificados y diplomas : los nombres de los destinatarios, las fechas de finalización y los detalles del curso varían según el registro.
- Documentos legales : los contratos incorporan cláusulas específicas del cliente y reglas de jurisdicción.
- Historiales médicos : los datos demográficos de los pacientes, los resultados de las pruebas y los planes de atención requieren un formato individual.
La alternativa convencional es mantener una biblioteca de plantillas estáticas y editarlas manualmente para cada variación. Ese enfoque fracasa rápidamente a medida que el volumen de documentos crece y las reglas de negocio se multiplican. Con el motor de conversión de HTML a PDF de IronPDF , usted escribe la lógica de generación una vez y produce miles de archivos PDF con formato correcto y datos precisos sin ninguna intervención manual.
IronPDF funciona en Windows, Linux, macOS, Docker y Azure: la misma API funciona de manera idéntica en todas las plataformas. Esa consistencia multiplataforma significa que puedes desarrollar localmente e implementar en un contenedor en la nube sin ningún ajuste específico de la plataforma. La biblioteca está orientada a .NET 6 y versiones posteriores, y admite tanto las últimas versiones de .NET como las versiones con soporte a largo plazo.

¿Cómo instalar y configurar la biblioteca?
IronPDF se distribuye como un paquete NuGet y se integra con cualquier proyecto .NET 6 o posterior, incluidas ASP.NET Core, Blazor y aplicaciones de consola. Instálelo a través de la consola del administrador de paquetes o la CLI de .NET :
Install-Package IronPdf
dotnet add package IronPdf
Install-Package IronPdf
dotnet add package IronPdf
Una vez instalado el paquete, puede comenzar a generar archivos PDF de inmediato: no se requiere ningún archivo de configuración ni clave API durante la prueba gratuita. Para obtener licencias de producción, visite la página de licencias de IronPDF y elija el plan que coincida con su modelo de implementación.
El punto de entrada para toda la representación es ChromePdfRenderer. El siguiente fragmento muestra el código mínimo necesario para convertir una cadena HTML dinámica en un archivo PDF guardado:
using IronPdf;
var renderer = new ChromePdfRenderer();
var customerName = "Alexandra Chen";
var orderNumber = "ORD-2025-001";
var totalAmount = 1499.99m;
var html = $"""
<h1>Order Confirmation</h1>
<p>Dear {customerName},</p>
<p>Thank you for your order #{orderNumber}.</p>
<p>Total amount: ${totalAmount:F2}</p>
<p>Your order will be processed within 24 hours.</p>
""";
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("order-confirmation.pdf");
// Stream the bytes directly in a web response if needed
byte[] pdfBytes = pdf.BinaryData;
using IronPdf;
var renderer = new ChromePdfRenderer();
var customerName = "Alexandra Chen";
var orderNumber = "ORD-2025-001";
var totalAmount = 1499.99m;
var html = $"""
<h1>Order Confirmation</h1>
<p>Dear {customerName},</p>
<p>Thank you for your order #{orderNumber}.</p>
<p>Total amount: ${totalAmount:F2}</p>
<p>Your order will be processed within 24 hours.</p>
""";
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("order-confirmation.pdf");
// Stream the bytes directly in a web response if needed
byte[] pdfBytes = pdf.BinaryData;
Imports IronPdf
Dim renderer As New ChromePdfRenderer()
Dim customerName As String = "Alexandra Chen"
Dim orderNumber As String = "ORD-2025-001"
Dim totalAmount As Decimal = 1499.99D
Dim html As String = $"
<h1>Order Confirmation</h1>
<p>Dear {customerName},</p>
<p>Thank you for your order #{orderNumber}.</p>
<p>Total amount: ${totalAmount:F2}</p>
<p>Your order will be processed within 24 hours.</p>
"
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("order-confirmation.pdf")
' Stream the bytes directly in a web response if needed
Dim pdfBytes As Byte() = pdf.BinaryData
ChromePdfRenderer maneja toda la complejidad de renderizado internamente. La interpolación de cadenas ($"""...""") inserta variables de C# en HTML en el punto de llamada, manteniendo las plantillas legibles y eliminando una biblioteca de plantillas dedicada para casos simples.
Para obtener una guía de configuración completa, incluida la configuración de vistas MVC y proyectos de servidor Blazor , consulte la documentación de IronPDF .
Resultado

¿Cómo se aplica la generación de PDF basada en plantillas?
La generación basada en plantillas separa el diseño del documento de la vinculación de datos. Un diseñador crea el diseño HTML una vez, colocando marcadores de posición con nombre ({{TOKEN}}) donde deben aparecer los valores de tiempo de ejecución, y su aplicación reemplaza esos tokens antes de renderizar. Este es el patrón recomendado en las discusiones de generación de PDF de Stack Overflow para proyectos donde las plantillas cambian con más frecuencia que el código de la aplicación.
using IronPdf;
// Reusable template -- stored in a file or database in production
var htmlTemplate = """
<style>
.invoice { font-family: Arial; max-width: 800px; margin: auto; }
.header { background: #f0f0f0; padding: 20px; }
.label { font-weight: bold; }
</style>
<div class='invoice'>
<div class='header'>
<h2>Invoice #{{INVOICE_NUMBER}}</h2>
<p>Date: {{INVOICE_DATE}}</p>
</div>
<p>Bill to: {{CUSTOMER_NAME}}</p>
<p class='label'>Amount due: ${{TOTAL_AMOUNT}}</p>
</div>
""";
var invoiceHtml = htmlTemplate
.Replace("{{INVOICE_NUMBER}}", "INV-2025-1234")
.Replace("{{INVOICE_DATE}}", DateTime.Now.ToString("MMM dd, yyyy"))
.Replace("{{CUSTOMER_NAME}}", "TechCorp Industries")
.Replace("{{TOTAL_AMOUNT}}", "5,750.00");
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.TextHeader = new TextHeaderFooter
{
CenterText = "Invoice",
DrawDividerLine = true
};
var pdf = renderer.RenderHtmlAsPdf(invoiceHtml);
pdf.SaveAs("invoice.pdf");
using IronPdf;
// Reusable template -- stored in a file or database in production
var htmlTemplate = """
<style>
.invoice { font-family: Arial; max-width: 800px; margin: auto; }
.header { background: #f0f0f0; padding: 20px; }
.label { font-weight: bold; }
</style>
<div class='invoice'>
<div class='header'>
<h2>Invoice #{{INVOICE_NUMBER}}</h2>
<p>Date: {{INVOICE_DATE}}</p>
</div>
<p>Bill to: {{CUSTOMER_NAME}}</p>
<p class='label'>Amount due: ${{TOTAL_AMOUNT}}</p>
</div>
""";
var invoiceHtml = htmlTemplate
.Replace("{{INVOICE_NUMBER}}", "INV-2025-1234")
.Replace("{{INVOICE_DATE}}", DateTime.Now.ToString("MMM dd, yyyy"))
.Replace("{{CUSTOMER_NAME}}", "TechCorp Industries")
.Replace("{{TOTAL_AMOUNT}}", "5,750.00");
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.TextHeader = new TextHeaderFooter
{
CenterText = "Invoice",
DrawDividerLine = true
};
var pdf = renderer.RenderHtmlAsPdf(invoiceHtml);
pdf.SaveAs("invoice.pdf");
Imports IronPdf
' Reusable template -- stored in a file or database in production
Dim htmlTemplate As String = "
<style>
.invoice { font-family: Arial; max-width: 800px; margin: auto; }
.header { background: #f0f0f0; padding: 20px; }
.label { font-weight: bold; }
</style>
<div class='invoice'>
<div class='header'>
<h2>Invoice #{{INVOICE_NUMBER}}</h2>
<p>Date: {{INVOICE_DATE}}</p>
</div>
<p>Bill to: {{CUSTOMER_NAME}}</p>
<p class='label'>Amount due: ${{TOTAL_AMOUNT}}</p>
</div>
"
Dim invoiceHtml As String = htmlTemplate _
.Replace("{{INVOICE_NUMBER}}", "INV-2025-1234") _
.Replace("{{INVOICE_DATE}}", DateTime.Now.ToString("MMM dd, yyyy")) _
.Replace("{{CUSTOMER_NAME}}", "TechCorp Industries") _
.Replace("{{TOTAL_AMOUNT}}", "5,750.00")
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.TextHeader = New TextHeaderFooter With {
.CenterText = "Invoice",
.DrawDividerLine = True
}
Dim pdf = renderer.RenderHtmlAsPdf(invoiceHtml)
pdf.SaveAs("invoice.pdf")
Los tokens ({{...}}) marcan exactamente dónde ingresan los datos al documento, lo que hace que las plantillas sean legibles para quienes no son desarrolladores. Almacenar plantillas como archivos externos significa que un diseñador puede actualizar el diseño sin tocar el código base de la aplicación. Para obtener una explicación más detallada de este patrón, consulte el tutorial de la plantilla IronPDF .

¿Cómo crear archivos PDF mediante programación a partir de datos?
Cuando el contenido del documento depende de bucles, agregaciones o formato condicional, crear la cadena HTML en el código le brinda el mayor control. Este enfoque es común en informes financieros y operativos, donde el número de filas se desconoce en tiempo de compilación. También permite aplicar reglas de formato directamente en C#, en lugar de incrustarlas en una plantilla estática.
using IronPdf;
using System.Text;
var orderItems = new[]
{
new { Product = "Premium License", Quantity = 5, Price = 399.00m },
new { Product = "Support Package", Quantity = 1, Price = 299.00m },
new { Product = "Training Session", Quantity = 2, Price = 150.00m }
};
var sb = new StringBuilder();
sb.Append("<h2>Order Summary</h2>");
sb.Append("<table style='width:100%; border-collapse:collapse;'>");
sb.Append("<tr style='background:#333; color:white;'>");
sb.Append("<th style='padding:10px;'>Product</th><th>Qty</th><th>Unit Price</th><th>Total</th>");
sb.Append("</tr>");
decimal grandTotal = 0;
foreach (var item in orderItems)
{
var lineTotal = item.Quantity * item.Price;
grandTotal += lineTotal;
sb.Append($"""
<tr>
<td style='padding:10px;'>{item.Product}</td>
<td style='text-align:center;'>{item.Quantity}</td>
<td style='text-align:right;'>${item.Price:F2}</td>
<td style='text-align:right;'>${lineTotal:F2}</td>
</tr>
""");
}
sb.Append($"""
<tr style='font-weight:bold; background:#f0f0f0;'>
<td colspan='3' style='padding:10px; text-align:right;'>Grand total:</td>
<td style='text-align:right; padding:10px;'>${grandTotal:F2}</td>
</tr>
""");
sb.Append("</table>");
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(sb.ToString());
pdf.SaveAs("order-summary.pdf");
// Get bytes for a web download response
byte[] pdfData = pdf.BinaryData;
using IronPdf;
using System.Text;
var orderItems = new[]
{
new { Product = "Premium License", Quantity = 5, Price = 399.00m },
new { Product = "Support Package", Quantity = 1, Price = 299.00m },
new { Product = "Training Session", Quantity = 2, Price = 150.00m }
};
var sb = new StringBuilder();
sb.Append("<h2>Order Summary</h2>");
sb.Append("<table style='width:100%; border-collapse:collapse;'>");
sb.Append("<tr style='background:#333; color:white;'>");
sb.Append("<th style='padding:10px;'>Product</th><th>Qty</th><th>Unit Price</th><th>Total</th>");
sb.Append("</tr>");
decimal grandTotal = 0;
foreach (var item in orderItems)
{
var lineTotal = item.Quantity * item.Price;
grandTotal += lineTotal;
sb.Append($"""
<tr>
<td style='padding:10px;'>{item.Product}</td>
<td style='text-align:center;'>{item.Quantity}</td>
<td style='text-align:right;'>${item.Price:F2}</td>
<td style='text-align:right;'>${lineTotal:F2}</td>
</tr>
""");
}
sb.Append($"""
<tr style='font-weight:bold; background:#f0f0f0;'>
<td colspan='3' style='padding:10px; text-align:right;'>Grand total:</td>
<td style='text-align:right; padding:10px;'>${grandTotal:F2}</td>
</tr>
""");
sb.Append("</table>");
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(sb.ToString());
pdf.SaveAs("order-summary.pdf");
// Get bytes for a web download response
byte[] pdfData = pdf.BinaryData;
Imports IronPdf
Imports System.Text
Dim orderItems = New() {
New With {.Product = "Premium License", .Quantity = 5, .Price = 399.0D},
New With {.Product = "Support Package", .Quantity = 1, .Price = 299.0D},
New With {.Product = "Training Session", .Quantity = 2, .Price = 150.0D}
}
Dim sb = New StringBuilder()
sb.Append("<h2>Order Summary</h2>")
sb.Append("<table style='width:100%; border-collapse:collapse;'>")
sb.Append("<tr style='background:#333; color:white;'>")
sb.Append("<th style='padding:10px;'>Product</th><th>Qty</th><th>Unit Price</th><th>Total</th>")
sb.Append("</tr>")
Dim grandTotal As Decimal = 0
For Each item In orderItems
Dim lineTotal = item.Quantity * item.Price
grandTotal += lineTotal
sb.Append($"
<tr>
<td style='padding:10px;'>{item.Product}</td>
<td style='text-align:center;'>{item.Quantity}</td>
<td style='text-align:right;'>${item.Price:F2}</td>
<td style='text-align:right;'>${lineTotal:F2}</td>
</tr>
")
Next
sb.Append($"
<tr style='font-weight:bold; background:#f0f0f0;'>
<td colspan='3' style='padding:10px; text-align:right;'>Grand total:</td>
<td style='text-align:right; padding:10px;'>${grandTotal:F2}</td>
</tr>
")
sb.Append("</table>")
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf(sb.ToString())
pdf.SaveAs("order-summary.pdf")
' Get bytes for a web download response
Dim pdfData As Byte() = pdf.BinaryData
StringBuilder maneja cadenas HTML grandes de manera eficiente. El bucle foreach se expande a cualquier cantidad de filas que proporcione su fuente de datos, y el cálculo grandTotal en ejecución muestra cómo la lógica empresarial se integra naturalmente con la construcción HTML. Para conjuntos de datos muy grandes, este enfoque combina bien con las opciones de representación de varias páginas de IronPDF .
Resultado

¿Cómo manejar tablas dinámicas que abarcan varias páginas?
Los informes generados a partir de bases de datos a menudo contienen recuentos de filas impredecibles. Para gestionar correctamente los saltos de página automáticos (sin cortar una fila a la mitad) se necesitan CSS específicos junto con las opciones de renderizado de IronPDF. La regla page-break-inside: avoid, combinada con una configuración de márgenes correcta, mantiene cada fila intacta a medida que la tabla fluye a través de las páginas.
using IronPdf;
var salesData = Enumerable.Range(1, 30).Select(i => new
{
Month = $"Month {i}",
Revenue = 10_000 + (i * 500),
Growth = 2.5 + (i * 0.3)
});
var tableHtml = """
<style>
table { width: 100%; border-collapse: collapse; page-break-inside: auto; }
th { background: #2c3e50; color: white; padding: 12px; }
td { padding: 8px; border-bottom: 1px solid #ddd; }
tr:nth-child(even) { background: #f9f9f9; }
tr { page-break-inside: avoid; page-break-after: auto; }
</style>
<h2>Sales Performance Report</h2>
<table>
<thead><tr><th>Period</th><th>Revenue</th><th>Growth %</th></tr></thead>
<tbody>
""";
foreach (var row in salesData)
{
tableHtml += $"""
<tr>
<td>{row.Month}</td>
<td>${row.Revenue:N0}</td>
<td>{row.Growth:F1}%</td>
</tr>
""";
}
tableHtml += "</tbody></table>";
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;
renderer.RenderingOptions.MarginTop = 40;
renderer.RenderingOptions.MarginBottom = 40;
renderer.RenderingOptions.TextFooter = new TextHeaderFooter
{
CenterText = "{page} of {total-pages}",
FontSize = 10
};
var pdf = renderer.RenderHtmlAsPdf(tableHtml);
pdf.SaveAs("sales-report.pdf");
using IronPdf;
var salesData = Enumerable.Range(1, 30).Select(i => new
{
Month = $"Month {i}",
Revenue = 10_000 + (i * 500),
Growth = 2.5 + (i * 0.3)
});
var tableHtml = """
<style>
table { width: 100%; border-collapse: collapse; page-break-inside: auto; }
th { background: #2c3e50; color: white; padding: 12px; }
td { padding: 8px; border-bottom: 1px solid #ddd; }
tr:nth-child(even) { background: #f9f9f9; }
tr { page-break-inside: avoid; page-break-after: auto; }
</style>
<h2>Sales Performance Report</h2>
<table>
<thead><tr><th>Period</th><th>Revenue</th><th>Growth %</th></tr></thead>
<tbody>
""";
foreach (var row in salesData)
{
tableHtml += $"""
<tr>
<td>{row.Month}</td>
<td>${row.Revenue:N0}</td>
<td>{row.Growth:F1}%</td>
</tr>
""";
}
tableHtml += "</tbody></table>";
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4;
renderer.RenderingOptions.MarginTop = 40;
renderer.RenderingOptions.MarginBottom = 40;
renderer.RenderingOptions.TextFooter = new TextHeaderFooter
{
CenterText = "{page} of {total-pages}",
FontSize = 10
};
var pdf = renderer.RenderHtmlAsPdf(tableHtml);
pdf.SaveAs("sales-report.pdf");
Imports IronPdf
Dim salesData = Enumerable.Range(1, 30).Select(Function(i) New With {
.Month = $"Month {i}",
.Revenue = 10000 + (i * 500),
.Growth = 2.5 + (i * 0.3)
})
Dim tableHtml As String = "
<style>
table { width: 100%; border-collapse: collapse; page-break-inside: auto; }
th { background: #2c3e50; color: white; padding: 12px; }
td { padding: 8px; border-bottom: 1px solid #ddd; }
tr:nth-child(even) { background: #f9f9f9; }
tr { page-break-inside: avoid; page-break-after: auto; }
</style>
<h2>Sales Performance Report</h2>
<table>
<thead><tr><th>Period</th><th>Revenue</th><th>Growth %</th></tr></thead>
<tbody>
"
For Each row In salesData
tableHtml += $"
<tr>
<td>{row.Month}</td>
<td>${row.Revenue:N0}</td>
<td>{row.Growth:F1}%</td>
</tr>
"
Next
tableHtml += "</tbody></table>"
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.PaperSize = IronPdf.Rendering.PdfPaperSize.A4
renderer.RenderingOptions.MarginTop = 40
renderer.RenderingOptions.MarginBottom = 40
renderer.RenderingOptions.TextFooter = New TextHeaderFooter With {
.CenterText = "{page} of {total-pages}",
.FontSize = 10
}
Dim pdf = renderer.RenderHtmlAsPdf(tableHtml)
pdf.SaveAs("sales-report.pdf")
{page} y {total-pages} son tokens integrados de IronPDF para la numeración automática de pie de página. Los márgenes mantienen el contenido alejado de los bordes en cada página, lo que le da al informe terminado una apariencia profesional incluso cuando la tabla ocupa docenas de páginas.
Para obtener instrucciones de formato sobre diseños de tablas complejos, incluidas celdas fusionadas, consulte la referencia de opciones de representación de IronPDF .
¿Cómo agregar contenido condicional a un PDF?
Muchos tipos de documentos incluyen secciones que deberían aparecer solo cuando se cumplen ciertas condiciones: una insignia premium para clientes de primer nivel, un bloque de descuento cuando se aplica una promoción, una advertencia cuando una cuenta está vencida. La lógica condicional de C# se asigna directamente a este requisito y, debido a que la condición se evalúa antes de que se construya la cadena HTML, ningún elemento de marcador de posición vacío termina en el PDF final.
using IronPdf;
var customer = new
{
Name = "Global Tech Solutions",
IsPremium = true,
HasDiscount = true,
DiscountPct = 15,
LoyaltyPoints = 2500
};
var html = $"""<h2>Customer Profile: {customer.Name}</h2><div style='border:1px solid #ddd; padding:20px;'>""";
if (customer.IsPremium)
{
html += """<div style='background:gold; padding:10px; margin-bottom:10px;'>PREMIUM MEMBER -- Exclusive benefits applied</div>""";
}
if (customer.HasDiscount)
{
html += $"""<div style='background:#e8f5e9; padding:10px; margin-bottom:10px;'>Special discount: {customer.DiscountPct}% off all orders</div>""";
}
if (customer.LoyaltyPoints > 0)
{
html += $"""<div style='background:#f3e5f5; padding:10px;'>Loyalty points balance: {customer.LoyaltyPoints:N0} points</div>""";
}
html += "</div>";
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("customer-profile.pdf");
using IronPdf;
var customer = new
{
Name = "Global Tech Solutions",
IsPremium = true,
HasDiscount = true,
DiscountPct = 15,
LoyaltyPoints = 2500
};
var html = $"""<h2>Customer Profile: {customer.Name}</h2><div style='border:1px solid #ddd; padding:20px;'>""";
if (customer.IsPremium)
{
html += """<div style='background:gold; padding:10px; margin-bottom:10px;'>PREMIUM MEMBER -- Exclusive benefits applied</div>""";
}
if (customer.HasDiscount)
{
html += $"""<div style='background:#e8f5e9; padding:10px; margin-bottom:10px;'>Special discount: {customer.DiscountPct}% off all orders</div>""";
}
if (customer.LoyaltyPoints > 0)
{
html += $"""<div style='background:#f3e5f5; padding:10px;'>Loyalty points balance: {customer.LoyaltyPoints:N0} points</div>""";
}
html += "</div>";
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("customer-profile.pdf");
Imports IronPdf
Dim customer = New With {
.Name = "Global Tech Solutions",
.IsPremium = True,
.HasDiscount = True,
.DiscountPct = 15,
.LoyaltyPoints = 2500
}
Dim html = $"<h2>Customer Profile: {customer.Name}</h2><div style='border:1px solid #ddd; padding:20px;'>"
If customer.IsPremium Then
html += "<div style='background:gold; padding:10px; margin-bottom:10px;'>PREMIUM MEMBER -- Exclusive benefits applied</div>"
End If
If customer.HasDiscount Then
html += $"<div style='background:#e8f5e9; padding:10px; margin-bottom:10px;'>Special discount: {customer.DiscountPct}% off all orders</div>"
End If
If customer.LoyaltyPoints > 0 Then
html += $"<div style='background:#f3e5f5; padding:10px;'>Loyalty points balance: {customer.LoyaltyPoints:N0} points</div>"
End If
html += "</div>"
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("customer-profile.pdf")
Puede extender el mismo patrón a cualquier contenido basado en reglas: descargos de responsabilidad legales específicos de la jurisdicción, secciones promocionales activadas por el valor del carrito o advertencias de seguridad activadas por la categoría del producto. El PDF resultante contiene exactamente el contenido que debería: nada más y nada menos.
Resultado

¿Cómo se representan gráficos con JavaScript en un PDF?
Los paneles modernos suelen utilizar bibliotecas de gráficos JavaScript como Chart.js o D3.js para dibujar gráficos en tiempo de renderizado. IronPDF puede ejecutar JavaScript antes de capturar la página, por lo que el gráfico se renderiza completamente antes de tomar la instantánea del PDF. Esto significa que no necesita un servicio de captura de pantalla independiente ni una biblioteca de representación de gráficos del lado del servidor.
using IronPdf;
var chartHtml = """
<script src='https://cdn.jsdelivr.net/npm/chart.js'></script>
<canvas id='revenueChart' width='500' height='250'></canvas>
<script>
var ctx = document.getElementById('revenueChart').getContext('2d');
new Chart(ctx, {
type: 'bar',
data: {
labels: ['Q1', 'Q2', 'Q3', 'Q4'],
datasets: [{
label: 'Revenue (thousands)',
data: [120, 195, 230, 285],
backgroundColor: '#3498db'
}]
},
options: { animation: false }
});
</script>
""";
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.EnableJavaScript = true;
renderer.RenderingOptions.WaitFor.RenderDelay(1500);
var pdf = renderer.RenderHtmlAsPdf(chartHtml);
pdf.SaveAs("revenue-chart.pdf");
using IronPdf;
var chartHtml = """
<script src='https://cdn.jsdelivr.net/npm/chart.js'></script>
<canvas id='revenueChart' width='500' height='250'></canvas>
<script>
var ctx = document.getElementById('revenueChart').getContext('2d');
new Chart(ctx, {
type: 'bar',
data: {
labels: ['Q1', 'Q2', 'Q3', 'Q4'],
datasets: [{
label: 'Revenue (thousands)',
data: [120, 195, 230, 285],
backgroundColor: '#3498db'
}]
},
options: { animation: false }
});
</script>
""";
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.EnableJavaScript = true;
renderer.RenderingOptions.WaitFor.RenderDelay(1500);
var pdf = renderer.RenderHtmlAsPdf(chartHtml);
pdf.SaveAs("revenue-chart.pdf");
Imports IronPdf
Dim chartHtml As String = "
<script src='https://cdn.jsdelivr.net/npm/chart.js'></script>
<canvas id='revenueChart' width='500' height='250'></canvas>
<script>
var ctx = document.getElementById('revenueChart').getContext('2d');
new Chart(ctx, {
type: 'bar',
data: {
labels: ['Q1', 'Q2', 'Q3', 'Q4'],
datasets: [{
label: 'Revenue (thousands)',
data: [120, 195, 230, 285],
backgroundColor: '#3498db'
}]
},
options: { animation: false }
});
</script>
"
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.EnableJavaScript = True
renderer.RenderingOptions.WaitFor.RenderDelay(1500)
Dim pdf = renderer.RenderHtmlAsPdf(chartHtml)
pdf.SaveAs("revenue-chart.pdf")
EnableJavaScript = true activa la ejecución del script dentro del motor Chrome sin interfaz gráfica. RenderDelay(1500) agrega una pausa de 1,5 segundos después de que se carga la página, lo que da tiempo a la representación asincrónica de gráficos para completarse antes de que se tome la instantánea. La configuración animation: false en las opciones de Chart.js evita que se capturen cuadros animados a mitad de la transición.
Esta técnica funciona con cualquier biblioteca de JavaScript . Puede pasar datos del lado del servidor al bloque <script> usando la interpolación de cadenas de C#, de modo que cada gráfico refleje las cifras de la base de datos en vivo en el momento de la generación. Para obtener más detalles sobre la configuración de JavaScript , consulte la guía de representación de JavaScript de IronPDF .
¿Cómo exportar y entregar el PDF generado?
Una vez que RenderHtmlAsPdf devuelve un objeto PdfDocument, tiene varias opciones de entrega dependiendo del tipo de aplicación. Guardar en el disco es el método más sencillo y funciona para trabajos por lotes en segundo plano. Para las API web y los controladores MVC, la transmisión de bytes directamente a la respuesta HTTP evita escribir archivos temporales y mantiene limpio el sistema de archivos del servidor.
using IronPdf;
using Microsoft.AspNetCore.Mvc;
// In an ASP.NET Core controller action:
public IActionResult DownloadInvoice(int orderId)
{
var renderer = new ChromePdfRenderer();
var html = BuildInvoiceHtml(orderId); // your data-binding method
var pdf = renderer.RenderHtmlAsPdf(html);
return File(pdf.BinaryData, "application/pdf", $"invoice-{orderId}.pdf");
}
using IronPdf;
using Microsoft.AspNetCore.Mvc;
// In an ASP.NET Core controller action:
public IActionResult DownloadInvoice(int orderId)
{
var renderer = new ChromePdfRenderer();
var html = BuildInvoiceHtml(orderId); // your data-binding method
var pdf = renderer.RenderHtmlAsPdf(html);
return File(pdf.BinaryData, "application/pdf", $"invoice-{orderId}.pdf");
}
Imports IronPdf
Imports Microsoft.AspNetCore.Mvc
' In an ASP.NET Core controller action:
Public Function DownloadInvoice(orderId As Integer) As IActionResult
Dim renderer = New ChromePdfRenderer()
Dim html = BuildInvoiceHtml(orderId) ' your data-binding method
Dim pdf = renderer.RenderHtmlAsPdf(html)
Return File(pdf.BinaryData, "application/pdf", $"invoice-{orderId}.pdf")
End Function
pdf.BinaryData devuelve los bytes sin procesar como un byte[], que se asigna directamente al resultado File() de ASP.NET Core. El navegador recibe el tipo MIME correcto (application/pdf) y activa un cuadro de diálogo de descarga con un nombre de archivo significativo.
Las capacidades de salida adicionales incluyen fusión de PDF , firmas digitales , formato de archivo PDF/A , protección con contraseña y extracción de texto e imágenes . Estas funciones operan en el mismo objeto PdfDocument devuelto por el renderizador, por lo que puede encadenar operaciones sin crear archivos intermedios.

¿Cuales son tus próximos pasos?
La generación dinámica de PDF en .NET se reduce a tres bloques fundamentales: una cadena HTML que varía con sus datos, ChromePdfRenderer para convertir esa cadena en un PDF y el mecanismo de entrega que se adapta a su aplicación. IronPDF gestiona todo lo demás: saltos de página, encabezados y pies de página, ejecución de JavaScript y compatibilidad entre plataformas.
Para pasar de la lectura a la compilación, comience por instalar el paquete y ejecutar uno de los ejemplos anteriores con sus propios datos:
dotnet add package IronPdf
dotnet add package IronPdf
Desde allí, explore la documentación de IronPDF para la configuración específica de la plataforma (Azure, Docker, Linux), opciones de renderizado avanzadas y la referencia completa de API. Cuando esté listo para implementar, visite la página de licencias para elegir un plan que se ajuste a su volumen de producción. La prueba gratuita le brinda acceso completo a las funciones sin necesidad de tarjeta de crédito, para que pueda validar su implementación antes de comprometerse.
Guías adicionales que combinan bien con la generación dinámica:
- Generar un PDF a partir de una plantilla HTML en C#
- Convertir una URL a PDF
- Fusionar y dividir documentos PDF
- Añadir firmas digitales a archivos PDF
- Cumplimiento de PDF/A para documentos de archivo


Preguntas Frecuentes
¿Qué es la generación dinámica de PDF?
La generación dinámica de PDF hace referencia a la creación de documentos PDF sobre la marcha basándose en la entrada de datos en tiempo real, en lugar de utilizar plantillas estáticas preexistentes.
¿Cómo puede IronPDF ayudar con la generación dinámica de PDF en .NET?
IronPDF simplifica la generación dinámica de PDF permitiendo a los desarrolladores crear PDF a partir de HTML, imágenes u otras fuentes, centrándose en la lógica empresarial en lugar de en la compleja renderización de PDF.
¿Cuáles son las ventajas de utilizar IronPDF para generar PDF dinámicos?
El uso de IronPDF para PDF dinámicos permite la personalización, la integración de datos en tiempo real y la reducción de la complejidad en la creación de documentos PDF directamente desde aplicaciones .NET.
¿Puede utilizarse IronPDF para generar facturas personalizadas en una plataforma de comercio electrónico?
Sí, IronPDF puede generar dinámicamente facturas personalizadas integrando datos en tiempo real, lo que lo hace ideal para plataformas de comercio electrónico.
¿Qué tipos de aplicaciones se benefician de la generación dinámica de PDF?
Aplicaciones como plataformas de comercio electrónico, sistemas de generación de informes y plataformas educativas se benefician de la generación dinámica de PDF al proporcionar documentos personalizados en tiempo real.
¿Es IronPDF adecuado para generar informes PDF con datos en tiempo real?
Por supuesto, IronPDF está diseñado para generar informes PDF a partir de datos en tiempo real, por lo que es perfecto para la generación dinámica de documentos.
¿Cómo gestiona IronPDF las complejidades del procesamiento de PDF?
IronPDF abstrae las complejidades de la renderización de PDF, lo que permite a los desarrolladores centrarse en la lógica empresarial de su aplicación mientras crean PDF de alta calidad.
¿Puede IronPDF crear certificados educativos de forma dinámica?
Sí, IronPDF puede generar certificados educativos de forma dinámica utilizando entradas de datos para crear certificados personalizados y de aspecto profesional.
¿Es IronPDF compatible con la creación de archivos PDF a partir de contenido HTML?
IronPDF admite la creación de PDF a partir de contenido HTML, lo que permite a los desarrolladores convertir páginas web o cadenas HTML directamente a formato PDF.
¿Cómo mejora IronPDF la productividad de los desarrolladores?
IronPDF mejora la productividad de los desarrolladores al proporcionar una API sencilla para la generación de PDF, lo que reduce el tiempo y el esfuerzo necesarios para crear documentos dinámicos.


