跳至页脚内容
迁移指南

如何用 C# 从 Nutrient.io 迁移到 IronPDF

从 Nutrient.io(原 PSPDFKit)迁移到IronPDFfor .NET,从具有异步优先模式的复杂文档智能平台迁移到具有直接同步 API 的专注 PDF 库,从而简化了您的 .NET PDF 工作流程。本指南提供了一个全面、逐步的迁移路径,可消除平台开销,同时保持所有基本的 PDF 功能。

为什么要从 Nutrient.io 迁移到 IronPDF.

平台复杂性问题

Nutrient.io(前身为 PSPDFKit)已从 PDF SDK 发展成为一个全面的 "文档智能平台"。这种转变在拓宽功能的同时,也给只需要可靠 PDF 操作的团队带来了巨大的挑战:

1.平台过度设计:曾经的 PDF SDK 现在已经发展成为一个完整的文档智能平台,具有 AI 功能和文档工作流功能,但对于简单的 PDF 任务来说,这些功能可能并不必要。

2.企业定价: Nutrient.io 的目标客户是大型组织,其定价不透明,需要联系销售部门。 这给中小型团队造成了障碍,也使预算规划变得困难。

3.品牌重塑带来的混乱: PSPDFKit → Nutrient 的过渡导致文档中同时出现两个名称,造成文档混乱。软件包名称可能仍然使用 PSPDFKit,过渡期间的迁移路径也尚不明确。

4.异步优先的复杂性: Nutrient.io 中的所有操作都需要 async/await 模式。 即使是简单的操作也需要 PdfProcessor.CreateAsync() 进行初始化,并且基本任务需要异步方法,这会增加同步工作流的开销。

5.依赖项较多:完整平台需要更多资源,软件包占用空间更大,初始化时间更长,并且需要额外的配置。

Nutrient.io 与IronPDF对比

方面 Nutrient.io (PSPDFKit) IronPDF
翻译重点 文档智能平台 PDF 库
定价 企业(联系销售) 透明、公开
结构 复杂的平台 简单库
API 风格 异步优先 同步与异步选项
依赖关系 重型 轻量级
配置 复杂的配置对象 简单明了的属性
学习曲线 陡峭(平台) 温和(库)
目标用户 企业 所有团队规模

对于计划在 2025 年和 2026 年之前采用 .NET 10 和 C# 14 的团队来说,IronPDF 提供了一个更简单的基础,可以干净利落地集成,而不需要完整文档智能平台的开销。


开始之前

前提条件

  1. .NET 环境: .NET Framework 4.6.2+ 或 .NET Core 3.1+ / .NET 5/6/7/8/9+
  2. NuGet 访问权限:能够安装 NuGet 包
  3. IronPDF 许可证:请从ironpdf.com获取您的许可证密钥。

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

许可配置

// 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";
' Add at application startup (Program.vb or Startup.vb)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
$vbLabelText   $csharpLabel

识别 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

完整的 API 参考

初始化映射

Nutrient.io (PSPDFKit) IronPDF
await PdfProcessor.CreateAsync() new ChromePdfRenderer()
processor.Dispose() (自动或手动)
new PdfConfiguration { ... } renderer.RenderingOptions

文档加载映射

Nutrient.io (PSPDFKit) IronPDF
await processor.OpenAsync(path) PdfDocument.FromFile(path)
Document.LoadFromStream(stream) PdfDocument.FromStream(stream)
Document.LoadFromBytes(bytes) new PdfDocument(bytes)

PDF 生成映射

Nutrient.io (PSPDFKit) IronPDF
await processor.GeneratePdfFromHtmlStringAsync(html) renderer.RenderHtmlAsPdf(html)
await processor.GeneratePdfFromUrlAsync(url) renderer.RenderUrlAsPdf(url)
await processor.GeneratePdfFromFileAsync(path) renderer.RenderHtmlFileAsPdf(path)

文档操作映射

Nutrient.io (PSPDFKit) IronPDF
await processor.MergeAsync(docs) PdfDocument.Merge(pdfs)
document.PageCount pdf.PageCount
await document.SaveAsync(path) pdf.SaveAs(path)
document.ToBytes() pdf.BinaryData

注释和水印映射

Nutrient.io (PSPDFKit) IronPDF
await document.AddAnnotationAsync(index, annotation) pdf.ApplyWatermark(html)
new TextAnnotation("text") 水印中的 HTML
annotation.Opacity = 0.5 CSS opacity: 0.5
annotation.FontSize = 48 CSS @@--CODE-5883--@

代码迁移示例

示例 1:HTML 到 PDF 的转换

之前(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");
    }
}
Imports PSPDFKit.Pdf
Imports System.Threading.Tasks

Module Program
    Async Function Main() As Task
        Dim htmlContent As String = "<html><body><h1>Hello World</h1></body></html>"

        Using processor = Await PdfProcessor.CreateAsync()
            Dim document = Await processor.GeneratePdfFromHtmlStringAsync(htmlContent)
            Await document.SaveAsync("output.pdf")
        End Using
    End Function
End Module
$vbLabelText   $csharpLabel

After (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");
    }
}
Imports IronPdf

Class Program
    Shared Sub Main()
        Dim htmlContent As String = "<html><body><h1>Hello World</h1></body></html>"

        Dim renderer As New ChromePdfRenderer()
        Dim pdf = renderer.RenderHtmlAsPdf(htmlContent)
        pdf.SaveAs("output.pdf")
    End Sub
End Class
$vbLabelText   $csharpLabel

Nutrient.io 的方法需要几个异步步骤:创建一个 PdfProcessorawait PdfProcessor.CreateAsync(),然后调用 await processor.GeneratePdfFromHtmlStringAsync(),最后调用 await document.SaveAsync()。 整个方法必须标记为 async Task,处理器需要 using 语句才能正确处置。

IronPDF 大幅简化了这一工作。 创建 ChromePdfRenderer,调用 RenderHtmlAsPdf(),并使用 SaveAs() 保存。 简单操作无需 async/await,无需管理处理器生命周期,也无需 using 代码块。 对于在 PDF 工作流程中不需要异步模式的开发人员来说,这种模式更为直观。 有关其他渲染选项,请参阅 HTML to PDF 文档

示例 2:合并多个 PDF 文件

之前(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");
    }
}
Imports PSPDFKit.Pdf
Imports System.Threading.Tasks
Imports System.Collections.Generic

Class Program
    Shared Async Function Main() As Task
        Using processor = Await PdfProcessor.CreateAsync()

            Dim document1 = Await processor.OpenAsync("document1.pdf")
            Dim document2 = Await processor.OpenAsync("document2.pdf")

            Dim mergedDocument = Await processor.MergeAsync(New List(Of PdfDocument) From {document1, document2})
            Await mergedDocument.SaveAsync("merged.pdf")
        End Using
    End Function
End Class
$vbLabelText   $csharpLabel

After (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");
    }
}
Imports IronPdf
Imports System.Collections.Generic

Class Program
    Shared Sub Main()
        Dim pdf1 = PdfDocument.FromFile("document1.pdf")
        Dim pdf2 = PdfDocument.FromFile("document2.pdf")

        Dim merged = PdfDocument.Merge(pdf1, pdf2)
        merged.SaveAs("merged.pdf")
    End Sub
End Class
$vbLabelText   $csharpLabel

Nutrient.io 合并操作需要创建一个处理器,使用 await PdfProcessor.CreateAsync(),使用单独的 await processor.OpenAsync() 调用打开每个文档,创建一个 List<PdfDocument>,使用该列表调用 await processor.MergeAsync(),最后使用 await mergedDocument.SaveAsync()。 这就是基本合并的五个异步操作。

IronPDF 将此操作简化为四行同步代码:使用 PdfDocument.FromFile() 加载每个 PDF,使用静态 PdfDocument.Merge() 方法合并,然后保存。 无处理器生命周期,无需创建列表(可直接传递文档),无异步开销。 了解有关 合并和拆分 PDF 的更多信息。

示例 3:添加水印

之前(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");
    }
}
Imports PSPDFKit.Pdf
Imports PSPDFKit.Pdf.Annotation
Imports System.Threading.Tasks

Class Program
    Shared Async Function Main() As Task
        Using processor = Await PdfProcessor.CreateAsync()
            Dim document = Await processor.OpenAsync("document.pdf")

            For i As Integer = 0 To document.PageCount - 1
                Dim watermark = New TextAnnotation("CONFIDENTIAL") With {
                    .Opacity = 0.5,
                    .FontSize = 48
                }
                Await document.AddAnnotationAsync(i, watermark)
            Next

            Await document.SaveAsync("watermarked.pdf")
        End Using
    End Function
End Class
$vbLabelText   $csharpLabel

After (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");
    }
}
Imports IronPdf
Imports IronPdf.Editing

Class Program
    Shared Sub Main()
        Dim 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")
    End Sub
End Class
$vbLabelText   $csharpLabel

这个例子突出了一个基本的架构差异。 Nutrient.io 使用基于注解的方法:您创建一个 TextAnnotation 对象,其中包含 OpacityFontSize 等属性,然后遍历每个页面,对每个属性调用 await document.AddAnnotationAsync(i, watermark)。 这就需要了解注释系统并自己管理循环。

IronPDF 使用基于 HTML 的方法: ApplyWatermark() 方法接受带有 CSS 样式的 HTML 字符串。 水印会在一次调用中自动应用到所有页面。 您可以通过熟悉的 CSS 属性(coloropacityfont-size)来控制外观,而不是通过特定于注释的对象属性。 这种方法提供了更大的样式灵活性--您可以使用任何 HTML/CSS,包括渐变、图像和复杂布局。 请参阅水印文档以获取更高级的示例。


关键迁移说明

同步到同步转换

最大的改动是删除了不必要的 async/await 模式:

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

// IronPDF: Sync by default (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: Sync by default (async available when needed)
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
Imports System
Imports System.Threading.Tasks

' Nutrient.io: Async-first
Using processor = Await PdfProcessor.CreateAsync()
    Dim document = Await processor.GeneratePdfFromHtmlStringAsync(html)
    Await document.SaveAsync("output.pdf")
End Using

' IronPDF: Sync by default (async available when needed)
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("output.pdf")
$vbLabelText   $csharpLabel

如果您确实需要异步操作,IronPDF 提供了异步变体,例如 RenderHtmlAsPdfAsync()

消除处理器生命周期

Nutrient.io 需要创建和处理处理器:

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

' Nutrient.io: Processor lifecycle management
Using processor = Await PdfProcessor.CreateAsync()
    ' ... use processor ...
    ' Processor disposed at end of using block
End Using

' IronPDF: No processor lifecycle
Dim renderer As New ChromePdfRenderer()
' Reuse renderer, no complex lifecycle management
$vbLabelText   $csharpLabel

配置模式更改

Nutrient.io 使用配置对象;IronPDF使用属性:

// 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);
Imports System.Threading.Tasks

' Nutrient.io: Config object
Dim config As New PdfConfiguration With {
    .PageSize = PageSize.A4,
    .Margins = New Margins(20, 20, 20, 20)
}
Dim doc = Await processor.GeneratePdfFromHtmlStringAsync(html, config)

' IronPDF: Properties on RenderingOptions
Dim renderer As New ChromePdfRenderer()
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4
renderer.RenderingOptions.MarginTop = 20
renderer.RenderingOptions.MarginBottom = 20
renderer.RenderingOptions.MarginLeft = 20
renderer.RenderingOptions.MarginRight = 20
Dim pdf = renderer.RenderHtmlAsPdf(html)
$vbLabelText   $csharpLabel

注释到 HTML 水印

用 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>"
' Nutrient.io: Annotation object with properties
New TextAnnotation("CONFIDENTIAL") With {.Opacity = 0.5F, .FontSize = 48}

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

页码处理

Nutrient.io 需要手动计算页数;IronPDF已内置占位符:

// 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}"
};
' Nutrient.io: Manual loop and page counting
For i As Integer = 0 To doc.PageCount - 1
    Dim footer = New TextAnnotation($"Page {i + 1} of {doc.PageCount}")
    Await doc.AddAnnotationAsync(i, footer)
Next

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

故障排除

问题 1:未找到 PdfProcessor

问题:IronPDF中不存在 PdfProcessor 类。

解决方案:使用 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();
' Nutrient.io
Using processor = Await PdfProcessor.CreateAsync()

' IronPDF
Dim renderer = New ChromePdfRenderer()
$vbLabelText   $csharpLabel

问题 2:GeneratePdfFromHtmlStringAsync 未找到

问题:不存在异步 HTML 方法。

解决方案:使用 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);
' Nutrient.io
Dim document = Await processor.GeneratePdfFromHtmlStringAsync(html)

' IronPDF
Dim pdf = renderer.RenderHtmlAsPdf(html)
$vbLabelText   $csharpLabel

问题 3:未找到文本注释

问题:IronPDF中不存在注释类。

解决方案:使用基于 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>");
Imports System.Threading.Tasks

' Nutrient.io
Dim watermark As New TextAnnotation("DRAFT") With {.Opacity = 0.5}
Await document.AddAnnotationAsync(0, watermark)

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

问题 4:未找到 MergeAsync

问题:不存在异步合并方法。

解决方案:使用静态 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);
Imports System.Threading.Tasks

' Nutrient.io
Dim mergedDocument = Await processor.MergeAsync(documentList)

' IronPDF
Dim merged = PdfDocument.Merge(pdf1, pdf2)
$vbLabelText   $csharpLabel

迁移清单

迁移前

  • 清点代码库中所有 PSPDFKit/营养素的使用情况
  • 记录可能需要调整的异步模式 列出所有配置对象及其属性
  • 识别基于标注的特征(水印、标题)
  • 审查表单处理要求
  • 获取IronPDF许可证密钥

软件包变更

  • 删除 PSPDFKit.NET NuGet 包
  • 删除 Nutrient NuGet 包 安装 IronPdf NuGet 包:dotnet add package IronPdf
  • 更新命名空间导入

代码更改

  • 在启动时添加许可证密钥配置
  • PdfProcessor.CreateAsync() 替换为 new ChromePdfRenderer()
  • processor.GeneratePdfFromHtmlStringAsync() 替换为 renderer.RenderHtmlAsPdf()
  • processor.MergeAsync() 替换为 PdfDocument.Merge()
  • TextAnnotation 水印转换为 HTML 水印
  • 将配置对象替换为 RenderingOptions 属性
  • 更新页眉/页脚,使用 HtmlHeaderFooter 并带占位符
  • 删除不必要的 async/await 模式

后迁移

  • 移除不再需要的 async/await
  • 运行回归测试,比较 PDF 输出
  • 核对页眉/页脚的页码
  • 测试水印渲染
  • 更新 CI/CD 流水线

Curtis Chau
技术作家

Curtis Chau 拥有卡尔顿大学的计算机科学学士学位,专注于前端开发,精通 Node.js、TypeScript、JavaScript 和 React。他热衷于打造直观且美观的用户界面,喜欢使用现代框架并创建结构良好、视觉吸引力强的手册。

除了开发之外,Curtis 对物联网 (IoT) 有浓厚的兴趣,探索将硬件和软件集成的新方法。在空闲时间,他喜欢玩游戏和构建 Discord 机器人,将他对技术的热爱与创造力相结合。

钢铁支援团队

我们每周 5 天,每天 24 小时在线。
聊天
电子邮件
打电话给我