Passer au contenu du pied de page
GUIDES DE MIGRATION

Comment migrer de Nutrient.io à IronPDF en C#

La migration de Nutrient.io (anciennement PSPDFKit) versIronPDFsimplifie votre flux de travail PDF .NET en passant d'une plateforme d'intelligence documentaire complexe avec des modèles asynchrones d'abord à une bibliothèque PDF ciblée avec des API synchrones directes. Ce guide fournit un chemin de migration complet, étape par étape, qui élimine la surcharge de la plateforme tout en conservant toutes les fonctionnalités PDF essentielles.

Pourquoi migrer de Nutrient.io à IronPDF

Le problème de la complexité des plateformes

Nutrient.io (anciennement PSPDFKit) est passé d'un SDK PDF à une "plateforme d'intelligence documentaire" complète Bien que cette transformation élargisse les capacités, elle introduit des défis importants pour les équipes qui ont simplement besoin d'opérations PDF fiables :

  1. Sur-ingénierie de la plateforme : ce qui était autrefois un SDK PDF est maintenant une plateforme complète d'intelligence documentaire avec des fonctionnalités d'IA et des capacités de flux de travail documentaire qui peuvent être inutiles pour les tâches PDF simples.

  2. Tarification pour entreprises : Nutrient.io est conçu pour les grandes organisations dont la tarification opaque nécessite de contacter le service commercial. Cela crée des obstacles pour les petites et moyennes équipes et rend la planification du budget difficile.

  3. Confusion liée au changement de nom : La transition de PSPDFKit à Nutrient a engendré des problèmes de documentation, les deux noms étant toujours mentionnés. Les noms de paquets peuvent encore utiliser PSPDFKit, et les procédures de migration restent floues.

  4. Complexité axée sur l'asynchrone : tout dans Nutrient.io nécessite des modèles async/await. Même les opérations simples nécessitent PdfProcessor.CreateAsync() pour l'initialisation et des méthodes asynchrones pour les tâches de base, ce qui augmente la charge de travail pour les flux de travail synchrones.

  5. Dépendances importantes : La plateforme complète nécessite plus de ressources, avec une empreinte mémoire plus importante, un temps d'initialisation plus long et une configuration supplémentaire.

Comparaison entreIronPDFet Nutrient.io

Aspect Nutrient.io (PSPDFKit) IronPDF
Objectif Plate-forme d'intelligence documentaire Bibliothèque PDF
Tarifs Entreprise (contacter les ventes) Transparent, publié
Architecture Plateforme complexe Bibliothèque simple
Style API Async-first Syncavec options asynchrones
Dépendances Lourdeur Léger
Configuration Objets de configuration complexes Propriétés simples
Courbe d'apprentissage Steep (plateforme) Gentle (bibliothèque)
Utilisateurs cibles Entreprise Toutes tailles d'équipe

Pour les équipes qui prévoient l'adoption de .NET 10 et C# 14 d'ici 2025 et 2026,IronPDFconstitue une base plus simple qui s'intègre proprement sans les frais généraux d'une plateforme complète d'intelligence documentaire.


Avant de commencer

Prérequis

  1. Environnement .NET : .NET Framework 4.6.2+ ou .NET Core 3.1+ / .NET 5/6/7/8/9+
  2. Accès à NuGet : possibilité d'installer des packages NuGet
  3. Licence IronPDF : Obtenez votre clé de licence sur ironpdf.com

Modifications du paquet 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

Configurationde la licence

// 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

Identifier l'utilisation 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

Référence API complète

Mappages d'initialisation

Nutrient.io (PSPDFKit) IronPDF Notes
await PdfProcessor.CreateAsync() new ChromePdfRenderer() Pas d'asynchronisme nécessaire
processeur.Dispose() la traduction doit rester professionnelle, tout en préservant la précision technique et en expliquant les caractéristiques et les avantages de ces outils de développement Un cycle de vie plus simple
nouvelle configuration Pdf { ... } renderer.RenderingOptions Basé sur la propriété

Mappages de chargement de documents

Nutrient.io (PSPDFKit) IronPDF Notes
await processor.OpenAsync(path) PdfDocument.FromFile(path) Synchronisation par défaut
Document.LoadFromStream(stream) PdfDocument.FromStream(stream) Support de flux
Document.LoadFromBytes(bytes) new PdfDocument(bytes) Tableau d'octets

Mappages de génération de PDF

Nutrient.io (PSPDFKit) IronPDF Notes
await processor.GeneratePdfFromHtmlStringAsync(html) renderer.RenderHtmlAsPdf(html) Méthode de synchronisation
await processor.GeneratePdfFromUrlAsync(url) renderer.RenderUrlAsPdf(url) URL directe
await processor.GeneratePdfFromFileAsync(path) renderer.RenderHtmlFileAsPdf(path) Fichier HTML

Mise en correspondance des opérations sur les documents

Nutrient.io (PSPDFKit) IronPDF Notes
await processor.MergeAsync(docs) PdfDocument.Merge(pdfs) Sync
document.PageCount pdf.PageCount Même modèle
await document.SaveAsync(path) pdf.SaveAs(path) Sync
document.ToBytes() pdf.BinaryData Tableau d'octets

Mappages d'annotations et de filigranes

Nutrient.io (PSPDFKit) IronPDF Notes
await document.AddAnnotationAsync(index, annotation) pdf.ApplyWatermark(html) Basé sur HTML
new TextAnnotation("text") HTML en filigrane Plus flexible
annotation.Opacity = 0.5 CSS opacité : 0.5 Style CSS
annotation.FontSize = 48 CSS font-size : 48px Style CSS

Exemples de migration de code

Exemple 1 : Conversion HTML vers PDF

Avant (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

Aprè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

L'approche de Nutrient.io nécessite plusieurs étapes asynchrones : la création d'un PdfProcessor avec await PdfProcessor.CreateAsync(), puis l'appel de await processor.GeneratePdfFromHtmlStringAsync(), et enfin await document.SaveAsync(). La méthode entière doit être marquée async Task, et le processeur nécessite une déclaration using pour une élimination correcte.

IronPDF simplifie considérablement cette tâche. Créez un ChromePdfRenderer, appelez RenderHtmlAsPdf() et enregistrez avec SaveAs(). Aucun async/await n'est requis, aucun cycle de vie de processeur n'est à gérer et aucun bloc utilisant n'est nécessaire pour les opérations simples. Ce modèle est plus intuitif pour les développeurs qui n'ont pas besoin de modèles asynchrones pour leur flux de travail PDF. Voir la documentation HTML vers PDF pour des options de rendu supplémentaires.

Exemple 2 : Fusionner plusieurs PDF

Avant (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

Aprè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

L'opération de fusion de Nutrient.io nécessite la création d'un processeur avec await PdfProcessor.CreateAsync(), l'ouverture de chaque document avec des appels await processor.OpenAsync() distincts, la création d'une List<PdfDocument>, l'appel de await processor.MergeAsync() avec cette liste, et enfin await mergedDocument.SaveAsync(). Cela représente cinq opérations asynchrones pour une fusion de base.

IronPDF réduit cela à quatre lignes synchrones : charger chaque PDF avec PdfDocument.FromFile(), fusionner avec la méthode statique PdfDocument.Merge(), et enregistrer. Pas de cycle de vie du processeur, pas de création de liste nécessaire (vous pouvez passer les documents directement), et pas de surcharge asynchrone. En savoir plus sur la fusion et la division de PDF.

Exemple 3 : Ajout de filigranes

Avant (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

Aprè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

Cet exemple met en évidence une différence architecturale fondamentale. Nutrient.io utilise une approche basée sur les annotations : vous créez un objet TextAnnotation avec des propriétés telles que Opacity et FontSize , puis vous parcourez chaque page en appelant await document.AddAnnotationAsync(i, watermark) pour chacune d'elles. Cela implique de comprendre le système d'annotation et de gérer soi-même la boucle.

IronPDF utilise une approche basée sur HTML : la méthode ApplyWatermark() accepte une chaîne HTML avec un style CSS. Le filigrane est automatiquement appliqué à toutes les pages en un seul appel. Vous contrôlez l'apparence par le biais de propriétés CSS familières (color, opacity, font-size) plutôt que par des propriétés d'objets spécifiques aux annotations. Cette approche offre une plus grande souplesse de style : vous pouvez utiliser n'importe quel code HTML/CSS, y compris des dégradés, des images et des mises en page complexes. Consultez la documentation sur les filigranes pour des exemples avancés.


Notesde migration essentielles

Conversion asynchrone vers synchrone

Le changement le plus important consiste à supprimer les modèles async/await inutiles :

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

// IronPDF: Synchronisation par défaut(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: Synchronisation par défaut(async available when needed)
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
$vbLabelText   $csharpLabel

Si vous avez besoin d'opérations asynchrones, IronPdf fournit des variantes asynchrones comme RenderHtmlAsPdfAsync().

Élimination du cycle de vie du processeur

Nutrient.io nécessite la création et l'élimination de processeurs :

// 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

Modification du modèle de configuration

Nutrient.io utilise des objets de configuration ;IronPDFutilise des propriétés :

// 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

Annotation en filigrane HTML

Remplacer les objets d'annotation par des chaînes 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

Gestion des numéros de page

Nutrient.io nécessite un comptage manuel des pages ;IronPDFdispose de caractères de remplacement intégrés :

// 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

Dépannage

Édition 1 : PdfProcessor introuvable

Problème : la classe PdfProcessor n'existe pas dans IronPDF.

Solution : Utiliser 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

Sujet 2 : GeneratePdfFromHtmlStringAsync introuvable

Problème : La méthode HTML asynchrone n'existe pas.

Solution : Utilisez 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

Sujet 3 : TextAnnotation Not Found

Problème : les classes d'annotations n'existent pas dans IronPDF.

Solution : Utiliser des filigranes 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

Edition 4 : MergeAsync introuvable

Problème : La méthode de fusion asynchrone n'existe pas.

Solution : Utiliser la méthode statique PdfDocument.Merge() :

// 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

Liste de contrôle de la migration

Pré-migration

  • Inventorier toutes les utilisations de PSPDFKit/Nutrient dans le code source
  • Documenter les modèles asynchrones qui pourraient nécessiter des ajustements
  • Lister tous les objets de configuration et leurs propriétés
  • Identifier les caractéristiques basées sur les annotations (filigranes, en-têtes)
  • Examiner les exigences de traitement des formulaires
  • Obtenir une clé de licence IronPDF

Modifications du paquet

  • Supprimer le package NuGet PSPDFKit.NET
  • Supprimer le package NuGet Nutrient
  • Installez le package NuGet IronPdf : dotnet add package IronPdf
  • Mettre à jour les importations d'espace de noms

Modifications du code

  • Ajouter la configuration de la clé de licence au démarrage
  • Remplacez PdfProcessor.CreateAsync() par new ChromePdfRenderer()
  • Remplacez processor.GeneratePdfFromHtmlStringAsync() par renderer.RenderHtmlAsPdf()
  • Remplacer processor.MergeAsync() par PdfDocument.Merge()
  • Convertir les filigranes TextAnnotation en filigranes HTML
  • Remplacer les objets de configuration par les propriétés RenderingOptions
  • Mettre à jour l'en-tête et le pied de page pour utiliser HtmlHeaderFooter avec des espaces réservés.
  • Supprimer les modèles async/await inutiles

Après la migration

  • Supprimez les blocs async/await lorsqu'ils ne sont plus nécessaires.
  • Effectuer des tests de régression comparant les résultats PDF
  • Vérifier que les en-têtes et pieds de page correspondent aux numéros de page
  • Test du rendu du filigrane
  • Mise à jour du pipeline CI/CD

Curtis Chau
Rédacteur technique

Curtis Chau détient un baccalauréat en informatique (Université de Carleton) et se spécialise dans le développement front-end avec expertise en Node.js, TypeScript, JavaScript et React. Passionné par la création d'interfaces utilisateur intuitives et esthétiquement plaisantes, Curtis aime travailler avec des frameworks modernes ...

Lire la suite