
如何在 NET MAUI 中将 XAML 转换为 PDF
为什么要从 pdforge 迁移到 IronPDF?
了解 pdforge
pdforge(在2026年重新命名为"pdf noodle"——pdfnoodle.com; 即使通过301重定向,api.pdforge.com 主机名也会一直有效,直到2026年底)是一个基于云的、模板驱动的PDF生成API,通过HTTP调用集成到您的应用程序中,提供了一种简便的方法来生成PDF文件。 没有在NuGet上提供官方的.NET SDK——集成是通过对记录的REST端点使用HttpClient进行的。 通过将 PDF 创建任务卸载到外部 API,开发人员可以简化开发流程。 不过,pdforge 也存在一些缺点,如外部依赖性、有限的定制选项和持续的订阅成本,开发人员应对此有所了解。
云 API 依赖性问题
pdforge 在外部云服务器上处理所有文件。 这种架构给生产应用程序带来了重大问题:
1.外部服务器处理:您生成的每个 PDF 都需要将您的 HTML/数据发送到 pdforge 的服务器——您的文档将离开您的基础架构。
2.隐私和合规风险:敏感数据通过互联网传输到第三方服务器。 使用 pdforge 时,开发人员需要考虑到与向外部 API 发送数据有关的安全问题。 如果 PDF 内容包含敏感信息,这可能是一个关键的考虑因素。
3.持续订阅成本:每月费用无限期累积,且不涉及资产所有权。pdforge 的 SaaS 模式引入了持续的运营支出,这些支出会随着时间的推移而累积。
4.网络依赖性:网络不可用时无法生成 PDF 文件。
5.速率限制: API 使用上限可能会限制高流量应用程序。
6.网络延迟:往返时间会使每次 PDF 生成增加几秒钟。
pdforge 与IronPDF对比
| 特征 | pdforge | IronPDF |
|---|---|---|
| 部署类型 | 基于云的 API | 本地库 |
| 依赖关系 | 需要互联网和 API 认证 | 无外部依赖性 |
| 定制 | 对 PDF 生成的控制有限 | 完全控制定制 |
| 成本结构 | 持续订阅 | 一次性购买选项 |
| 安全性 | 通过网络发送数据的潜在问题 | 完全在本地环境中进行数据处理 |
| 设置复杂性 | 外部处理使初始设置更简单 | 需要更多的初始设置和配置 |
IronPDF 的与众不同之处在于它提供了一个完全本地化的库,使开发人员能够完全控制 PDF 创建过程。 这对于希望在内部处理文件或外部 API 调用引入安全问题的应用程序尤其有利。IronPDF在本地处理所有内容,将此类风险降至最低。
对于计划在当前.NET版本上采用.NET 10和C# 14的团队,IronPDF提供了一个消除云依赖的本地处理基础,同时增加了全面的PDF操作能力。
开始之前
前提条件
- .NET 环境: .NET Framework 4.6.2+ 或 .NET Core 3.1+ / .NET 5/6/7/8/9+
- NuGet 访问权限:能够安装 NuGet 包
- IronPDF 许可证:请从ironpdf.com获取您的许可证密钥。
NuGet 软件包变更
# pdforge has no official .NET SDK on NuGet — integration is HttpClient + JSON.
# If your project depends only on built-in System.Net.Http, there is no
# competitor package to remove. Just install IronPDF:
dotnet add package IronPdf
许可配置
// 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"' Add at application startup (Program.vb or Startup.vb)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"确定 pdforge 的用法
# Find pdforge / pdf noodle endpoint usage
grep -r "api\.pdforge\.com\|api\.pdfnoodle\.com" --include="*.cs" .
# Find API key / Bearer token references
grep -r "pdfnoodle_api_\|pdforge_api_" --include="*.cs" --include="*.json" --include="*.config" .
# Find Chromium header/footer templates that need migrating
grep -r "totalPages\|pageNumber\|footerTemplate\|headerTemplate" --include="*.cs" .
完整的 API 参考
命名空间变更
// Before: pdforge — raw HttpClient against api.pdfnoodle.com
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
// After: IronPDF
using IronPdf;
using IronPdf.Rendering;// Before: pdforge — raw HttpClient against api.pdfnoodle.com
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
// After: IronPDF
using IronPdf;
using IronPdf.Rendering;Imports System.Net.Http
Imports System.Net.Http.Headers
Imports System.Text
Imports System.Text.Json
Imports IronPdf
Imports IronPdf.RenderingImports System.Net.Http
Imports System.Net.Http.Headers
Imports System.Text
Imports System.Text.Json
Imports IronPdf
Imports IronPdf.Rendering核心概念映射
| pdforge (REST) | IronPDF |
|---|---|
HttpClient + Authorization: Bearer pdfnoodle_api_... | new ChromePdfRenderer() |
POST https://api.pdfnoodle.com/v1/html-to-pdf/sync | renderer.RenderHtmlAsPdf(html) |
JSON body { html, pdfParams } | ChromePdfRenderer + RenderingOptions |
Response: JSON envelope with signedUrl | PdfDocument |
Return: byte[] (after fetching signedUrl) | pdf.BinaryData |
操作映射
| pdforge | IronPDF |
|---|---|
POST /v1/html-to-pdf/sync with { html } | renderer.RenderHtmlAsPdf(html) |
| 获取URL,然后POST其HTML(没有专用的URL端点) | renderer.RenderUrlAsPdf(url) |
Download signedUrl then File.WriteAllBytes(path, bytes) | pdf.SaveAs(path) |
await http.GetByteArrayAsync(signedUrl) | pdf.BinaryData |
配置映射
pdforge pdfParams | IronPDF (渲染选项) |
|---|---|
format: "A4" | renderer.RenderingOptions.PaperSize = PdfPaperSize.A4 |
landscape: true | renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape |
margin: { top: "20px" } | renderer.RenderingOptions.MarginTop = 20 |
footerTemplate with <span class="pageNumber"> / <span class="totalPages"> | TextFooter = new TextHeaderFooter { CenterText = "Page {page} of {total-pages}" } |
pdforge 中没有的新功能
| IronPDF 特点 | 说明 |
|---|---|
PdfDocument.Merge() | 合并多个 PDF |
pdf.ExtractAllText() | 从 PDF 中提取文本 |
pdf.ApplyWatermark() | 添加水印 |
pdf.SecuritySettings | 密码保护 |
pdf.Form | 表格填写 |
pdf.SignWithDigitalSignature() | 数字签名 |
代码迁移示例
示例 1:HTML 字符串到 PDF 的转换
之前(pdforge):
// REST API — no .NET SDK on NuGet. Integration is HttpClient + JSON POST.
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", "pdfnoodle_api_YOUR_KEY");
var body = new { html = "<html><body><h1>Hello World</h1></body></html>" };
var json = new StringContent(JsonSerializer.Serialize(body), Encoding.UTF8, "application/json");
var resp = await http.PostAsync("https://api.pdfnoodle.com/v1/html-to-pdf/sync", json);
resp.EnsureSuccessStatusCode();
using var doc = JsonDocument.Parse(await resp.Content.ReadAsStringAsync());
var pdfBytes = await http.GetByteArrayAsync(doc.RootElement.GetProperty("signedUrl").GetString());
File.WriteAllBytes("output.pdf", pdfBytes);
}
}// REST API — no .NET SDK on NuGet. Integration is HttpClient + JSON POST.
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", "pdfnoodle_api_YOUR_KEY");
var body = new { html = "<html><body><h1>Hello World</h1></body></html>" };
var json = new StringContent(JsonSerializer.Serialize(body), Encoding.UTF8, "application/json");
var resp = await http.PostAsync("https://api.pdfnoodle.com/v1/html-to-pdf/sync", json);
resp.EnsureSuccessStatusCode();
using var doc = JsonDocument.Parse(await resp.Content.ReadAsStringAsync());
var pdfBytes = await http.GetByteArrayAsync(doc.RootElement.GetProperty("signedUrl").GetString());
File.WriteAllBytes("output.pdf", pdfBytes);
}
}Imports System.IO
Imports System.Net.Http
Imports System.Net.Http.Headers
Imports System.Text
Imports System.Text.Json
Imports System.Threading.Tasks
Module Program
Async Function Main() As Task
Using http As New HttpClient()
http.DefaultRequestHeaders.Authorization = New AuthenticationHeaderValue("Bearer", "pdfnoodle_api_YOUR_KEY")
Dim body = New With {.html = "<html><body><h1>Hello World</h1></body></html>"}
Dim json As New StringContent(JsonSerializer.Serialize(body), Encoding.UTF8, "application/json")
Dim resp = Await http.PostAsync("https://api.pdfnoodle.com/v1/html-to-pdf/sync", json)
resp.EnsureSuccessStatusCode()
Using doc = JsonDocument.Parse(Await resp.Content.ReadAsStringAsync())
Dim pdfBytes = Await http.GetByteArrayAsync(doc.RootElement.GetProperty("signedUrl").GetString())
File.WriteAllBytes("output.pdf", pdfBytes)
End Using
End Using
End Function
End ModuleImports System.IO
Imports System.Net.Http
Imports System.Net.Http.Headers
Imports System.Text
Imports System.Text.Json
Imports System.Threading.Tasks
Module Program
Async Function Main() As Task
Using http As New HttpClient()
http.DefaultRequestHeaders.Authorization = New AuthenticationHeaderValue("Bearer", "pdfnoodle_api_YOUR_KEY")
Dim body = New With {.html = "<html><body><h1>Hello World</h1></body></html>"}
Dim json As New StringContent(JsonSerializer.Serialize(body), Encoding.UTF8, "application/json")
Dim resp = Await http.PostAsync("https://api.pdfnoodle.com/v1/html-to-pdf/sync", json)
resp.EnsureSuccessStatusCode()
Using doc = JsonDocument.Parse(Await resp.Content.ReadAsStringAsync())
Dim pdfBytes = Await http.GetByteArrayAsync(doc.RootElement.GetProperty("signedUrl").GetString())
File.WriteAllBytes("output.pdf", pdfBytes)
End Using
End Using
End Function
End ModuleAfter (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var html = "<html><body><h1>Hello World</h1></body></html>";
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
}
}// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var html = "<html><body><h1>Hello World</h1></body></html>";
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");
}
}Imports IronPdf
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
Dim html = "<html><body><h1>Hello World</h1></body></html>"
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("output.pdf")
End Sub
End ClassImports IronPdf
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
Dim html = "<html><body><h1>Hello World</h1></body></html>"
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("output.pdf")
End Sub
End Class这里的根本区别在于处理模型和返回类型。 pdforge需要经过认证的HttpClient POST到https://api.pdfnoodle.com/v1/html-to-pdf/sync,这将返回一个包含签名的S3 URL的JSON信封——然后您从该URL获取PDF字节并通过File.WriteAllBytes()写入。
IronPDF使用PdfDocument对象。 此对象可以直接通过pdf.BinaryData。 在保存之前,PdfDocument还允许操作(添加水印、与其他PDF合并、添加安全性)。 请参阅 HTML 转 PDF 文档,了解全面的示例。
示例 2:URL 到 PDF 的转换
之前(pdforge):
// REST API — no .NET SDK on NuGet. pdforge has no dedicated URL endpoint;
// fetch the page yourself and POST its HTML to /v1/html-to-pdf/sync.
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", "pdfnoodle_api_YOUR_KEY");
var sourceHtml = await http.GetStringAsync("https://example.com");
var body = new { html = sourceHtml };
var json = new StringContent(JsonSerializer.Serialize(body), Encoding.UTF8, "application/json");
var resp = await http.PostAsync("https://api.pdfnoodle.com/v1/html-to-pdf/sync", json);
resp.EnsureSuccessStatusCode();
using var doc = JsonDocument.Parse(await resp.Content.ReadAsStringAsync());
var pdfBytes = await http.GetByteArrayAsync(doc.RootElement.GetProperty("signedUrl").GetString());
File.WriteAllBytes("webpage.pdf", pdfBytes);
}
}// REST API — no .NET SDK on NuGet. pdforge has no dedicated URL endpoint;
// fetch the page yourself and POST its HTML to /v1/html-to-pdf/sync.
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", "pdfnoodle_api_YOUR_KEY");
var sourceHtml = await http.GetStringAsync("https://example.com");
var body = new { html = sourceHtml };
var json = new StringContent(JsonSerializer.Serialize(body), Encoding.UTF8, "application/json");
var resp = await http.PostAsync("https://api.pdfnoodle.com/v1/html-to-pdf/sync", json);
resp.EnsureSuccessStatusCode();
using var doc = JsonDocument.Parse(await resp.Content.ReadAsStringAsync());
var pdfBytes = await http.GetByteArrayAsync(doc.RootElement.GetProperty("signedUrl").GetString());
File.WriteAllBytes("webpage.pdf", pdfBytes);
}
}Imports System.IO
Imports System.Net.Http
Imports System.Net.Http.Headers
Imports System.Text
Imports System.Text.Json
Imports System.Threading.Tasks
Module Program
Async Function Main() As Task
Using http As New HttpClient()
http.DefaultRequestHeaders.Authorization = New AuthenticationHeaderValue("Bearer", "pdfnoodle_api_YOUR_KEY")
Dim sourceHtml As String = Await http.GetStringAsync("https://example.com")
Dim body = New With {Key .html = sourceHtml}
Dim json As New StringContent(JsonSerializer.Serialize(body), Encoding.UTF8, "application/json")
Dim resp As HttpResponseMessage = Await http.PostAsync("https://api.pdfnoodle.com/v1/html-to-pdf/sync", json)
resp.EnsureSuccessStatusCode()
Using doc As JsonDocument = JsonDocument.Parse(Await resp.Content.ReadAsStringAsync())
Dim pdfBytes As Byte() = Await http.GetByteArrayAsync(doc.RootElement.GetProperty("signedUrl").GetString())
File.WriteAllBytes("webpage.pdf", pdfBytes)
End Using
End Using
End Function
End ModuleImports System.IO
Imports System.Net.Http
Imports System.Net.Http.Headers
Imports System.Text
Imports System.Text.Json
Imports System.Threading.Tasks
Module Program
Async Function Main() As Task
Using http As New HttpClient()
http.DefaultRequestHeaders.Authorization = New AuthenticationHeaderValue("Bearer", "pdfnoodle_api_YOUR_KEY")
Dim sourceHtml As String = Await http.GetStringAsync("https://example.com")
Dim body = New With {Key .html = sourceHtml}
Dim json As New StringContent(JsonSerializer.Serialize(body), Encoding.UTF8, "application/json")
Dim resp As HttpResponseMessage = Await http.PostAsync("https://api.pdfnoodle.com/v1/html-to-pdf/sync", json)
resp.EnsureSuccessStatusCode()
Using doc As JsonDocument = JsonDocument.Parse(Await resp.Content.ReadAsStringAsync())
Dim pdfBytes As Byte() = Await http.GetByteArrayAsync(doc.RootElement.GetProperty("signedUrl").GetString())
File.WriteAllBytes("webpage.pdf", pdfBytes)
End Using
End Using
End Function
End ModuleAfter (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderUrlAsPdf("https://example.com");
pdf.SaveAs("webpage.pdf");
}
}// NuGet: Install-Package IronPdf
using IronPdf;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderUrlAsPdf("https://example.com");
pdf.SaveAs("webpage.pdf");
}
}Imports IronPdf
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderUrlAsPdf("https://example.com")
pdf.SaveAs("webpage.pdf")
End Sub
End ClassImports IronPdf
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderUrlAsPdf("https://example.com")
pdf.SaveAs("webpage.pdf")
End Sub
End Classpdforge没有专用的URL到PDF端点 - 您自己获取页面,然后将其HTML发布到同步端点,并从返回的签名URL下载结果。 IronPDF在PdfDocument。
IronPDF 的主要优势在于使用 Chromium 引擎在本地获取和渲染 URL,而不会将数据发送到外部服务器。IronPDF作为一个本地库,可能会提供更好的性能,因为网络请求不涉及往返时间。 了解有关 URL 至 PDF 转换的更多信息。
示例 3:使用自定义设置将 HTML 文件转换为 PDF 文件
之前(pdforge):
// REST API — no .NET SDK on NuGet. Page size / orientation flow through the
// optional `pdfParams` object using Chromium/Puppeteer-style names.
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", "pdfnoodle_api_YOUR_KEY");
var htmlContent = File.ReadAllText("input.html");
var body = new { html = htmlContent, pdfParams = new { format = "A4", landscape = true } };
var json = new StringContent(JsonSerializer.Serialize(body), Encoding.UTF8, "application/json");
var resp = await http.PostAsync("https://api.pdfnoodle.com/v1/html-to-pdf/sync", json);
resp.EnsureSuccessStatusCode();
using var doc = JsonDocument.Parse(await resp.Content.ReadAsStringAsync());
var pdfBytes = await http.GetByteArrayAsync(doc.RootElement.GetProperty("signedUrl").GetString());
File.WriteAllBytes("output.pdf", pdfBytes);
}
}// REST API — no .NET SDK on NuGet. Page size / orientation flow through the
// optional `pdfParams` object using Chromium/Puppeteer-style names.
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", "pdfnoodle_api_YOUR_KEY");
var htmlContent = File.ReadAllText("input.html");
var body = new { html = htmlContent, pdfParams = new { format = "A4", landscape = true } };
var json = new StringContent(JsonSerializer.Serialize(body), Encoding.UTF8, "application/json");
var resp = await http.PostAsync("https://api.pdfnoodle.com/v1/html-to-pdf/sync", json);
resp.EnsureSuccessStatusCode();
using var doc = JsonDocument.Parse(await resp.Content.ReadAsStringAsync());
var pdfBytes = await http.GetByteArrayAsync(doc.RootElement.GetProperty("signedUrl").GetString());
File.WriteAllBytes("output.pdf", pdfBytes);
}
}Imports System.IO
Imports System.Net.Http
Imports System.Net.Http.Headers
Imports System.Text
Imports System.Text.Json
Imports System.Threading.Tasks
Module Program
Async Function Main() As Task
Using http As New HttpClient()
http.DefaultRequestHeaders.Authorization = New AuthenticationHeaderValue("Bearer", "pdfnoodle_api_YOUR_KEY")
Dim htmlContent As String = File.ReadAllText("input.html")
Dim body = New With {
.html = htmlContent,
.pdfParams = New With {
.format = "A4",
.landscape = True
}
}
Dim json As New StringContent(JsonSerializer.Serialize(body), Encoding.UTF8, "application/json")
Dim resp As HttpResponseMessage = Await http.PostAsync("https://api.pdfnoodle.com/v1/html-to-pdf/sync", json)
resp.EnsureSuccessStatusCode()
Using doc As JsonDocument = JsonDocument.Parse(Await resp.Content.ReadAsStringAsync())
Dim pdfBytes As Byte() = Await http.GetByteArrayAsync(doc.RootElement.GetProperty("signedUrl").GetString())
File.WriteAllBytes("output.pdf", pdfBytes)
End Using
End Using
End Function
End ModuleImports System.IO
Imports System.Net.Http
Imports System.Net.Http.Headers
Imports System.Text
Imports System.Text.Json
Imports System.Threading.Tasks
Module Program
Async Function Main() As Task
Using http As New HttpClient()
http.DefaultRequestHeaders.Authorization = New AuthenticationHeaderValue("Bearer", "pdfnoodle_api_YOUR_KEY")
Dim htmlContent As String = File.ReadAllText("input.html")
Dim body = New With {
.html = htmlContent,
.pdfParams = New With {
.format = "A4",
.landscape = True
}
}
Dim json As New StringContent(JsonSerializer.Serialize(body), Encoding.UTF8, "application/json")
Dim resp As HttpResponseMessage = Await http.PostAsync("https://api.pdfnoodle.com/v1/html-to-pdf/sync", json)
resp.EnsureSuccessStatusCode()
Using doc As JsonDocument = JsonDocument.Parse(Await resp.Content.ReadAsStringAsync())
Dim pdfBytes As Byte() = Await http.GetByteArrayAsync(doc.RootElement.GetProperty("signedUrl").GetString())
File.WriteAllBytes("output.pdf", pdfBytes)
End Using
End Using
End Function
End ModuleAfter (IronPDF):
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;
var htmlContent = System.IO.File.ReadAllText("input.html");
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("output.pdf");
}
}// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Rendering;
class Program
{
static void Main()
{
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;
var htmlContent = System.IO.File.ReadAllText("input.html");
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
pdf.SaveAs("output.pdf");
}
}Imports IronPdf
Imports IronPdf.Rendering
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4
renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape
Dim htmlContent = System.IO.File.ReadAllText("input.html")
Dim pdf = renderer.RenderHtmlAsPdf(htmlContent)
pdf.SaveAs("output.pdf")
End Sub
End ClassImports IronPdf
Imports IronPdf.Rendering
Class Program
Shared Sub Main()
Dim renderer = New ChromePdfRenderer()
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4
renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape
Dim htmlContent = System.IO.File.ReadAllText("input.html")
Dim pdf = renderer.RenderHtmlAsPdf(htmlContent)
pdf.SaveAs("output.pdf")
End Sub
End Class本例显示了配置模式的差异。 pdforge在POST体内的format = "A4", landscape = true),遵循Chromium/Puppeteer命名约定。
IronPDF使用强类型枚举的renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape。 这将提供 IntelliSense 支持和编译时类型安全。 请注意,IronPDF需要导入IronPdf.Rendering命名空间以使用纸张大小和方向枚举。 更多配置示例请参见 tutorials 。
关键迁移说明
返回类型更改
pdforge返回带有已签名URL的JSON信封; IronPDF返回PdfDocument:
// pdforge: Two-step — parse signedUrl from JSON, then fetch bytes from it
var resp = await http.PostAsync("https://api.pdfnoodle.com/v1/html-to-pdf/sync", json);
using var doc = JsonDocument.Parse(await resp.Content.ReadAsStringAsync());
var pdfBytes = await http.GetByteArrayAsync(doc.RootElement.GetProperty("signedUrl").GetString());
File.WriteAllBytes("output.pdf", pdfBytes);
// IronPDF: Returns PdfDocument
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf"); // Direct save
byte[] bytes = pdf.BinaryData; // Get bytes if needed// pdforge: Two-step — parse signedUrl from JSON, then fetch bytes from it
var resp = await http.PostAsync("https://api.pdfnoodle.com/v1/html-to-pdf/sync", json);
using var doc = JsonDocument.Parse(await resp.Content.ReadAsStringAsync());
var pdfBytes = await http.GetByteArrayAsync(doc.RootElement.GetProperty("signedUrl").GetString());
File.WriteAllBytes("output.pdf", pdfBytes);
// IronPDF: Returns PdfDocument
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf"); // Direct save
byte[] bytes = pdf.BinaryData; // Get bytes if neededImports System.IO
Imports System.Net.Http
Imports System.Text.Json
Imports IronPdf
' pdforge: Two-step — parse signedUrl from JSON, then fetch bytes from it
Dim resp = Await http.PostAsync("https://api.pdfnoodle.com/v1/html-to-pdf/sync", json)
Using doc As JsonDocument = JsonDocument.Parse(Await resp.Content.ReadAsStringAsync())
Dim pdfBytes = Await http.GetByteArrayAsync(doc.RootElement.GetProperty("signedUrl").GetString())
File.WriteAllBytes("output.pdf", pdfBytes)
End Using
' IronPDF: Returns PdfDocument
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("output.pdf") ' Direct save
Dim bytes As Byte() = pdf.BinaryData ' Get bytes if neededImports System.IO
Imports System.Net.Http
Imports System.Text.Json
Imports IronPdf
' pdforge: Two-step — parse signedUrl from JSON, then fetch bytes from it
Dim resp = Await http.PostAsync("https://api.pdfnoodle.com/v1/html-to-pdf/sync", json)
Using doc As JsonDocument = JsonDocument.Parse(Await resp.Content.ReadAsStringAsync())
Dim pdfBytes = Await http.GetByteArrayAsync(doc.RootElement.GetProperty("signedUrl").GetString())
File.WriteAllBytes("output.pdf", pdfBytes)
End Using
' IronPDF: Returns PdfDocument
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("output.pdf") ' Direct save
Dim bytes As Byte() = pdf.BinaryData ' Get bytes if needed生成器更改
// pdforge: HttpClient against the REST endpoint
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", "pdfnoodle_api_YOUR_KEY");
// IronPDF: ChromePdfRenderer
var renderer = new ChromePdfRenderer();// pdforge: HttpClient against the REST endpoint
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", "pdfnoodle_api_YOUR_KEY");
// IronPDF: ChromePdfRenderer
var renderer = new ChromePdfRenderer();' pdforge: HttpClient against the REST endpoint
Using http As New HttpClient()
http.DefaultRequestHeaders.Authorization = New AuthenticationHeaderValue("Bearer", "pdfnoodle_api_YOUR_KEY")
' IronPDF: ChromePdfRenderer
Dim renderer As New ChromePdfRenderer()
End Using' pdforge: HttpClient against the REST endpoint
Using http As New HttpClient()
http.DefaultRequestHeaders.Authorization = New AuthenticationHeaderValue("Bearer", "pdfnoodle_api_YOUR_KEY")
' IronPDF: ChromePdfRenderer
Dim renderer As New ChromePdfRenderer()
End Using操作更改
// pdforge operations
await http.PostAsync("https://api.pdfnoodle.com/v1/html-to-pdf/sync", json); // HTML to PDF
// URL to PDF: fetch the page first, then POST its HTML to the same endpoint
//IronPDFmethods
renderer.RenderHtmlAsPdf(html)
renderer.RenderUrlAsPdf(url)// pdforge operations
await http.PostAsync("https://api.pdfnoodle.com/v1/html-to-pdf/sync", json); // HTML to PDF
// URL to PDF: fetch the page first, then POST its HTML to the same endpoint
//IronPDFmethods
renderer.RenderHtmlAsPdf(html)
renderer.RenderUrlAsPdf(url)' pdforge operations
Await http.PostAsync("https://api.pdfnoodle.com/v1/html-to-pdf/sync", json) ' HTML to PDF
' URL to PDF: fetch the page first, then POST its HTML to the same endpoint
'IronPDFmethods
renderer.RenderHtmlAsPdf(html)
renderer.RenderUrlAsPdf(url)' pdforge operations
Await http.PostAsync("https://api.pdfnoodle.com/v1/html-to-pdf/sync", json) ' HTML to PDF
' URL to PDF: fetch the page first, then POST its HTML to the same endpoint
'IronPDFmethods
renderer.RenderHtmlAsPdf(html)
renderer.RenderUrlAsPdf(url)保存方法更改
// pdforge: Two-step — fetch bytes from signed URL, then write to disk
var pdfBytes = await http.GetByteArrayAsync(signedUrl);
File.WriteAllBytes("output.pdf", pdfBytes);
// IronPDF: Built-in save method
pdf.SaveAs("output.pdf");// pdforge: Two-step — fetch bytes from signed URL, then write to disk
var pdfBytes = await http.GetByteArrayAsync(signedUrl);
File.WriteAllBytes("output.pdf", pdfBytes);
// IronPDF: Built-in save method
pdf.SaveAs("output.pdf");' pdforge: Two-step — fetch bytes from signed URL, then write to disk
Dim pdfBytes = Await http.GetByteArrayAsync(signedUrl)
File.WriteAllBytes("output.pdf", pdfBytes)
' IronPDF: Built-in save method
pdf.SaveAs("output.pdf")' pdforge: Two-step — fetch bytes from signed URL, then write to disk
Dim pdfBytes = Await http.GetByteArrayAsync(signedUrl)
File.WriteAllBytes("output.pdf", pdfBytes)
' IronPDF: Built-in save method
pdf.SaveAs("output.pdf")配置位置更改
pdforge将选项作为JSON字段传递到pdfParams;IronPDF使用 RenderingOptions:
// pdforge: JSON pdfParams object on the POST body
var body = new { html, pdfParams = new { format = "A4", landscape = true } };
// IronPDF: Properties on RenderingOptions
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;// pdforge: JSON pdfParams object on the POST body
var body = new { html, pdfParams = new { format = "A4", landscape = true } };
// IronPDF: Properties on RenderingOptions
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;' pdforge: JSON pdfParams object on the POST body
Dim body = New With {Key .html = html, Key .pdfParams = New With {Key .format = "A4", Key .landscape = True}}
' IronPDF: Properties on RenderingOptions
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4
renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape' pdforge: JSON pdfParams object on the POST body
Dim body = New With {Key .html = html, Key .pdfParams = New With {Key .format = "A4", Key .landscape = True}}
' IronPDF: Properties on RenderingOptions
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4
renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape页眉/页脚占位符语法
pdforge继承了Chromium的页眉/页脚模板格式——HTML片段包含的TextHeaderFooter / HtmlHeaderFooter内:
// pdforge: Chromium template HTML inside pdfParams.footerTemplate
// "<div>Page <span class=\"pageNumber\"></span> of <span class=\"totalPages\"></span></div>"
//IronPDFplaceholders
"Page {page} of {total-pages}" // Note: hyphen in total-pages// pdforge: Chromium template HTML inside pdfParams.footerTemplate
// "<div>Page <span class=\"pageNumber\"></span> of <span class=\"totalPages\"></span></div>"
//IronPDFplaceholders
"Page {page} of {total-pages}" // Note: hyphen in total-pages' pdforge: Chromium template HTML inside pdfParams.footerTemplate
' "<div>Page <span class=""pageNumber""></span> of <span class=""totalPages""></span></div>"
'IronPDFplaceholders
"Page {page} of {total-pages}" ' Note: hyphen in total-pages' pdforge: Chromium template HTML inside pdfParams.footerTemplate
' "<div>Page <span class=""pageNumber""></span> of <span class=""totalPages""></span></div>"
'IronPDFplaceholders
"Page {page} of {total-pages}" ' Note: hyphen in total-pages迁移后的新功能
迁移到IronPDF后,您将获得 pdforge 无法提供的功能:
PDF 合并
var pdf1 = PdfDocument.FromFile("document1.pdf");
var pdf2 = PdfDocument.FromFile("document2.pdf");
var merged = PdfDocument.Merge(pdf1, pdf2);
merged.SaveAs("merged.pdf");var pdf1 = PdfDocument.FromFile("document1.pdf");
var pdf2 = PdfDocument.FromFile("document2.pdf");
var merged = PdfDocument.Merge(pdf1, pdf2);
merged.SaveAs("merged.pdf");Dim pdf1 = PdfDocument.FromFile("document1.pdf")
Dim pdf2 = PdfDocument.FromFile("document2.pdf")
Dim merged = PdfDocument.Merge(pdf1, pdf2)
merged.SaveAs("merged.pdf")Dim pdf1 = PdfDocument.FromFile("document1.pdf")
Dim pdf2 = PdfDocument.FromFile("document2.pdf")
Dim merged = PdfDocument.Merge(pdf1, pdf2)
merged.SaveAs("merged.pdf")文本提取
var pdf = PdfDocument.FromFile("document.pdf");
string allText = pdf.ExtractAllText();var pdf = PdfDocument.FromFile("document.pdf");
string allText = pdf.ExtractAllText();Dim pdf = PdfDocument.FromFile("document.pdf")
Dim allText As String = pdf.ExtractAllText()Dim pdf = PdfDocument.FromFile("document.pdf")
Dim allText As String = pdf.ExtractAllText()水印
pdf.ApplyWatermark("<h2 style='color:red;'>CONFIDENTIAL</h2>");pdf.ApplyWatermark("<h2 style='color:red;'>CONFIDENTIAL</h2>");pdf.ApplyWatermark("<h2 style='color:red;'>CONFIDENTIAL</h2>")pdf.ApplyWatermark("<h2 style='color:red;'>CONFIDENTIAL</h2>")密码保护
pdf.SecuritySettings.UserPassword = "userpassword";
pdf.SecuritySettings.OwnerPassword = "ownerpassword";pdf.SecuritySettings.UserPassword = "userpassword";
pdf.SecuritySettings.OwnerPassword = "ownerpassword";pdf.SecuritySettings.UserPassword = "userpassword"
pdf.SecuritySettings.OwnerPassword = "ownerpassword"pdf.SecuritySettings.UserPassword = "userpassword"
pdf.SecuritySettings.OwnerPassword = "ownerpassword"功能对比摘要
| 特征 | pdforge | IronPDF |
|---|---|---|
| HTML 至 PDF | ✓ | ✓ |
| URL 至 PDF | ✓ | ✓ |
| 页面设置 | ✓ | ✓ |
| 离线能力 | ✗ | ✓ |
| 本地处理 | ✗ | ✓ |
| 合并 PDF | ✗ | ✓ |
| 拆分 PDF | ✗ | ✓ |
| 提取文本 | ✗ | ✓ |
| 水印 | ✗ | ✓ |
| 表格填写 | ✗ | ✓ |
| 数字签名 | ✗ | ✓ |
| 密码保护 | ✗ | ✓ |
| 无费率限制 | ✗ | ✓ |
| 一次性许可 | ✗ | ✓ |
迁移清单
迁移前
- 清点代码库中所有pdforge / pdf noodle端点调用(
api.pdforge.com,api.pdfnoodle.com) - 记录使用的当前
pdfParamsJSON配置(页面大小、方向、页边距) - 确定要转换为IronPDF占位符(
{page},<span class="pageNumber">,<span class="totalPages">) - 规划IronPDF许可证密钥存储(建议使用环境变量)
- 先使用IronPDF试用许可证进行测试
软件包变更
- pdforge在NuGet上没有.NET SDK - 没有竞争对手包需要删除
- 安装
IronPdfNuGet包:dotnet add package IronPdf
代码更改
- 删除仅用于pdforge调用的
System.Net.Http/System.Text.Json导入 - 添加
using IronPdf.Rendering;以用于纸张大小和方向枚举 - 将经过认证的
ChromePdfRenderer - 用
POST /v1/html-to-pdf/sync - 将获取URL然后POST模式替换为
RenderUrlAsPdf() - 将两步的
GetByteArrayAsync(signedUrl)+pdf.SaveAs() - 将
RenderingOptions.PaperSize - 将
RenderingOptions.PaperOrientation - 使用
PdfPaperSize.A4/PdfPaperOrientation.Landscape枚举 - 将Chromium模板转换为IronPDF占位符放入
TextHeaderFooter/HtmlHeaderFooter - 在启动时用一次性
Bearer标记
后迁移
- 测试 PDF 输出质量是否符合预期
- 验证离线操作是否正常
- 从配置中移除 API 凭据
- 根据需要添加新功能(合并、水印、安全)。
Curtis Chau 拥有卡尔顿大学的计算机科学学士学位,专注于前端开发,精通 Node.js、TypeScript、JavaScript 和 React。他热衷于打造直观且美观的用户界面,喜欢使用现代框架并创建结构良好、视觉吸引力强的手册。
相关文章


