迁移指南 如何用 C# 从 Nutrient.io 迁移到 IronPDF Curtis Chau 已发布:2026年1月25日 下载 IronPDF NuGet 下载 DLL 下载 Windows 安装程序 免费试用 法学硕士副本 法学硕士副本 将页面复制为 Markdown 格式,用于 LLMs 在 ChatGPT 中打开 向 ChatGPT 咨询此页面 在双子座打开 向 Gemini 询问此页面 在 Grok 中打开 向 Grok 询问此页面 打开困惑 向 Perplexity 询问有关此页面的信息 分享 在 Facebook 上分享 分享到 X(Twitter) 在 LinkedIn 上分享 复制链接 电子邮件文章 从 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 提供了一个更简单的基础,可以干净利落地集成,而不需要完整文档智能平台的开销。 开始之前 前提条件 .NET 环境: .NET Framework 4.6.2+ 或 .NET Core 3.1+ / .NET 5/6/7/8/9+ NuGet 访问权限:能够安装 NuGet 包 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"; $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 备注 等待 PdfProcessor.CreateAsync() new ChromePdfRenderer() 无需异步 processor.Dispose() (自动或手动) 更简单的生命周期 new PdfConfiguration { ... } renderer.RenderingOptions 基于属性 文档加载映射 Nutrient.io (PSPDFKit) IronPDF 备注 等待处理器.OpenAsync(路径) PdfDocument.FromFile(路径) 默认同步 Document.LoadFromStream(stream) PdfDocument.FromStream(流) 流支持 Document.LoadFromBytes(字节) new PdfDocument(字节) 字节数组 PDF 生成映射 Nutrient.io (PSPDFKit) IronPDF 备注 等待处理器.GeneratePdfFromHtmlStringAsync(html) renderer.RenderHtmlAsPdf(html) 同步方法 await processor.GeneratePdfFromUrlAsync(url)<br renderer.RenderUrlAsPdf(url) 直接 URL await processor.GeneratePdfFromFileAsync(path) renderer.RenderHtmlFileAsPdf(path) HTML 文件 文档操作映射 Nutrient.io (PSPDFKit) IronPDF 备注 等待处理器.MergeAsync(docs) PdfDocument.Merge(pdfs) 同步 document.PageCount pdf.PageCount 相同模式 等待 document.SaveAsync(path) pdf.SaveAs(路径) 同步 document.ToBytes() pdf.BinaryData 字节数组 注释和水印映射 Nutrient.io (PSPDFKit) IronPDF 备注 等待 document.AddAnnotationAsync(index, annotation) pdf.ApplyWatermark(html) 基于 HTML new TextAnnotation("text") 水印中的 HTML 更灵活 annotation.Opacity = 0.5 CSS 不透明度:0.5 CSS 定型 annotation.FontSize = 48 CSS font-size: 48px CSS 定型 代码迁移示例 示例 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"); } } $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"); } } $vbLabelText $csharpLabel Nutrient.io 方法需要几个异步步骤:使用等待 PdfProcessor.CreateAsync()创建 PdfProcessor ,然后调用 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"); } } $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"); } } $vbLabelText $csharpLabel Nutrient.io 的合并操作需要使用等待 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"); } } $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"); } } $vbLabelText $csharpLabel 这个例子突出了一个基本的架构差异。 Nutrient.io 使用基于注释的方法:您创建一个TextAnnotation对象,其中包含Opacity和FontSize等属性,然后遍历每个页面,对每个页面调用await document.AddAnnotationAsync(i, watermark) 。 这就需要了解注释系统并自己管理循环。 IronPDF 使用基于 HTML 的方法: ApplyWatermark()方法接受带有 CSS 样式的 HTML 字符串。 水印会在一次调用中自动应用到所有页面。 您可以通过熟悉的 CSS 属性(color、opacity、font-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:默认同步(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:默认同步(async available when needed) var renderer = new ChromePdfRenderer(); var 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 $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); $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>" $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}" }; $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(); $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); $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>"); $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); $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 机器人,将他对技术的热爱与创造力相结合。 相关文章 已发布2026年2月1日 如何用 C# 从 ZetPDF 迁移到 IronPDF 通过这本完整的 C# 指南,掌握从 ZetPDF 到 IronPDF 的迁移。从基于坐标的库转换到现代的 HTML 到 PDF 解决方案。包括 HTML 转换、合并 PDF 和移除 PDFSharp 依赖性的代码示例。 阅读更多 已发布2026年2月1日 如何用 C# 从 Scryber.Core 迁移到 IronPDF 通过这本完整的 C# 指南,掌握从 Scryber.Core 迁移到 IronPDF 的方法。从自定义 XML/HTML 解析转换到现代 Chromium 渲染器。包括 HTML 转换、URL 呈现和替换专有绑定的代码示例。 阅读更多 已发布2026年2月1日 如何用 C# 从 XFINIUM.PDF 迁移到 IronPDF 通过这本完整的 C# 指南,掌握从 XFINIUM.PDF 到 IronPDF 的迁移。从基于坐标的手动定位切换到声明式 HTML/CSS 渲染。包括替换图形基元和自动布局的代码示例。 阅读更多 如何用 C# 从 PDFBolt 迁移到 IronPDF如何在 C# 中从 NReco PDF 生...
已发布2026年2月1日 如何用 C# 从 ZetPDF 迁移到 IronPDF 通过这本完整的 C# 指南,掌握从 ZetPDF 到 IronPDF 的迁移。从基于坐标的库转换到现代的 HTML 到 PDF 解决方案。包括 HTML 转换、合并 PDF 和移除 PDFSharp 依赖性的代码示例。 阅读更多
已发布2026年2月1日 如何用 C# 从 Scryber.Core 迁移到 IronPDF 通过这本完整的 C# 指南,掌握从 Scryber.Core 迁移到 IronPDF 的方法。从自定义 XML/HTML 解析转换到现代 Chromium 渲染器。包括 HTML 转换、URL 呈现和替换专有绑定的代码示例。 阅读更多
已发布2026年2月1日 如何用 C# 从 XFINIUM.PDF 迁移到 IronPDF 通过这本完整的 C# 指南,掌握从 XFINIUM.PDF 到 IronPDF 的迁移。从基于坐标的手动定位切换到声明式 HTML/CSS 渲染。包括替换图形基元和自动布局的代码示例。 阅读更多