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

Cómo migrar de Nutrient.io a IronPDF en C#

La migración de Nutrient.io (anteriormente PSPDFKit) aIronPDFsimplifica su flujo de trabajo PDF .NET al pasar de una compleja plataforma de inteligencia de documentos con patrones asíncronos a una biblioteca PDF centrada con API síncronas directas. Esta guía proporciona una ruta de migración completa, paso a paso, que elimina la sobrecarga de la plataforma al tiempo que mantiene todas las capacidades esenciales de PDF.

Por qué migrar de Nutrient.io a IronPDF

El problema de la complejidad de la plataforma

Nutrient.io (antes PSPDFKit) ha pasado de ser un SDK de PDF a una completa "plataforma de inteligencia documental" Aunque esta transformación amplía las capacidades, introduce retos significativos para los equipos que simplemente necesitan operaciones de PDF fiables:

  1. Sobreingeniería de plataforma: lo que alguna vez fue un SDK de PDF ahora es una plataforma de inteligencia de documentos completa con funciones de IA y capacidades de flujo de trabajo de documentos que pueden ser innecesarias para tareas de PDF sencillas.

  2. Precios empresariales: Nutrient.io está posicionado para grandes organizaciones con precios opacos que requieren contactar al departamento de ventas. Esto crea barreras para los equipos pequeños y medianos y dificulta la planificación del presupuesto.

  3. Confusión sobre el cambio de marca: La transición de PSPDFKit a Nutrient ha generado problemas de documentación donde existen referencias a ambos nombres. Es posible que los nombres de los paquetes aún usen PSPDFKit, y las rutas de migración durante la transición siguen siendo confusas.

  4. Complejidad asíncrona primero: todo en Nutrient.io requiere patrones asíncronos/en espera. Incluso las operaciones sencillas necesitan PdfProcessor.CreateAsync() para la inicialización y métodos asíncronos para las tareas básicas, lo que añade sobrecarga a los flujos de trabajo síncronos.

  5. Dependencias pesadas: la plataforma completa requiere más recursos con una mayor huella de paquetes, más tiempo de inicialización y configuración adicional.

Comparación entre Nutrient.io y IronPDF

AspectoNutrient.io (PSPDFKit)IronPDF
EnfoquePlataforma de inteligencia documentalBiblioteca PDF
PreciosEmpresa (póngase en contacto con ventas)Transparente, publicado
ArquitecturaPlataforma complejaBiblioteca sencilla
Estilo APIAsync-firstSincronización con opciones asíncronas
DependenciasPesadoLigero
ConfiguraciónObjetos de configuración complejosPropiedades sencillas
Curva de aprendizajeSteep (plataforma)Gentle (biblioteca)
Usuarios objetivoEmpresaTodos los tamaños de equipo

Para los equipos que planifican la adopción de .NET 10 y C# 14 hasta 2025 y 2026,IronPDFproporciona una base más sencilla que se integra limpiamente sin la sobrecarga de una plataforma completa de inteligencia documental.


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 Nutrient/PSPDFKit packages
dotnet remove package PSPDFKit.NET
dotnet remove package PSPDFKit.PDF
dotnet remove package Nutrient
dotnet remove package Nutrient.PDF

# Install IronPDF
dotnet add package IronPdf
# Remove Nutrient/PSPDFKit packages
dotnet remove package PSPDFKit.NET
dotnet remove package PSPDFKit.PDF
dotnet remove package Nutrient
dotnet remove package Nutrient.PDF

# Install IronPDF
dotnet add package IronPdf
SHELL

Configuración de licencias

// Add at application startup (Program.cs or Startup.cs)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// Add at application startup (Program.cs or Startup.cs)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
$vbLabelText   $csharpLabel

Identificar el uso de Nutrient.io

# Find all Nutrient/PSPDFKit references
grep -r "PSPDFKit\|Nutrient\|PdfProcessor\|PdfConfiguration" --include="*.cs" .
# Find all Nutrient/PSPDFKit references
grep -r "PSPDFKit\|Nutrient\|PdfProcessor\|PdfConfiguration" --include="*.cs" .
SHELL

Referencia completa de la API

Mapas de inicialización

Nutrient.io (PSPDFKit)IronPDFNotas
esperar PdfProcessor.CreateAsync()<código>new ChromePdfRenderer()</códigoNo se requiere async
<código>processor.Dispose()</código>(automático o manual)_Ciclo de vida más sencillo
nueva PdfConfiguration { ... }<código>renderer.RenderingOptions</códigoBasado en propiedades

Mapas de carga de documentos

Nutrient.io (PSPDFKit)IronPDFNotas
<código>await processor.OpenAsync(path)</código<código>PdfDocument.FromFile(path)</códigoSincronización por defecto
Document.LoadFromStream(stream)<código>PdfDocument.FromStream(stream)</códigoSoporte técnico
<código>Document.LoadFromBytes(bytes)</códigonuevo PdfDocument(bytes)Matriz de bytes

Mapas de generación de PDF

Nutrient.io (PSPDFKit)IronPDFNotas
await processor.GeneratePdfFromHtmlStringAsync(html)renderer.RenderHtmlAsPdf(html)Método de sincronización
await processor.GeneratePdfFromUrlAsync(url)<código>renderer.RenderUrlAsPdf(url)</códigoURL directa
await processor.GeneratePdfFromFileAsync(path)<código>renderer.RenderHtmlFileAsPdf(ruta)</códigoArchivo HTML

Mapeo de operaciones documentales

Nutrient.io (PSPDFKit)IronPDFNotas
await processor.MergeAsync(docs)<código>PdfDocument.Merge(pdfs)</códigoSincronización
document.PageCount<código>pdf.PageCount</códigoMismo patrón
await document.SaveAsync(path)<código>pdf.SaveAs(ruta)</códigoSincronización
document.ToBytes()<código>pdf.BinaryData</códigoMatriz de bytes

Mapas de anotaciones y marcas de agua

Nutrient.io (PSPDFKit)IronPDFNotas
await document.AddAnnotationAsync(index, annotation)<código>pdf.ApplyWatermark(html)</códigoBasado en HTML
<código>new TextAnnotation("texto")</códigoHTML en marca de aguaMás flexibilidad
<código>annotation.Opacity = 0.5</códigoCSS opacidad: 0,5Estilo CSS
annotation.FontSize = 48CSS tamaño de fuente: 48pxEstilo CSS

Ejemplos de migración de código

Ejemplo 1: Conversión de HTML a PDF

Antes (Nutrient.io):

// NuGet: Install-Package PSPDFKit.Dotnet
using PSPDFKit.Pdf;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        var htmlContent = "<html><body><h1>Hello World</h1></body></html>";

        using var processor = await PdfProcessor.CreateAsync();
        var document = await processor.GeneratePdfFromHtmlStringAsync(htmlContent);
        await document.SaveAsync("output.pdf");
    }
}
// NuGet: Install-Package PSPDFKit.Dotnet
using PSPDFKit.Pdf;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        var htmlContent = "<html><body><h1>Hello World</h1></body></html>";

        using var processor = await PdfProcessor.CreateAsync();
        var document = await processor.GeneratePdfFromHtmlStringAsync(htmlContent);
        await document.SaveAsync("output.pdf");
    }
}
$vbLabelText   $csharpLabel

Después (IronPDF):

// NuGet: Install-Package IronPdf
using IronPdf;

class Program
{
    static void Main()
    {
        var htmlContent = "<html><body><h1>Hello World</h1></body></html>";

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

class Program
{
    static void Main()
    {
        var htmlContent = "<html><body><h1>Hello World</h1></body></html>";

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

El enfoque de Nutrient.io requiere varios pasos asíncronos: crear un PdfProcessor con await PdfProcessor.CreateAsync(), luego llamar a await processor.GeneratePdfFromHtmlStringAsync(), y finalmente await document.SaveAsync(). Todo el método debe estar marcado como async Task, y el procesador requiere una declaración using para su correcta eliminación.

IronPDF simplifica esta tarea drásticamente. Crea un ChromePdfRenderer, llama a RenderHtmlAsPdf() y guarda con SaveAs(). No se requiere async/await, no hay que gestionar el ciclo de vida del procesador y no se necesitan bloques use para operaciones sencillas. Este patrón es más intuitivo para los desarrolladores que no necesitan patrones asíncronos para su flujo de trabajo PDF. Consulte la documentación HTML a PDF para obtener más opciones de conversión.

Ejemplo 2: Fusión de varios PDF

Antes (Nutrient.io):

// NuGet: Install-Package PSPDFKit.Dotnet
using PSPDFKit.Pdf;
using System.Threading.Tasks;
using System.Collections.Generic;

class Program
{
    static async Task Main()
    {
        using var processor = await PdfProcessor.CreateAsync();

        var document1 = await processor.OpenAsync("document1.pdf");
        var document2 = await processor.OpenAsync("document2.pdf");

        var mergedDocument = await processor.MergeAsync(new List<PdfDocument> { document1, document2 });
        await mergedDocument.SaveAsync("merged.pdf");
    }
}
// NuGet: Install-Package PSPDFKit.Dotnet
using PSPDFKit.Pdf;
using System.Threading.Tasks;
using System.Collections.Generic;

class Program
{
    static async Task Main()
    {
        using var processor = await PdfProcessor.CreateAsync();

        var document1 = await processor.OpenAsync("document1.pdf");
        var document2 = await processor.OpenAsync("document2.pdf");

        var mergedDocument = await processor.MergeAsync(new List<PdfDocument> { document1, document2 });
        await mergedDocument.SaveAsync("merged.pdf");
    }
}
$vbLabelText   $csharpLabel

Después (IronPDF):

// NuGet: Install-Package IronPdf
using IronPdf;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        var pdf1 = PdfDocument.FromFile("document1.pdf");
        var pdf2 = PdfDocument.FromFile("document2.pdf");

        var merged = PdfDocument.Merge(pdf1, pdf2);
        merged.SaveAs("merged.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        var pdf1 = PdfDocument.FromFile("document1.pdf");
        var pdf2 = PdfDocument.FromFile("document2.pdf");

        var merged = PdfDocument.Merge(pdf1, pdf2);
        merged.SaveAs("merged.pdf");
    }
}
$vbLabelText   $csharpLabel

La operación de fusión de Nutrient.io requiere crear un procesador con await PdfProcessor.CreateAsync(), abrir cada documento con llamadas separadas a await processor.OpenAsync(), crear una List<PdfDocument>, llamar a await processor.MergeAsync() con esa lista y, por último, await mergedDocument.SaveAsync(). Son cinco operaciones asíncronas para una fusión básica.

IronPDF reduce esto a cuatro líneas síncronas: cargar cada PDF con PdfDocument.FromFile(), fusionar con el método estático PdfDocument.Merge() y guardar. No hay ciclo de vida del procesador, no es necesario crear listas (se pueden pasar documentos directamente) y no hay sobrecarga asíncrona. Más información sobre mezclar y dividir archivos PDF.

Ejemplo 3: Añadir marcas de agua

Antes (Nutrient.io):

// NuGet: Install-Package PSPDFKit.Dotnet
using PSPDFKit.Pdf;
using PSPDFKit.Pdf.Annotation;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        using var processor = await PdfProcessor.CreateAsync();
        var document = await processor.OpenAsync("document.pdf");

        for (int i = 0; i < document.PageCount; i++)
        {
            var watermark = new TextAnnotation("CONFIDENTIAL")
            {
                Opacity = 0.5,
                FontSize = 48
            };
            await document.AddAnnotationAsync(i, watermark);
        }

        await document.SaveAsync("watermarked.pdf");
    }
}
// NuGet: Install-Package PSPDFKit.Dotnet
using PSPDFKit.Pdf;
using PSPDFKit.Pdf.Annotation;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        using var processor = await PdfProcessor.CreateAsync();
        var document = await processor.OpenAsync("document.pdf");

        for (int i = 0; i < document.PageCount; i++)
        {
            var watermark = new TextAnnotation("CONFIDENTIAL")
            {
                Opacity = 0.5,
                FontSize = 48
            };
            await document.AddAnnotationAsync(i, watermark);
        }

        await document.SaveAsync("watermarked.pdf");
    }
}
$vbLabelText   $csharpLabel

Después (IronPDF):

// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Editing;

class Program
{
    static void Main()
    {
        var pdf = PdfDocument.FromFile("document.pdf");

        pdf.ApplyWatermark("<h1 style='color:gray;opacity:0.5;'>CONFIDENTIAL</h1>",
            50,
            VerticalAlignment.Middle,
            HorizontalAlignment.Center);

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

class Program
{
    static void Main()
    {
        var pdf = PdfDocument.FromFile("document.pdf");

        pdf.ApplyWatermark("<h1 style='color:gray;opacity:0.5;'>CONFIDENTIAL</h1>",
            50,
            VerticalAlignment.Middle,
            HorizontalAlignment.Center);

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

Este ejemplo pone de relieve una diferencia arquitectónica fundamental. Nutrient.io utiliza un enfoque basado en anotaciones: crea un objeto TextAnnotation con propiedades como Opacity y FontSize , luego recorre cada página llamando await document.AddAnnotationAsync(i, watermark) para cada una. Esto requiere comprender el sistema de anotaciones y manejar el bucle uno mismo.

IronPDF utiliza un enfoque basado en HTML: el método ApplyWatermark() acepta una cadena HTML con estilo CSS. La marca de agua se aplica automáticamente a todas las páginas en una sola llamada. La apariencia se controla mediante propiedades CSS conocidas (color, opacidad, tamaño de fuente) en lugar de propiedades de objeto específicas de la anotación. Este enfoque ofrece más flexibilidad de estilo: se puede utilizar cualquier HTML/CSS, incluidos degradados, imágenes y diseños complejos. Consulte la documentación de la marca de agua para ver ejemplos avanzados.


Notas de migración críticas

Conversión de Async a Sync

El cambio más significativo es la eliminación de patrones async/await innecesarios:

// Nutrient.io: Async-first
using var processor = await PdfProcessor.CreateAsync();
var document = await processor.GeneratePdfFromHtmlStringAsync(html);
await document.SaveAsync("output.pdf");

// IronPDF: Sincronización por defecto(async available when needed)
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
// Nutrient.io: Async-first
using var processor = await PdfProcessor.CreateAsync();
var document = await processor.GeneratePdfFromHtmlStringAsync(html);
await document.SaveAsync("output.pdf");

// IronPDF: Sincronización por defecto(async available when needed)
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
$vbLabelText   $csharpLabel

Si necesita operaciones asíncronas,IronPDFproporciona variantes asíncronas como RenderHtmlAsPdfAsync().

Eliminación del ciclo de vida del procesador

Nutrient.io requiere la creación y eliminación de procesadores:

// Nutrient.io: Processor lifecycle management
using var processor = await PdfProcessor.CreateAsync();
// ... use processor ...
// Processor disposed at end of using block

// IronPDF: No processor lifecycle
var renderer = new ChromePdfRenderer();
// Reuse renderer, no complex lifecycle management
// Nutrient.io: Processor lifecycle management
using var processor = await PdfProcessor.CreateAsync();
// ... use processor ...
// Processor disposed at end of using block

// IronPDF: No processor lifecycle
var renderer = new ChromePdfRenderer();
// Reuse renderer, no complex lifecycle management
$vbLabelText   $csharpLabel

Cambio de patrón de configuración

Nutrient.io utiliza objetos de configuración;IronPDFutiliza propiedades:

// Nutrient.io: Config object
var config = new PdfConfiguration
{
    PageSize = PageSize.A4,
    Margins = new Margins(20, 20, 20, 20)
};
var doc = await processor.GeneratePdfFromHtmlStringAsync(html, config);

// IronPDF: Properties on RenderingOptions
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
renderer.RenderingOptions.MarginTop = 20;
renderer.RenderingOptions.MarginBottom = 20;
renderer.RenderingOptions.MarginLeft = 20;
renderer.RenderingOptions.MarginRight = 20;
var pdf = renderer.RenderHtmlAsPdf(html);
// Nutrient.io: Config object
var config = new PdfConfiguration
{
    PageSize = PageSize.A4,
    Margins = new Margins(20, 20, 20, 20)
};
var doc = await processor.GeneratePdfFromHtmlStringAsync(html, config);

// IronPDF: Properties on RenderingOptions
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
renderer.RenderingOptions.MarginTop = 20;
renderer.RenderingOptions.MarginBottom = 20;
renderer.RenderingOptions.MarginLeft = 20;
renderer.RenderingOptions.MarginRight = 20;
var pdf = renderer.RenderHtmlAsPdf(html);
$vbLabelText   $csharpLabel

Marcas de agua de anotación a HTML

Sustituya los objetos de anotación por cadenas HTML:

// Nutrient.io: Annotation object with properties
new TextAnnotation("CONFIDENTIAL") { Opacity = 0.5f, FontSize = 48 }

// IronPDF: HTML with CSS
"<h1 style='opacity:0.5; font-size:48px;'>CONFIDENTIAL</h1>"
// Nutrient.io: Annotation object with properties
new TextAnnotation("CONFIDENTIAL") { Opacity = 0.5f, FontSize = 48 }

// IronPDF: HTML with CSS
"<h1 style='opacity:0.5; font-size:48px;'>CONFIDENTIAL</h1>"
$vbLabelText   $csharpLabel

Manejo de números de página

Nutrient.io requiere recuento manual de páginas;IronPDFtiene marcadores de posición integrados:

// Nutrient.io: Manual loop and page counting
for (int i = 0; i < doc.PageCount; i++)
{
    var footer = new TextAnnotation($"Page {i + 1} of {doc.PageCount}");
    await doc.AddAnnotationAsync(i, footer);
}

// IronPDF: Built-in placeholders
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
    HtmlFragment = "Page {page} of {total-pages}"
};
// Nutrient.io: Manual loop and page counting
for (int i = 0; i < doc.PageCount; i++)
{
    var footer = new TextAnnotation($"Page {i + 1} of {doc.PageCount}");
    await doc.AddAnnotationAsync(i, footer);
}

// IronPDF: Built-in placeholders
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
    HtmlFragment = "Page {page} of {total-pages}"
};
$vbLabelText   $csharpLabel

Solución de problemas

Cuestión 1: PdfProcessor no encontrado

Problema: la clase PdfProcessor no existe en IronPDF.

Solución: utilice ChromePdfRenderer :

// Nutrient.io
using var processor = await PdfProcessor.CreateAsync();

// IronPDF
var renderer = new ChromePdfRenderer();
// Nutrient.io
using var processor = await PdfProcessor.CreateAsync();

// IronPDF
var renderer = new ChromePdfRenderer();
$vbLabelText   $csharpLabel

Asunto 2: GeneratePdfFromHtmlStringAsync Not Found

Problema: el método HTML asíncrono no existe.

Solución: utilice RenderHtmlAsPdf() :

// Nutrient.io
var document = await processor.GeneratePdfFromHtmlStringAsync(html);

// IronPDF
var pdf = renderer.RenderHtmlAsPdf(html);
// Nutrient.io
var document = await processor.GeneratePdfFromHtmlStringAsync(html);

// IronPDF
var pdf = renderer.RenderHtmlAsPdf(html);
$vbLabelText   $csharpLabel

Asunto 3: TextAnnotation Not Found

Problema: Las clases de anotación no existen en IronPDF.

Solución: utilice marcas de agua basadas en HTML:

// Nutrient.io
var watermark = new TextAnnotation("DRAFT") { Opacity = 0.5 };
await document.AddAnnotationAsync(0, watermark);

// IronPDF
pdf.ApplyWatermark("<div style='opacity:0.5;'>DRAFT</div>");
// Nutrient.io
var watermark = new TextAnnotation("DRAFT") { Opacity = 0.5 };
await document.AddAnnotationAsync(0, watermark);

// IronPDF
pdf.ApplyWatermark("<div style='opacity:0.5;'>DRAFT</div>");
$vbLabelText   $csharpLabel

Edición 4: MergeAsync no encontrado

Problema: el método de combinación asíncrona no existe.

Solución: utilice PdfDocument.Merge() estático:

// Nutrient.io
var mergedDocument = await processor.MergeAsync(documentList);

// IronPDF
var merged = PdfDocument.Merge(pdf1, pdf2);
// Nutrient.io
var mergedDocument = await processor.MergeAsync(documentList);

// IronPDF
var merged = PdfDocument.Merge(pdf1, pdf2);
$vbLabelText   $csharpLabel

Lista de comprobación de la migración

Pre-Migración

  • Inventariar todos los usos de PSPDFKit/Nutrient en el código base
  • Documentar patrones asincrónicos que puedan necesitar ajustes
  • Enumere todos los objetos de configuración y sus propiedades
  • Identificar características basadas en anotaciones (marcas de agua, encabezados)
  • Revisar los requisitos de manejo de formularios
  • Obtener la clave de licencia de IronPDF

Cambios en el paquete

  • Eliminar el paquete NuGet de PSPDFKit.NET
  • Eliminar el paquete Nutrient NuGet
  • Instalar el paquete NuGet IronPdf : dotnet add package IronPdf
  • Actualizar las importaciones de espacios de nombres

Cambios de código

  • Agregar configuración de clave de licencia al inicio
  • Reemplace PdfProcessor.CreateAsync() con new ChromePdfRenderer()
  • Reemplace processor.GeneratePdfFromHtmlStringAsync() con renderer.RenderHtmlAsPdf()
  • Reemplazar processor.MergeAsync() con PdfDocument.Merge()
  • Convertir marcas de agua TextAnnotation en marcas de agua HTML
  • Reemplazar los objetos de configuración con propiedades RenderingOptions
  • Actualizar el encabezado/pie de página para usar HtmlHeaderFooter con marcadores de posición
  • Eliminar patrones async/await innecesarios

Posmigración

  • Eliminar async/await donde ya no sea necesario
  • Ejecutar pruebas de regresión comparando la salida PDF
  • Verificar encabezados/pies de página con números de página
  • Prueba de representación de marca de agua
  • Actualizar la canalización de CI/CD

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