如何用 C# 从 Api2pdf 迁移到 IronPDF
Api2pdf 提供基于云的 PDF 生成服务,但将敏感文档发送到外部服务器可能会导致安全风险、合规性问题以及持续的成本,这些成本会随着时间的推移而累积。本指南详细介绍了从Api2pdf迁移到IronPDF的路径。IronPDF 是一个原生 .NET PDF 库,它完全在您自己的基础设施上处理文档,消除了数据传输方面的顾虑,并将每次转换的成本转化为一次性投资。
为什么考虑从 API2PDF 迁移?
虽然Api2pdf提供了便捷的基于云的 PDF 生成功能,但多种因素促使开发团队寻求本地部署的替代方案来满足其 PDF 生成需求。
安全和合规问题
Api2pdf 是一项基于云的服务,您的敏感 HTML 和文档将被发送到第三方服务器进行处理。 这给处理受监管数据的组织带来了极大的困扰。
| 风险 | Api2pdf | IronPDF |
|---|---|---|
| 数据传输 | 所有发送到外部服务器的内容 | 在您的基础架构上进行本地处理 |
| GDPR 合规性 | 数据跨辖区 | 数据永远不会离开您的环境 |
| HIPAA 合规性 | 外部传输的 PHI | 将 PHI 保留在您的系统中 |
| SOC 2 SOC 2 | 第三方依赖性 | 对数据处理的完全控制 |
| PCI DSS | 可能暴露的银行卡数据 | 无外部传输 |
成本随时间的累积
Api2pdf 无限期收取每次转换约 0.005 美元的费用,而IronPDF则提供一次性永久许可。 对于生成大量 PDF 文件的应用程序来说,成本差异会变得很大:
| 翻译量 | Api2pdf(年度) | IronPdf (一次性) |
|---|---|---|
| 每月 10,000 份 PDF | ~600美元/年 | 749 美元(Lite) |
| 每月 50,000 份 PDF | ~3,000 美元/年 | 749 美元(Lite) |
| 每月 100,000 份 PDF | ~6,000 美元/年 | 1,499 美元(Plus) |
对于大多数生产应用而言,IronPdf 可在数月内收回成本。
性能和可用性
Api2pdf 需要网络往返,每次生成 PDF 请求会增加 2-5 秒的延迟。IronPDF 的本地处理时间为 100-500 毫秒。 此外,IronPdf 可在完全离线和空气屏蔽的环境中工作--这对于不能依赖外部服务可用性的应用程序来说至关重要。
Api2pdf与 IronPDF:主要区别
| 方面 | Api2pdf | IronPDF |
|---|---|---|
| 数据处理 | 发送到第三方云服务器 | 在您的基础设施上进行本地处理 |
| 定价 | 按转换付费(~0.005 美元/PDF) | 一次性永久许可 |
| 延迟 | 2-5 秒(网络往返) | 100-500毫秒(本地处理) |
| 离线 | 不可用 | 完全离线工作 |
| 安装 | API 密钥 + HTTP 客户端 | 简单的 NuGet 软件包</a |
| 合规性 | 关注 GDPR/HIPAA(数据离开网络) | 完全合规控制 |
逐步迁移过程
步骤 1:更新 NuGet 软件包
移除Api2pdf软件包并安装 IronPDF:
# Remove Api2pdf
dotnet remove package Api2Pdf
# Install IronPDF
dotnet add package IronPdf# Remove Api2pdf
dotnet remove package Api2Pdf
# Install IronPDF
dotnet add package IronPdf或通过软件包管理器控制台:
Uninstall-Package Api2Pdf
Install-Package IronPdf步骤 2:更新命名空间引用
用IronPDF替换Api2pdf命名空间:
// Remove these
using Api2Pdf;
using Api2Pdf.DotNet;
// Add these
using IronPdf;
using IronPdf.Rendering;// Remove these
using Api2Pdf;
using Api2Pdf.DotNet;
// Add these
using IronPdf;
using IronPdf.Rendering;步骤 3:配置许可证密钥
在应用程序启动时设置 IronPdf 许可证密钥:
// Set once at application startup
IronPdf.License.LicenseKey = "YOUR-IRONPDF-LICENSE-KEY";
// Or configure via appsettings.json:
// { "IronPdf.LicenseKey": "YOUR-IRONPDF-LICENSE-KEY" }// Set once at application startup
IronPdf.License.LicenseKey = "YOUR-IRONPDF-LICENSE-KEY";
// Or configure via appsettings.json:
// { "IronPdf.LicenseKey": "YOUR-IRONPDF-LICENSE-KEY" }步骤 4:移除 API 密钥配置
IronPDF 可在本地运行,不需要 API 密钥:
// Remove thisApi2pdfpattern
var client = new Api2PdfClient("API_KEY");
// Just create the renderer directly
var renderer = new ChromePdfRenderer();// Remove thisApi2pdfpattern
var client = new Api2PdfClient("API_KEY");
// Just create the renderer directly
var renderer = new ChromePdfRenderer();完整的 API 迁移参考
核心类映射
| Api2pdf 类 | IronPdf 同等产品 | 备注 |
|---|---|---|
| <代码>Api2PdfClient</代码 | <代码>ChromePdfRenderer</代码 | 主渲染类 |
| <代码>Api2PdfResult</代码 | <代码>PDF 文档</代码 | 代表 PDF |
| <代码>无头铬选项</代码 | <代码>ChromePdfRenderOptions</代码 | 渲染配置 |
方法映射
| Api2pdf 方法 | IronPdf 方法 | 备注 |
|---|---|---|
| <代码>client.HeadlessChrome.FromHtmlAsync(html)</代码 | <代码>renderer.RenderHtmlAsPdf(html)</代码 | HTML 转 PDF |
| <代码>client.HeadlessChrome.FromUrlAsync(url)</代码 | <代码>renderer.RenderUrlAsPdf(url)</代码 | URL to PDF |
| <代码>response.Pdf</代码> (URL) | <代码>pdf.SaveAs(路径)</代码 | 保存到文件 |
| <代码>response.Pdf</代码>(下载) | <代码>pdf.BinaryData</代码 | 以字节数组形式获取 |
| <代码>client.PdfSharp.MergePdfsAsync(urls)</代码 | <代码>PdfDocument.Merge(pdfs)</代码 | Merge PDFs |
| <代码>client.PdfSharp.SetPasswordAsync(url, pwd)</ 代码 | <代码>pdf.SecuritySettings.OwnerPassword</代码 | 密码保护 |
渲染选项映射
| Api2pdf 选项 | IronPdf 选项 | 备注 |
|---|---|---|
| <代码>Landscape = true</ 代码 | <代码>RenderingOptions.PaperOrientation = Landscape</代码 | 页面方向 |
| <代码>页面大小 = "A4"</ 代码 | <代码>RenderingOptions.PaperSize = PdfPaperSize.A4</ 代码 | 纸张大小 |
| <代码>PrintBackground = true</ 代码 | <代码>RenderingOptions.PrintHtmlBackgrounds = true</ 代码 | 背景颜色 |
MarginTop 等。 | RenderingOptions.MarginTop 等。 | 边距(毫米 |
| <代码>延迟 = 5000</ 代码 | <代码>RenderingOptions.WaitFor.RenderDelay(5000)</代码 | 呈现前请等待 |
代码迁移示例
HTML 到 PDF 转换
最常见的Api2pdf操作体现了根本性的转变——从云 API 调用到本地处理。
Api2pdf 实现:
// NuGet: Install-Package Api2Pdf.DotNet
using System;
using System.Threading.Tasks;
using Api2Pdf.DotNet;
class Program
{
static async Task Main(string[] args)
{
var a2pClient = new Api2PdfClient("your-api-key");
var apiResponse = await a2pClient.HeadlessChrome.FromHtmlAsync("<h1>Hello World</h1>");
Console.WriteLine(apiResponse.Pdf);
}
}// NuGet: Install-Package Api2Pdf.DotNet
using System;
using System.Threading.Tasks;
using Api2Pdf.DotNet;
class Program
{
static async Task Main(string[] args)
{
var a2pClient = new Api2PdfClient("your-api-key");
var apiResponse = await a2pClient.HeadlessChrome.FromHtmlAsync("<h1>Hello World</h1>");
Console.WriteLine(apiResponse.Pdf);
}
}IronPDF 实现:
// NuGet: Install-Package IronPdf
using System;
using IronPdf;
class Program
{
static void Main(string[] args)
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1>");
pdf.SaveAs("output.pdf");
Console.WriteLine("PDF created successfully");
}
}// NuGet: Install-Package IronPdf
using System;
using IronPdf;
class Program
{
static void Main(string[] args)
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1>");
pdf.SaveAs("output.pdf");
Console.WriteLine("PDF created successfully");
}
}IronPDF 消除了网络往返、API 密钥管理以及Api2pdf基于 URL 的响应模式所需的单独下载步骤。
URL到PDF转换
Api2pdf 实现:
// NuGet: Install-Package Api2Pdf.DotNet
using System;
using System.Threading.Tasks;
using Api2Pdf.DotNet;
class Program
{
static async Task Main(string[] args)
{
var a2pClient = new Api2PdfClient("your-api-key");
var apiResponse = await a2pClient.HeadlessChrome.FromUrlAsync("https://www.example.com");
Console.WriteLine(apiResponse.Pdf);
}
}// NuGet: Install-Package Api2Pdf.DotNet
using System;
using System.Threading.Tasks;
using Api2Pdf.DotNet;
class Program
{
static async Task Main(string[] args)
{
var a2pClient = new Api2PdfClient("your-api-key");
var apiResponse = await a2pClient.HeadlessChrome.FromUrlAsync("https://www.example.com");
Console.WriteLine(apiResponse.Pdf);
}
}IronPDF 实现:
// NuGet: Install-Package IronPdf
using System;
using IronPdf;
class Program
{
static void Main(string[] args)
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderUrlAsPdf("https://www.example.com");
pdf.SaveAs("webpage.pdf");
Console.WriteLine("PDF created from URL successfully");
}
}// NuGet: Install-Package IronPdf
using System;
using IronPdf;
class Program
{
static void Main(string[] args)
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderUrlAsPdf("https://www.example.com");
pdf.SaveAs("webpage.pdf");
Console.WriteLine("PDF created from URL successfully");
}
}将 HTML 文件转换为带选项的 PDF 文件
Api2pdf 实现:
// NuGet: Install-Package Api2Pdf.DotNet
using System;
using System.IO;
using System.Threading.Tasks;
using Api2Pdf.DotNet;
class Program
{
static async Task Main(string[] args)
{
var a2pClient = new Api2PdfClient("your-api-key");
string html = File.ReadAllText("input.html");
var options = new HeadlessChromeOptions
{
Landscape = true,
PrintBackground = true
};
var apiResponse = await a2pClient.HeadlessChrome.FromHtmlAsync(html, options);
Console.WriteLine(apiResponse.Pdf);
}
}// NuGet: Install-Package Api2Pdf.DotNet
using System;
using System.IO;
using System.Threading.Tasks;
using Api2Pdf.DotNet;
class Program
{
static async Task Main(string[] args)
{
var a2pClient = new Api2PdfClient("your-api-key");
string html = File.ReadAllText("input.html");
var options = new HeadlessChromeOptions
{
Landscape = true,
PrintBackground = true
};
var apiResponse = await a2pClient.HeadlessChrome.FromHtmlAsync(html, options);
Console.WriteLine(apiResponse.Pdf);
}
}IronPDF 实现:
// NuGet: Install-Package IronPdf
using System;
using System.IO;
using IronPdf;
class Program
{
static void Main(string[] args)
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperOrientation = IronPdf.Rendering.PdfPaperOrientation.Landscape;
renderer.RenderingOptions.CssMediaType = IronPdf.Rendering.PdfCssMediaType.Print;
string html = File.ReadAllText("input.html");
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
Console.WriteLine("PDF created with options successfully");
}
}// NuGet: Install-Package IronPdf
using System;
using System.IO;
using IronPdf;
class Program
{
static void Main(string[] args)
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperOrientation = IronPdf.Rendering.PdfPaperOrientation.Landscape;
renderer.RenderingOptions.CssMediaType = IronPdf.Rendering.PdfCssMediaType.Print;
string html = File.ReadAllText("input.html");
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
Console.WriteLine("PDF created with options successfully");
}
}IronPdf 直接在渲染器对象上配置渲染选项,而不是将其作为单独的选项参数传递给每个 API 调用。
合并多个 PDF 文件
Api2pdf 实现:
using Api2Pdf.DotNet;
var a2pClient = new Api2PdfClient("YOUR_API_KEY");
var pdfUrls = new List<string>
{
"https://example.com/pdf1.pdf",
"https://example.com/pdf2.pdf",
"https://example.com/pdf3.pdf"
};
var request = new PdfMergeRequest { Urls = pdfUrls };
var response = await a2pClient.PdfSharp.MergePdfsAsync(request);
if (response.Success)
{
// Download merged PDF from response.Pdf URL
}using Api2Pdf.DotNet;
var a2pClient = new Api2PdfClient("YOUR_API_KEY");
var pdfUrls = new List<string>
{
"https://example.com/pdf1.pdf",
"https://example.com/pdf2.pdf",
"https://example.com/pdf3.pdf"
};
var request = new PdfMergeRequest { Urls = pdfUrls };
var response = await a2pClient.PdfSharp.MergePdfsAsync(request);
if (response.Success)
{
// Download merged PDF from response.Pdf URL
}IronPDF 实现:
using IronPdf;
// Load PDFs from files
var pdf1 = PdfDocument.FromFile("document1.pdf");
var pdf2 = PdfDocument.FromFile("document2.pdf");
var pdf3 = PdfDocument.FromFile("document3.pdf");
// Merge all PDFs
var merged = PdfDocument.Merge(pdf1, pdf2, pdf3);
merged.SaveAs("merged.pdf");using IronPdf;
// Load PDFs from files
var pdf1 = PdfDocument.FromFile("document1.pdf");
var pdf2 = PdfDocument.FromFile("document2.pdf");
var pdf3 = PdfDocument.FromFile("document3.pdf");
// Merge all PDFs
var merged = PdfDocument.Merge(pdf1, pdf2, pdf3);
merged.SaveAs("merged.pdf");IronPDF 的静态 Merge 方法可直接接受多个文档,省去了基于 URL 的工作流程。
受密码保护的 PDF 文件
Api2pdf 实现:
using Api2Pdf.DotNet;
var a2pClient = new Api2PdfClient("YOUR_API_KEY");
// Generate PDF first
var pdfResponse = await a2pClient.HeadlessChrome.FromHtmlAsync("<h1>Confidential</h1>");
// Then add password protection in separate call
var protectedResponse = await a2pClient.PdfSharp.SetPasswordAsync(
pdfResponse.Pdf,
"secretpassword"
);using Api2Pdf.DotNet;
var a2pClient = new Api2PdfClient("YOUR_API_KEY");
// Generate PDF first
var pdfResponse = await a2pClient.HeadlessChrome.FromHtmlAsync("<h1>Confidential</h1>");
// Then add password protection in separate call
var protectedResponse = await a2pClient.PdfSharp.SetPasswordAsync(
pdfResponse.Pdf,
"secretpassword"
);IronPDF 实现:
using IronPdf;
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Confidential</h1>");
// Set security in one step
pdf.SecuritySettings.OwnerPassword = "owner123";
pdf.SecuritySettings.UserPassword = "user123";
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.NoPrint;
pdf.SecuritySettings.AllowUserCopyPasteContent = false;
pdf.SecuritySettings.AllowUserEdits = PdfEditSecurity.NoEdit;
pdf.SaveAs("protected.pdf");using IronPdf;
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Confidential</h1>");
// Set security in one step
pdf.SecuritySettings.OwnerPassword = "owner123";
pdf.SecuritySettings.UserPassword = "user123";
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.NoPrint;
pdf.SecuritySettings.AllowUserCopyPasteContent = false;
pdf.SecuritySettings.AllowUserEdits = PdfEditSecurity.NoEdit;
pdf.SaveAs("protected.pdf");IronPDF 通过 SecuritySettings 属性对 PDF 权限进行细粒度控制。
页眉和页脚
Api2pdf 实现:
using Api2Pdf.DotNet;
var a2pClient = new Api2PdfClient("YOUR_API_KEY");
var options = new HeadlessChromeOptions
{
HeaderHtml = "<div style='font-size:10px'>Company Header</div>",
FooterHtml = "<div style='font-size:10px'>Page <span class='pageNumber'></span></div>"
};
var response = await a2pClient.HeadlessChrome.FromHtmlAsync(html, options);using Api2Pdf.DotNet;
var a2pClient = new Api2PdfClient("YOUR_API_KEY");
var options = new HeadlessChromeOptions
{
HeaderHtml = "<div style='font-size:10px'>Company Header</div>",
FooterHtml = "<div style='font-size:10px'>Page <span class='pageNumber'></span></div>"
};
var response = await a2pClient.HeadlessChrome.FromHtmlAsync(html, options);IronPDF 实现:
using IronPdf;
var renderer = new ChromePdfRenderer();
// HTML headers and footers with full styling
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
{
HtmlFragment = "<div style='font-size:10px; text-align:center;'>Company Header</div>",
DrawDividerLine = true
};
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
HtmlFragment = "<div style='font-size:10px; text-align:center;'>Page {page} of {total-pages}</div>",
DrawDividerLine = true
};
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("with-headers.pdf");using IronPdf;
var renderer = new ChromePdfRenderer();
// HTML headers and footers with full styling
renderer.RenderingOptions.HtmlHeader = new HtmlHeaderFooter
{
HtmlFragment = "<div style='font-size:10px; text-align:center;'>Company Header</div>",
DrawDividerLine = true
};
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
HtmlFragment = "<div style='font-size:10px; text-align:center;'>Page {page} of {total-pages}</div>",
DrawDividerLine = true
};
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("with-headers.pdf");IronPdf 支持占位符标记,如用于动态页码的 {page} 和 {total-pages} 。 有关更多选项,请参阅页眉和页脚文档。
ASP.NET Core 集成
Api2pdf 的异步 HTTP 模式与IronPDF的直接生成 PDF 有很大不同。
Api2pdf模式:
[ApiController]
public class PdfController : ControllerBase
{
private readonly Api2PdfClient _client;
public PdfController()
{
_client = new Api2PdfClient("YOUR_API_KEY");
}
[HttpGet("generate")]
public async Task<IActionResult> GeneratePdf()
{
var response = await _client.HeadlessChrome.FromHtmlAsync("<h1>Report</h1>");
if (!response.Success)
return BadRequest(response.Error);
// Redirect to download URL
return Redirect(response.Pdf);
}
}[ApiController]
public class PdfController : ControllerBase
{
private readonly Api2PdfClient _client;
public PdfController()
{
_client = new Api2PdfClient("YOUR_API_KEY");
}
[HttpGet("generate")]
public async Task<IActionResult> GeneratePdf()
{
var response = await _client.HeadlessChrome.FromHtmlAsync("<h1>Report</h1>");
if (!response.Success)
return BadRequest(response.Error);
// Redirect to download URL
return Redirect(response.Pdf);
}
}IronPdf模式:
[ApiController]
public class PdfController : ControllerBase
{
[HttpGet("generate")]
public IActionResult GeneratePdf()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Report</h1>");
// Return PDF directly - no download step needed
return File(pdf.BinaryData, "application/pdf", "report.pdf");
}
[HttpGet("generate-async")]
public async Task<IActionResult> GeneratePdfAsync()
{
var renderer = new ChromePdfRenderer();
var pdf = await renderer.RenderHtmlAsPdfAsync("<h1>Report</h1>");
return File(pdf.Stream, "application/pdf", "report.pdf");
}
}[ApiController]
public class PdfController : ControllerBase
{
[HttpGet("generate")]
public IActionResult GeneratePdf()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf("<h1>Report</h1>");
// Return PDF directly - no download step needed
return File(pdf.BinaryData, "application/pdf", "report.pdf");
}
[HttpGet("generate-async")]
public async Task<IActionResult> GeneratePdfAsync()
{
var renderer = new ChromePdfRenderer();
var pdf = await renderer.RenderHtmlAsPdfAsync("<h1>Report</h1>");
return File(pdf.Stream, "application/pdf", "report.pdf");
}
}IronPdf 通过 BinaryData 或 Stream 直接返回 PDF,消除了从重定向到下载的模式。
依赖注入配置
// Program.cs or Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IPdfService, IronPdfService>();
}
// IPdfService.cs
public interface IPdfService
{
PdfDocument GenerateFromHtml(string html);
Task<PdfDocument> GenerateFromHtmlAsync(string html);
}
// IronPdfService.cs
public class IronPdfService : IPdfService
{
private readonly ChromePdfRenderer _renderer;
public IronPdfService()
{
_renderer = new ChromePdfRenderer();
_renderer.RenderingOptions.PrintHtmlBackgrounds = true;
_renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
}
public PdfDocument GenerateFromHtml(string html) =>
_renderer.RenderHtmlAsPdf(html);
public Task<PdfDocument> GenerateFromHtmlAsync(string html) =>
_renderer.RenderHtmlAsPdfAsync(html);
}// Program.cs or Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IPdfService, IronPdfService>();
}
// IPdfService.cs
public interface IPdfService
{
PdfDocument GenerateFromHtml(string html);
Task<PdfDocument> GenerateFromHtmlAsync(string html);
}
// IronPdfService.cs
public class IronPdfService : IPdfService
{
private readonly ChromePdfRenderer _renderer;
public IronPdfService()
{
_renderer = new ChromePdfRenderer();
_renderer.RenderingOptions.PrintHtmlBackgrounds = true;
_renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
}
public PdfDocument GenerateFromHtml(string html) =>
_renderer.RenderHtmlAsPdf(html);
public Task<PdfDocument> GenerateFromHtmlAsync(string html) =>
_renderer.RenderHtmlAsPdfAsync(html);
}错误处理迁移
Api2pdf 使用响应对象检查。 IronPdf 使用标准的 .NET 异常。
Api2pdf模式:
var response = await a2pClient.HeadlessChrome.FromHtmlAsync(html);
if (!response.Success)
{
Console.WriteLine($"Error: {response.Error}");
return;
}var response = await a2pClient.HeadlessChrome.FromHtmlAsync(html);
if (!response.Success)
{
Console.WriteLine($"Error: {response.Error}");
return;
}IronPdf模式:
try
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
}
catch (IronPdf.Exceptions.IronPdfLicenseException ex)
{
Console.WriteLine($"License error: {ex.Message}");
}
catch (IronPdf.Exceptions.IronPdfRenderingException ex)
{
Console.WriteLine($"Rendering error: {ex.Message}");
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}try
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
}
catch (IronPdf.Exceptions.IronPdfLicenseException ex)
{
Console.WriteLine($"License error: {ex.Message}");
}
catch (IronPdf.Exceptions.IronPdfRenderingException ex)
{
Console.WriteLine($"Rendering error: {ex.Message}");
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}性能比较
| 指标 | Api2pdf | IronPDF |
|---|---|---|
| 简单 HTML | 2-5 秒(网络) | 100-500毫秒(本地) |
| 复杂页面 | 5-10 秒 | 500ms-2s |
| 每批 100 份 | 分钟(费率限制) | 秒(并行) |
| 离线 | 不可用 | 工作内容 |
| 冷启动 | 无 | ~2 秒(第一次渲染) |
性能优化技巧
// 1. Reuse renderer instance
private static readonly ChromePdfRenderer SharedRenderer = new ChromePdfRenderer();
public PdfDocument GeneratePdf(string html)
{
return SharedRenderer.RenderHtmlAsPdf(html);
}
// 2. Parallel generation
var tasks = htmlDocs.Select(html =>
Task.Run(() => SharedRenderer.RenderHtmlAsPdf(html)));
var results = await Task.WhenAll(tasks);
// 3. Disable unnecessary features for speed
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.EnableJavaScript = false; // If not needed
renderer.RenderingOptions.WaitFor.RenderDelay(0); // No delay// 1. Reuse renderer instance
private static readonly ChromePdfRenderer SharedRenderer = new ChromePdfRenderer();
public PdfDocument GeneratePdf(string html)
{
return SharedRenderer.RenderHtmlAsPdf(html);
}
// 2. Parallel generation
var tasks = htmlDocs.Select(html =>
Task.Run(() => SharedRenderer.RenderHtmlAsPdf(html)));
var results = await Task.WhenAll(tasks);
// 3. Disable unnecessary features for speed
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.EnableJavaScript = false; // If not needed
renderer.RenderingOptions.WaitFor.RenderDelay(0); // No delay常见迁移问题的故障排除
问题:PDF 看起来与Api2pdf输出不同
匹配Api2pdf的无头 Chrome 浏览器设置:
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Print;
renderer.RenderingOptions.PrintHtmlBackgrounds = true;
renderer.RenderingOptions.ViewPortWidth = 1280;
renderer.RenderingOptions.EnableJavaScript = true;
renderer.RenderingOptions.WaitFor.RenderDelay(1000);var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Print;
renderer.RenderingOptions.PrintHtmlBackgrounds = true;
renderer.RenderingOptions.ViewPortWidth = 1280;
renderer.RenderingOptions.EnableJavaScript = true;
renderer.RenderingOptions.WaitFor.RenderDelay(1000);问题:外部资源无法加载
配置资源加载超时:
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.WaitFor.AllFontsLoaded(timeout: 10000);
renderer.RenderingOptions.WaitFor.NetworkIdle(timeout: 10000);
// Or use base URL for relative paths
var pdf = renderer.RenderHtmlAsPdf(html, baseUrl: "https://example.com/");var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.WaitFor.AllFontsLoaded(timeout: 10000);
renderer.RenderingOptions.WaitFor.NetworkIdle(timeout: 10000);
// Or use base URL for relative paths
var pdf = renderer.RenderHtmlAsPdf(html, baseUrl: "https://example.com/");问题:PDF 文件大小
生成后压缩图像:
renderer.RenderingOptions.ImageQuality = 80;
// Or compress after generation
pdf.CompressImages(quality: 75);
pdf.SaveAs("compressed.pdf");renderer.RenderingOptions.ImageQuality = 80;
// Or compress after generation
pdf.CompressImages(quality: 75);
pdf.SaveAs("compressed.pdf");迁移后核对表
完成代码迁移后,请验证以下内容:
- 验证 PDF 输出质量是否符合预期
- 测试所有极端情况(大型文档、特殊字符)
- 验证绩效指标(应有显著改善)
- 如果需要,更新 Docker 配置
- 删除Api2pdf门户帐户和 API 密钥
- 更新监控(不再需要跟踪 API 延迟)
- 为你的团队记录新模式
- 更新 CI/CD 流水线
未来保护您的 PDF 基础架构
随着 .NET 10 的临近和 C# 14 引入新的语言特性,选择本地 .NET PDF 库可以确保与不断发展的运行时功能兼容。IronPDF承诺支持最新的 .NET 版本,这意味着当项目扩展到 2025 年和 2026 年时,您的迁移投资将获得回报--而无需不断累积每次转换的成本。
其他资源
从Api2pdf迁移到IronPDF可将您的 PDF 生成从依赖云的按转换成本模式转变为本地的一次性投资。 您的敏感文档将保留在您的基础架构上,延迟时间将从几秒缩短到几毫秒,而且您还可以消除对供应商的依赖性,从而实现这一关键应用功能。






