Saltar al pie de página
GUíAS DE MIGRACIóN

Cómo migrar de QuestPDF a IronPDF en C#

La migración de QuestPDF aIronPDFtransforma su flujo de trabajo de generación de PDF de una API propietaria fluida de C# a un enfoque estándar basado en HTML/CSS con amplias capacidades de manipulación de PDF. Esta guía proporciona una ruta de migración completa, paso a paso, que le permite aprovechar las habilidades web existentes, reutilizar plantillas HTML y obtener características que QuestPDF simplemente no puede proporcionar.

Por qué migrar de QuestPDF a IronPDF

Entender QuestPDF

QuestPDF es una API moderna y fluida creada específicamente para generar PDF mediante programación en C#. A diferencia de algunos de sus homólogos que ofrecen una amplia capacidad de conversión de HTML a PDF, QuestPDF se limita a las funcionalidades programáticas de la API de diseño. QuestPDF destaca en situaciones en las que los desarrolladores necesitan generar documentos desde cero utilizando código C#, sin depender de HTML.

La biblioteca es gratuita para las empresas con ingresos inferiores a 1 millón de dólares, pero se exige demostrar este nivel de ingresos, lo que podría suponer una carga de cumplimiento para algunas. Los usuarios que superen este umbral deberán adquirir una licencia, lo que debe tenerse en cuenta en la planificación a largo plazo al evaluar QuestPDF como posible solución.

El problema principal: no es compatible con HTML

A menudo se recomienda QuestPDF para la conversión de HTML a PDF, pero no admite HTML en absoluto. A pesar de estar muy promocionado en los foros de desarrolladores, QuestPDF utiliza su propio lenguaje de maquetación que requiere aprender un DSL completamente nuevo en lugar de aprovechar los conocimientos web existentes.

CaracterísticaQuestPDFIronPDF
HTML a PDFNO SE APOYASoporte completo
Estilización CSSNO SE APOYACSS3 completo
Plantillas existentesDebe reconstruirse desde ceroReutilización de activos HTML/CSS
Compatibilidad con herramientas de diseñoNingunoCualquier herramienta de diseño web
Curva de aprendizajeNuevo DSL propietarioTransferencia de conocimientos web
Vista previa del diseñoRequiere plugin IDEVista previa en cualquier navegador
Manipulación de PDFNingunoFusión, división, edición

IronPDF proporciona un renderizado nativo de HTML a PDF del que QuestPDF carece por completo, eliminando la necesidad de reconstruir manualmente los documentos en código C#. Incluye funciones completas de manipulación de PDF (combinar, dividir, editar, proteger) que QuestPDF no puede realizar.

El Modelo de Licencia QuestPDF

La "Licencia Comunitaria" de QuestPDF sólo es gratuita si su empresa tiene menos de 1 millón de dólares de ingresos brutos anuales. Es posible que sus clientes (no solo usted como desarrollador) tengan que adquirir licencias si superan los umbrales de ingresos. A diferencia de una simple licencia comercial por desarrollador, el modelo de QuestPDF requiere la divulgación de los ingresos y el seguimiento del cumplimiento.

IronPDF ofrece licencias sencillas: una licencia por desarrollador, sin auditorías de ingresos, sin requisitos de licencia del cliente y con costes claros y predecibles.

Para los equipos que planifican la adopción de .NET 10 y C# 14 hasta 2025 y 2026,IronPDFofrece licencias transparentes sin auditorías basadas en ingresos y un enfoque HTML/CSS estándar que aprovecha las habilidades de desarrollo web existentes.


Antes de empezar

Prerrequisitos

  1. Entorno .NET: .NET Framework 4.6.2+ o .NET Core 3.1+ / .NET 5/6/7/8/9+
  2. Acceso a NuGet: Capacidad para instalar paquetes NuGet
  3. Licencia de IronPDF: Obtenga su clave de licencia en ironpdf.com

Cambios en el paquete NuGet

# Remove QuestPDF
dotnet remove package QuestPDF

# Add IronPDF
dotnet add package IronPdf
# Remove QuestPDF
dotnet remove package QuestPDF

# Add IronPDF
dotnet add package IronPdf
SHELL

Configuración de licencias

// Add at application startup
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// Add at application startup
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
$vbLabelText   $csharpLabel

Buscar el uso de QuestPDF

# Find all QuestPDF usages in your codebase
grep -r "QuestPDF\|Document.Create\|\.GeneratePdf" --include="*.cs" .
# Find all QuestPDF usages in your codebase
grep -r "QuestPDF\|Document.Create\|\.GeneratePdf" --include="*.cs" .
SHELL

Referencia completa de la API

Cambios en el espacio de nombres

// Before: QuestPDF
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;

// After: IronPDF
using IronPdf;
// Before: QuestPDF
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;

// After: IronPDF
using IronPdf;
$vbLabelText   $csharpLabel

Mapeos de API principales

Concepto de QuestPDFEquivalente de IronPDFNotas
Document.Create()<código>new ChromePdfRenderer()</códigoCreación de renderizadores
<código>.Page()</código><código>RenderHtmlAsPdf()</códigoConvierte HTML a PDF
<código>.Text()</código>HTML <p>, <h1>, <span>Etiquetas HTML estándar
.Bold()CSS font-weight: negritaCSS estándar
<código>.FontSize(24)</código>CSS tamaño de fuente: 24pxCSS estándar
.Image()HTML <img src="...">HTML estándar
<código>.Table()</código>HTML <código></código>HTML estándar
.Column()CSS display:flex; flex-dirección: columnaCSS Flexbox
.Row()CSS display:flex; flex-dirección: rowCSS Flexbox
<código>TamañoDePágina.A4</código<código>RenderingOptions.PaperSize</códigoDimensiones del documento
.Margin()<código>RenderingOptions.Margin*</códigoMárgenes de página
<código>.GeneratePdf()</código><código>pdf.SaveAs()</códigoArchivo de salida
N/APdfDocument.Merge()Fusionar PDF
N/A<código>PdfDocument.FromFile()</códigoCargar PDF existentes
N/A<código>pdf.SecuritySettings</códigoCodificación PDF

Ejemplos de migración de código

Ejemplo 1: Creación de documentos básicos (HTML a PDF)

Antes (QuestPDF):

// NuGet: Install-Package QuestPDF
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;

class Program
{
    static void Main()
    {
        QuestPDF.Settings.License = LicenseType.Community;

        Document.Create(container =>
        {
            container.Page(page =>
            {
                page.Size(PageSizes.A4);
                page.Margin(2, Unit.Centimetre);
                page.Content().Column(column =>
                {
                    column.Item().Text("Hello World").FontSize(20).Bold();
                    column.Item().Text("This is a paragraph of text.");
                });
            });
        }).GeneratePdf("output.pdf");
    }
}
// NuGet: Install-Package QuestPDF
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;

class Program
{
    static void Main()
    {
        QuestPDF.Settings.License = LicenseType.Community;

        Document.Create(container =>
        {
            container.Page(page =>
            {
                page.Size(PageSizes.A4);
                page.Margin(2, Unit.Centimetre);
                page.Content().Column(column =>
                {
                    column.Item().Text("Hello World").FontSize(20).Bold();
                    column.Item().Text("This is a paragraph of text.");
                });
            });
        }).GeneratePdf("output.pdf");
    }
}
$vbLabelText   $csharpLabel

Después (IronPDF):

// NuGet: Install-Package IronPdf
using IronPdf;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>This is a paragraph of text.</p>");
        pdf.SaveAs("output.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>This is a paragraph of text.</p>");
        pdf.SaveAs("output.pdf");
    }
}
$vbLabelText   $csharpLabel

Este ejemplo demuestra la diferencia fundamental de paradigma. QuestPDF requiere el aprendizaje de su fluida API: Document.Create(), container.Page(), page.Content().Column(), column.Item().Text(), con estilos mediante encadenamiento de métodos como .FontSize(20).Bold(). También debe establecer el tipo de licencia con QuestPDF.Settings.License = LicenseType.Community.

IronPDF utiliza HTML estándar que cualquier desarrollador web conoce: <h1> para los títulos, <p> para los párrafos. No hay que aprender ningún DSL propietario. El enfoque deIronPDFofrece una sintaxis más limpia y una mejor integración con las aplicaciones .NET modernas. Consulte la documentación HTML a PDF para ver ejemplos completos.

Ejemplo 2: Generación de facturas

Antes (QuestPDF):

// NuGet: Install-Package QuestPDF
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;

class Program
{
    static void Main()
    {
        QuestPDF.Settings.License = LicenseType.Community;

        Document.Create(container =>
        {
            container.Page(page =>
            {
                page.Size(PageSizes.A4);
                page.Margin(2, Unit.Centimetre);
                page.Content().Column(column =>
                {
                    column.Item().Text("INVOICE").FontSize(24).Bold();
                    column.Item().Text("Invoice #: 12345").FontSize(12);
                    column.Item().PaddingTop(20);
                    column.Item().Text("Customer: John Doe");
                    column.Item().Text("Total: $100.00").Bold();
                });
            });
        }).GeneratePdf("invoice.pdf");
    }
}
// NuGet: Install-Package QuestPDF
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;

class Program
{
    static void Main()
    {
        QuestPDF.Settings.License = LicenseType.Community;

        Document.Create(container =>
        {
            container.Page(page =>
            {
                page.Size(PageSizes.A4);
                page.Margin(2, Unit.Centimetre);
                page.Content().Column(column =>
                {
                    column.Item().Text("INVOICE").FontSize(24).Bold();
                    column.Item().Text("Invoice #: 12345").FontSize(12);
                    column.Item().PaddingTop(20);
                    column.Item().Text("Customer: John Doe");
                    column.Item().Text("Total: $100.00").Bold();
                });
            });
        }).GeneratePdf("invoice.pdf");
    }
}
$vbLabelText   $csharpLabel

Después (IronPDF):

// NuGet: Install-Package IronPdf
using IronPdf;

class Program
{
    static void Main()
    {
        var htmlContent = @"
            <h1>INVOICE</h1>
            <p>Invoice #: 12345</p>
            <br/>
            <p>Customer: John Doe</p>
            <p><strong>Total: $100.00</strong></p>
        ";

        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderHtmlAsPdf(htmlContent);
        pdf.SaveAs("invoice.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;

class Program
{
    static void Main()
    {
        var htmlContent = @"
            <h1>INVOICE</h1>
            <p>Invoice #: 12345</p>
            <br/>
            <p>Customer: John Doe</p>
            <p><strong>Total: $100.00</strong></p>
        ";

        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderHtmlAsPdf(htmlContent);
        pdf.SaveAs("invoice.pdf");
    }
}
$vbLabelText   $csharpLabel

QuestPDF utiliza .Column()y .Item() para el diseño, con <código>.PaddingTop(20)</código>para el espaciado.IronPDFutiliza HTML estándar: <h1> para el título, <p> para los párrafos, <br/> para el espaciado y <strong> para el texto en negrita.

La ventaja real: con IronPDF, los diseñadores pueden crear y modificar plantillas HTML de forma independiente. Con QuestPDF, cada cambio de diseño requiere que un desarrollador de C# modifique el código. Más información en nuestros tutoriales.

Ejemplo 3: Encabezados y pies de página con números de página

Antes (QuestPDF):

// NuGet: Install-Package QuestPDF
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;

class Program
{
    static void Main()
    {
        QuestPDF.Settings.License = LicenseType.Community;

        Document.Create(container =>
        {
            container.Page(page =>
            {
                page.Size(PageSizes.A4);
                page.Margin(2, Unit.Centimetre);

                page.Header().Text("Document Header").FontSize(14).Bold();

                page.Content().Text("Main content of the document.");

                page.Footer().AlignCenter().Text(text =>
                {
                    text.Span("Page ");
                    text.CurrentPageNumber();
                });
            });
        }).GeneratePdf("document.pdf");
    }
}
// NuGet: Install-Package QuestPDF
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;

class Program
{
    static void Main()
    {
        QuestPDF.Settings.License = LicenseType.Community;

        Document.Create(container =>
        {
            container.Page(page =>
            {
                page.Size(PageSizes.A4);
                page.Margin(2, Unit.Centimetre);

                page.Header().Text("Document Header").FontSize(14).Bold();

                page.Content().Text("Main content of the document.");

                page.Footer().AlignCenter().Text(text =>
                {
                    text.Span("Page ");
                    text.CurrentPageNumber();
                });
            });
        }).GeneratePdf("document.pdf");
    }
}
$vbLabelText   $csharpLabel

Después (IronPDF):

// NuGet: Install-Package IronPdf
using IronPdf;

class Program
{
    static void Main()
    {
        var htmlContent = "<p>Main content of the document.</p>";

        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderHtmlAsPdf(htmlContent);

        pdf.Header = new TextHeaderFooter()
        {
            CenterText = "Document Header",
            FontSize = 14
        };

        pdf.Footer = new TextHeaderFooter()
        {
            CenterText = "Page {page}"
        };

        pdf.SaveAs("document.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;

class Program
{
    static void Main()
    {
        var htmlContent = "<p>Main content of the document.</p>";

        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderHtmlAsPdf(htmlContent);

        pdf.Header = new TextHeaderFooter()
        {
            CenterText = "Document Header",
            FontSize = 14
        };

        pdf.Footer = new TextHeaderFooter()
        {
            CenterText = "Page {page}"
        };

        pdf.SaveAs("document.pdf");
    }
}
$vbLabelText   $csharpLabel

QuestPDF utiliza .Header() y .Footer() con métodos fluidos como <código>.AlignCenter()</código>y .CurrentPageNumber().IronPDFutiliza objetos TextHeaderFooter con propiedades como CenterText y FontSize. El marcador de posición {page} inserta automáticamente el número de la página actual.


Notas de migración críticas

El cambio de paradigma

El cambio fundamental consiste en pasar de un DSL de C# propietario a HTML/CSS estándar:

// QuestPDF: Proprietary fluent API
container.Page(page =>
{
    page.Content().Column(column =>
    {
        column.Item().Text("Invoice").Bold().FontSize(24);
        column.Item().Row(row =>
        {
            row.RelativeItem().Text("Customer:");
            row.RelativeItem().Text("Acme Corp");
        });
    });
});

// IronPDF: Standard HTML/CSS
var html = @"
<div style='font-family: Arial; padding: 40px;'>
    <h1 style='font-weight: bold; font-size: 24px;'>Invoice</h1>
    <div style='display: flex; justify-content: space-between;'>
        <span>Customer:</span>
        <span>Acme Corp</span>
    </div>
</div>";

var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
// QuestPDF: Proprietary fluent API
container.Page(page =>
{
    page.Content().Column(column =>
    {
        column.Item().Text("Invoice").Bold().FontSize(24);
        column.Item().Row(row =>
        {
            row.RelativeItem().Text("Customer:");
            row.RelativeItem().Text("Acme Corp");
        });
    });
});

// IronPDF: Standard HTML/CSS
var html = @"
<div style='font-family: Arial; padding: 40px;'>
    <h1 style='font-weight: bold; font-size: 24px;'>Invoice</h1>
    <div style='display: flex; justify-content: space-between;'>
        <span>Customer:</span>
        <span>Acme Corp</span>
    </div>
</div>";

var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
$vbLabelText   $csharpLabel

Conversiones de patrones de diseño

Patrón QuestPDFEquivalente HTML/CSS
.Column()pantalla: flex; flex-dirección: columna
.Row()pantalla: flex; flex-dirección: row
.RelativeItem()flex: 1
<código>.Table()</código>elemento <table>
<código>.PaddingTop(20)</código>padding-top: 20px o <br/>
<código>.AlignCenter()</código>text-align: center
<código>.FontSize(24)</código>tamaño de fuente: 24px
.Bold()font-weight: negrita o <strong>

Conversión de la configuración de página

// QuestPDF
page.Size(PageSizes.A4);
page.Margin(2, Unit.Centimetre);

// IronPDF
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
renderer.RenderingOptions.MarginTop = 20;    // mm (2cm = 20mm)
renderer.RenderingOptions.MarginBottom = 20;
renderer.RenderingOptions.MarginLeft = 20;
renderer.RenderingOptions.MarginRight = 20;
// QuestPDF
page.Size(PageSizes.A4);
page.Margin(2, Unit.Centimetre);

// IronPDF
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
renderer.RenderingOptions.MarginTop = 20;    // mm (2cm = 20mm)
renderer.RenderingOptions.MarginBottom = 20;
renderer.RenderingOptions.MarginLeft = 20;
renderer.RenderingOptions.MarginRight = 20;
$vbLabelText   $csharpLabel

Nuevas capacidades tras la migración

Tras migrar a IronPDF, obtendrá funciones que QuestPDF no puede proporcionarle:

Fusión de PDF

var cover = renderer.RenderHtmlAsPdf("<h1>Cover</h1>");
var content = renderer.RenderHtmlAsPdf(reportHtml);
var existing = PdfDocument.FromFile("appendix.pdf");

var merged = PdfDocument.Merge(cover, content, existing);
merged.SaveAs("complete.pdf");
var cover = renderer.RenderHtmlAsPdf("<h1>Cover</h1>");
var content = renderer.RenderHtmlAsPdf(reportHtml);
var existing = PdfDocument.FromFile("appendix.pdf");

var merged = PdfDocument.Merge(cover, content, existing);
merged.SaveAs("complete.pdf");
$vbLabelText   $csharpLabel

Seguridad en PDF

var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SecuritySettings.OwnerPassword = "admin";
pdf.SecuritySettings.UserPassword = "reader";
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights;
pdf.SaveAs("protected.pdf");
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SecuritySettings.OwnerPassword = "admin";
pdf.SecuritySettings.UserPassword = "reader";
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights;
pdf.SaveAs("protected.pdf");
$vbLabelText   $csharpLabel

URL a PDF

var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.EnableJavaScript = true;

var pdf = renderer.RenderUrlAsPdf("https://example.com/report");
pdf.SaveAs("webpage.pdf");
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.EnableJavaScript = true;

var pdf = renderer.RenderUrlAsPdf("https://example.com/report");
pdf.SaveAs("webpage.pdf");
$vbLabelText   $csharpLabel

Cargar y editar PDF existentes

var pdf = PdfDocument.FromFile("existing.pdf");
// Modify, merge, add security, etc.
pdf.SaveAs("modified.pdf");
var pdf = PdfDocument.FromFile("existing.pdf");
// Modify, merge, add security, etc.
pdf.SaveAs("modified.pdf");
$vbLabelText   $csharpLabel

Resumen comparativo de características

CaracterísticaQuestPDFIronPDF
HTML a PDFNo soportadoCaracterística principal
Curva de aprendizajeDSL propietarioConocimientos web estándar
Vista previa de la plantillaPlugin necesarioCualquier navegador
Colaboración en el diseñoSólo desarrolladoresDiseñadores + Desarrolladores
Activos existentesDebe reconstruirReutilizar HTML/CSS
Manipulación de PDFNo soportadoSoporte completo
Seguridad/FirmaNo soportadoSoporte completo
Modelo de licenciaBasado en los ingresosPor desarrollador
Impacto en el clientePuede necesitar licenciasNinguno
Bootstrap/TailwindNo soportadoSoporte completo
URL a PDFNo soportadoSoporte completo

Lista de comprobación de la migración

Pre-Migración

  • Identificar todas las plantillas de documentos QuestPDF ( Document.Create , .GeneratePdf )
  • Documentar los patrones DSL utilizados ( .Column(), .Row(), <código>.Table()</código>, <código>.Text()</código>)
  • Asignar métodos de estilo a equivalentes CSS
  • Obtenga la clave de licencia deIronPDFen ironpdf.com

Cambios en el paquete

  • Eliminar el paquete NuGet QuestPDF
  • Instalar el paquete NuGet IronPdf : dotnet add package IronPdf

Cambios de código

  • Actualizar las importaciones de espacios de nombres
  • Eliminar QuestPDF.Settings.License = LicenseType.Community
  • Convertir el patrón Document.Create()a ChromePdfRenderer + HTML
  • Reemplazar .Column()/ .Row()con CSS Flexbox
  • Reemplazar <código>.Table()</código>con HTML<table> elementos
  • Convertir .Text().Bold().FontSize(24) a<h1> style="...">
  • Reemplace page.Header() / page.Footer() con TextHeaderFooter
  • Reemplace .CurrentPageNumber() con el marcador de posición {page}
  • Convertir <código>.GeneratePdf()</código>a pdf.SaveAs()
  • Agregar inicialización de licencia al iniciar la aplicación

Posmigración

  • Comparación visual de la salida PDF
  • Pruebe documentos de varias páginas para verificar que los saltos de página sean correctos
  • Agregue nuevas capacidades (seguridad, fusión, URL a PDF) según sea necesario

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