IRONSOFTWAREHOME
视频

如何在 NET MAUI 中将 XAML 转换为 PDF

Curtis Chau
Curtis Chau
Updated: 2026年7月19日

为什么要从 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对比

特征pdforgeIronPDF
部署类型基于云的 API本地库
依赖关系需要互联网和 API 认证无外部依赖性
定制对 PDF 生成的控制有限完全控制定制
成本结构持续订阅一次性购买选项
安全性通过网络发送数据的潜在问题完全在本地环境中进行数据处理
设置复杂性外部处理使初始设置更简单需要更多的初始设置和配置

IronPDF 的与众不同之处在于它提供了一个完全本地化的库,使开发人员能够完全控制 PDF 创建过程。 这对于希望在内部处理文件或外部 API 调用引入安全问题的应用程序尤其有利。IronPDF在本地处理所有内容,将此类风险降至最低。

对于计划在当前.NET版本上采用.NET 10和C# 14的团队,IronPDF提供了一个消除云依赖的本地处理基础,同时增加了全面的PDF操作能力。


开始之前

前提条件

  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 软件包变更

# 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
SHELL

许可配置

// Add at application startup (Program.cs or Startup.cs)
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" .
SHELL

完整的 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;

核心概念映射

pdforge (REST)IronPDF
HttpClient + Authorization: Bearer pdfnoodle_api_...new ChromePdfRenderer()
POST https://api.pdfnoodle.com/v1/html-to-pdf/syncrenderer.RenderHtmlAsPdf(html)
JSON body { html, pdfParams }ChromePdfRenderer + RenderingOptions
Response: JSON envelope with signedUrlPdfDocument
Return: byte[] (after fetching signedUrl)pdf.BinaryData

操作映射

pdforgeIronPDF
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 pdfParamsIronPDF (渲染选项)
format: "A4"renderer.RenderingOptions.PaperSize = PdfPaperSize.A4
landscape: truerenderer.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);
    }
}

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

这里的根本区别在于处理模型和返回类型。 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);
    }
}

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

pdforge没有专用的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);
    }
}

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

本例显示了配置模式的差异。 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: 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 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)
C#

保存方法更改

// 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将选项作为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继承了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
C#

迁移后的新功能

迁移到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 pdf = PdfDocument.FromFile("document.pdf");
string allText = pdf.ExtractAllText();

水印

pdf.ApplyWatermark("<h2 style='color:red;'>CONFIDENTIAL</h2>");

密码保护

pdf.SecuritySettings.UserPassword = "userpassword";
pdf.SecuritySettings.OwnerPassword = "ownerpassword";

功能对比摘要

特征pdforgeIronPDF
HTML 至 PDF
URL 至 PDF
页面设置
离线能力
本地处理
合并 PDF
拆分 PDF
提取文本
水印
表格填写
数字签名
密码保护
无费率限制
一次性许可

迁移清单

迁移前

  • 清点代码库中所有pdforge / pdf noodle端点调用(api.pdforge.com, api.pdfnoodle.com
  • 记录使用的当前pdfParams JSON配置(页面大小、方向、页边距)
  • 确定要转换为IronPDF占位符({page}, <span class="pageNumber">, <span class="totalPages">
  • 规划IronPDF许可证密钥存储(建议使用环境变量)
  • 先使用IronPDF试用许可证进行测试

软件包变更

  • pdforge在NuGet上没有.NET SDK — 没有竞争对手包需要删除
  • 安装IronPdf NuGet包: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 凭据
  • 根据需要添加新功能(合并、水印、安全)。

请注意: pdforge和pdf noodle是其各自所有者的商标。 本网站与pdforge / pdf noodle的所有者无关联、认可或赞助。 所有产品名称、徽标和品牌均为各自所有者的财产。 比较仅供参考,反映撰写时公开可用的信息。
Curtis Chau
技术作家

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

...
阅读更多

相关文章

Key in blue circle

立即获取免费的 30 天试用版密钥

Your trial license will be sent to your email address

无任何限制。100% 解锁。无需信用卡。

bullet_checked无需信用卡或创建账户无任何限制。100% 解锁。无需信用卡。
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Join Millions of Engineers who’ve tried IronPDF
预约您的免费现场演示
Booking Badge

深受全球数百万工程师信赖

Iron Software 的客户徽标
获取您的无义务咨询
填写下面的表格或通过sales@ironsoftware.com
您的资料将始终保密。
深受全球数百万工程师信赖
Iron Software 的客户徽标
立即获取您的免费30 天试用密钥
无需信用卡或创建账户