跳至頁尾內容
移民指南

如何使用 C# 將 QuestPDF 遷移到 IronPDF

從 QuestPDF 遷移到 IronPDF 會將您的 PDF 生成工作流程從專有的 C# 流暢 API 轉變為基於 HTML/CSS 的標準方法,並具有全面的 PDF 操作功能。 本指南提供了一條完整的、循序漸進的遷移路徑,使您能夠利用現有的網路技能、重複使用 HTML 模板,並獲得 QuestPDF 根本無法提供的功能。

為什麼要從 QuestPDF 遷移到 IronPDF

了解 QuestPDF

QuestPDF 是一個現代化的、流暢的 API,專門用於在 C# 中以程式設計方式產生 PDF。 與一些提供全面 HTML 到 PDF 轉換功能的同類產品不同,QuestPDF 僅限於程式化佈局 API 功能。 QuestPDF 在開發人員需要使用 C# 程式碼從頭開始產生文檔,而無需依賴 HTML 的場景中表現出色。

對於年收入低於 100 萬美元的企業,該圖書館是免費的,但需要證明其收入水平,這可能會給一些企業帶來合規負擔。 超過此閾值的用戶需要購買許可證,在評估 QuestPDF 作為潛在解決方案時,必須將此因素納入長期規劃中。

核心問題:不支援 HTML

QuestPDF 經常被推薦用於 HTML 轉 PDF,但它根本不支援 HTML。 儘管 QuestPDF 在開發者論壇上得到了大力推廣,但它使用自己專有的佈局語言,需要學習一種全新的領域特定語言 (DSL),而不是利用現有的網路技能。

特徵QuestPDFIronPDF
HTML 轉 PDF不支援全力支持
CSS樣式不支援完整的 CSS3
現有模板必須從頭開始重建重複使用 HTML/CSS 資源
設計工具相容性沒有任何任何網頁設計工具
學習曲線新型專有DSL網路技能轉移
佈局預覽需要 IDE 插件在任何瀏覽器中預覽
PDF 處理沒有任何合併、拆分、編輯

IronPDF 提供 QuestPDF 完全不具備的原生 HTML 到 PDF 渲染功能,因此無需在 C# 程式碼中手動重建文件。 它包含 QuestPDF 無法實現的全面 PDF 操作功能(合併、分割、編輯、保護)。

QuestPDF 授權模式

QuestPDF 的"社群授權"僅在公司年總收入低於 100 萬美元時免費。 如果收入超過閾值,您的客戶(不僅僅是您作為開發人員)可能需要購買許可證。 與簡單的按開發者計費的商業許可不同,QuestPDF 的模式要求揭露收入並進行合規性追蹤。

IronPDF 提供簡單的許可:每個開發者一個許可證,沒有收入審計,沒有客戶許可要求,以及清晰、可預測的成本。

對於計劃在 2025 年和 2026 年採用 .NET 10 和 C# 14 的團隊,IronPDF 提供透明的許可,無需基於收入的審計,並採用標準的 HTML/CSS 方法,充分利用現有的 Web 開發技能。


開始之前

先決條件

  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 QuestPDF
dotnet remove package QuestPDF

# Add IronPDF
dotnet add package IronPdf
# Remove QuestPDF
dotnet remove package QuestPDF

# Add IronPDF
dotnet add package IronPdf
SHELL

許可證配置

// Add at application startup
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// Add at application startup
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
$vbLabelText   $csharpLabel

尋找 QuestPDF 使用情況

# Find all QuestPDF usages in your codebase
grep -r "QuestPDF\|Document.Create\|\.GeneratePdf" --include="*.cs" .
# Find all QuestPDF usages in your codebase
grep -r "QuestPDF\|Document.Create\|\.GeneratePdf" --include="*.cs" .
SHELL

完整 API 參考

命名空間變更

// Before: QuestPDF
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;

// After: IronPDF
using IronPdf;
// Before: QuestPDF
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;

// After: IronPDF
using IronPdf;
$vbLabelText   $csharpLabel

核心 API 映射

QuestPDF概念IronPDF當量筆記
Document.Create()new ChromePdfRenderer()渲染器創建
.Page()RenderHtmlAsPdf()將 HTML 渲染為 PDF
.Text()HTML<p><h1><span>標準 HTML 標籤
.Bold()CSS font-weight: bold標準 CSS
.FontSize(24)CSS font-size: 24px標準 CSS
.Image()HTML<img src="...">標準 HTML
.Table()HTML<table>標準 HTML
.Column()CSS display: flex; flex-direction: columnCSS Flexbox
.Row()CSS display: flex; flex-direction: rowCSS Flexbox
PageSizes.A4RenderingOptions.PaperSize紙張尺寸
.Margin()RenderingOptions.Margin*頁面邊距
.GeneratePdf()pdf.SaveAs()文件輸出
不適用PdfDocument.Merge()合併PDF
不適用PdfDocument.FromFile()載入現有PDF文件
不適用pdf.SecuritySettingsPDF加密

程式碼遷移範例

範例 1:基本文件建立(HTML 轉 PDF)

之前(QuestPDF):

// NuGet: Install-Package QuestPDF
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;

class Program
{
    static void Main()
    {
        QuestPDF.Settings.License = LicenseType.Community;

        Document.Create(container =>
        {
            container.Page(page =>
            {
                page.Size(PageSizes.A4);
                page.Margin(2, Unit.Centimetre);
                page.Content().Column(column =>
                {
                    column.Item().Text("Hello World").FontSize(20).Bold();
                    column.Item().Text("This is a paragraph of text.");
                });
            });
        }).GeneratePdf("output.pdf");
    }
}
// NuGet: Install-Package QuestPDF
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;

class Program
{
    static void Main()
    {
        QuestPDF.Settings.License = LicenseType.Community;

        Document.Create(container =>
        {
            container.Page(page =>
            {
                page.Size(PageSizes.A4);
                page.Margin(2, Unit.Centimetre);
                page.Content().Column(column =>
                {
                    column.Item().Text("Hello World").FontSize(20).Bold();
                    column.Item().Text("This is a paragraph of text.");
                });
            });
        }).GeneratePdf("output.pdf");
    }
}
$vbLabelText   $csharpLabel

(IronPDF 之後):

// NuGet: Install-Package IronPdf
using IronPdf;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>This is a paragraph of text.</p>");
        pdf.SaveAs("output.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1><p>This is a paragraph of text.</p>");
        pdf.SaveAs("output.pdf");
    }
}
$vbLabelText   $csharpLabel

這個例子體現了根本性的範式差異。 QuestPDF 需要學習其流暢的 API: Document.Create()container.Page()page.Content().Column()column.Item().Text() ,以及透過方法鏈進行樣式設定,例如.FontSize(20).Bold() 。 您還必須使用QuestPDF.Settings.License = LicenseType.Community設定許可證類型。

IronPDF 使用任何 Web 開發人員都熟悉的標準 HTML:<h1>標題,<p>用於段落。無需學習專有領域特定語言 (DSL)。 IronPDF 的方法提供了更簡潔的語法和與現代 .NET 應用程式更好的整合。 請參閱HTML 轉 PDF 文件以取得完整範例。

範例 2:發票生成

之前(QuestPDF):

// NuGet: Install-Package QuestPDF
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;

class Program
{
    static void Main()
    {
        QuestPDF.Settings.License = LicenseType.Community;

        Document.Create(container =>
        {
            container.Page(page =>
            {
                page.Size(PageSizes.A4);
                page.Margin(2, Unit.Centimetre);
                page.Content().Column(column =>
                {
                    column.Item().Text("INVOICE").FontSize(24).Bold();
                    column.Item().Text("Invoice #: 12345").FontSize(12);
                    column.Item().PaddingTop(20);
                    column.Item().Text("Customer: John Doe");
                    column.Item().Text("Total: $100.00").Bold();
                });
            });
        }).GeneratePdf("invoice.pdf");
    }
}
// NuGet: Install-Package QuestPDF
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;

class Program
{
    static void Main()
    {
        QuestPDF.Settings.License = LicenseType.Community;

        Document.Create(container =>
        {
            container.Page(page =>
            {
                page.Size(PageSizes.A4);
                page.Margin(2, Unit.Centimetre);
                page.Content().Column(column =>
                {
                    column.Item().Text("INVOICE").FontSize(24).Bold();
                    column.Item().Text("Invoice #: 12345").FontSize(12);
                    column.Item().PaddingTop(20);
                    column.Item().Text("Customer: John Doe");
                    column.Item().Text("Total: $100.00").Bold();
                });
            });
        }).GeneratePdf("invoice.pdf");
    }
}
$vbLabelText   $csharpLabel

(IronPDF 之後):

// NuGet: Install-Package IronPdf
using IronPdf;

class Program
{
    static void Main()
    {
        var htmlContent = @"
            <h1>INVOICE</h1>
            <p>Invoice #: 12345</p>
            <br/>
            <p>Customer: John Doe</p>
            <p><strong>Total: $100.00</strong></p>
        ";

        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderHtmlAsPdf(htmlContent);
        pdf.SaveAs("invoice.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;

class Program
{
    static void Main()
    {
        var htmlContent = @"
            <h1>INVOICE</h1>
            <p>Invoice #: 12345</p>
            <br/>
            <p>Customer: John Doe</p>
            <p><strong>Total: $100.00</strong></p>
        ";

        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderHtmlAsPdf(htmlContent);
        pdf.SaveAs("invoice.pdf");
    }
}
$vbLabelText   $csharpLabel

QuestPDF 使用.Column().Item()進行佈局,使用.PaddingTop(20)進行間距設定。 IronPDF 使用標準 HTML:<h1>至於標題,<p>對於段落而言,<br/>用於間距,以及<strong>粗體文字。

真正的優勢在於:借助 IronPDF,設計師可以獨立建立和修改 HTML 模板。 使用 QuestPDF 時,每次設計變更都需要 C# 開發人員修改程式碼。 了解更多信息,請閱讀我們的教程

範例 3:帶頁碼的頁首和頁尾

之前(QuestPDF):

// NuGet: Install-Package QuestPDF
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;

class Program
{
    static void Main()
    {
        QuestPDF.Settings.License = LicenseType.Community;

        Document.Create(container =>
        {
            container.Page(page =>
            {
                page.Size(PageSizes.A4);
                page.Margin(2, Unit.Centimetre);

                page.Header().Text("Document Header").FontSize(14).Bold();

                page.Content().Text("Main content of the document.");

                page.Footer().AlignCenter().Text(text =>
                {
                    text.Span("Page ");
                    text.CurrentPageNumber();
                });
            });
        }).GeneratePdf("document.pdf");
    }
}
// NuGet: Install-Package QuestPDF
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;

class Program
{
    static void Main()
    {
        QuestPDF.Settings.License = LicenseType.Community;

        Document.Create(container =>
        {
            container.Page(page =>
            {
                page.Size(PageSizes.A4);
                page.Margin(2, Unit.Centimetre);

                page.Header().Text("Document Header").FontSize(14).Bold();

                page.Content().Text("Main content of the document.");

                page.Footer().AlignCenter().Text(text =>
                {
                    text.Span("Page ");
                    text.CurrentPageNumber();
                });
            });
        }).GeneratePdf("document.pdf");
    }
}
$vbLabelText   $csharpLabel

(IronPDF 之後):

// NuGet: Install-Package IronPdf
using IronPdf;

class Program
{
    static void Main()
    {
        var htmlContent = "<p>Main content of the document.</p>";

        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderHtmlAsPdf(htmlContent);

        pdf.Header = new TextHeaderFooter()
        {
            CenterText = "Document Header",
            FontSize = 14
        };

        pdf.Footer = new TextHeaderFooter()
        {
            CenterText = "Page {page}"
        };

        pdf.SaveAs("document.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;

class Program
{
    static void Main()
    {
        var htmlContent = "<p>Main content of the document.</p>";

        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderHtmlAsPdf(htmlContent);

        pdf.Header = new TextHeaderFooter()
        {
            CenterText = "Document Header",
            FontSize = 14
        };

        pdf.Footer = new TextHeaderFooter()
        {
            CenterText = "Page {page}"
        };

        pdf.SaveAs("document.pdf");
    }
}
$vbLabelText   $csharpLabel

QuestPDF 使用page.Header()page.Footer()以及.AlignCenter().CurrentPageNumber()等流暢方法。 IronPDF 使用TextHeaderFooter對象,其屬性包括CenterTextFontSize{page}佔位符會自動插入目前頁碼。


關鍵遷移說明

範式轉移

根本性的改變是從專有的 C# DSL 轉向標準的 HTML/CSS:

// QuestPDF: Proprietary fluent API
container.Page(page =>
{
    page.Content().Column(column =>
    {
        column.Item().Text("Invoice").Bold().FontSize(24);
        column.Item().Row(row =>
        {
            row.RelativeItem().Text("Customer:");
            row.RelativeItem().Text("Acme Corp");
        });
    });
});

// IronPDF: Standard HTML/CSS
var html = @"
<div style='font-family: Arial; padding: 40px;'>
    <h1 style='font-weight: bold; font-size: 24px;'>Invoice</h1>
    <div style='display: flex; justify-content: space-between;'>
        <span>Customer:</span>
        <span>Acme Corp</span>
    </div>
</div>";

var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
// QuestPDF: Proprietary fluent API
container.Page(page =>
{
    page.Content().Column(column =>
    {
        column.Item().Text("Invoice").Bold().FontSize(24);
        column.Item().Row(row =>
        {
            row.RelativeItem().Text("Customer:");
            row.RelativeItem().Text("Acme Corp");
        });
    });
});

// IronPDF: Standard HTML/CSS
var html = @"
<div style='font-family: Arial; padding: 40px;'>
    <h1 style='font-weight: bold; font-size: 24px;'>Invoice</h1>
    <div style='display: flex; justify-content: space-between;'>
        <span>Customer:</span>
        <span>Acme Corp</span>
    </div>
</div>";

var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
$vbLabelText   $csharpLabel

佈局模式轉換

QuestPDF 圖案HTML/CSS 等效項
.Column()display: flex; flex-direction: column
.Row()display: flex; flex-direction: row
.RelativeItem()flex: 1
.Table()<table>元素
.PaddingTop(20)padding-top: 20px<br/>
.AlignCenter()text-align: center
.FontSize(24)font-size: 24px
.Bold()font-weight: bold<strong>

頁面設定轉換

// QuestPDF
page.Size(PageSizes.A4);
page.Margin(2, Unit.Centimetre);

// IronPDF
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
renderer.RenderingOptions.MarginTop = 20;    // mm (2cm = 20mm)
renderer.RenderingOptions.MarginBottom = 20;
renderer.RenderingOptions.MarginLeft = 20;
renderer.RenderingOptions.MarginRight = 20;
// QuestPDF
page.Size(PageSizes.A4);
page.Margin(2, Unit.Centimetre);

// IronPDF
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
renderer.RenderingOptions.MarginTop = 20;    // mm (2cm = 20mm)
renderer.RenderingOptions.MarginBottom = 20;
renderer.RenderingOptions.MarginLeft = 20;
renderer.RenderingOptions.MarginRight = 20;
$vbLabelText   $csharpLabel

遷移後的新功能

遷移到 IronPDF 後,您將獲得 QuestPDF 無法提供的功能:

PDF合併

var cover = renderer.RenderHtmlAsPdf("<h1>Cover</h1>");
var content = renderer.RenderHtmlAsPdf(reportHtml);
var existing = PdfDocument.FromFile("appendix.pdf");

var merged = PdfDocument.Merge(cover, content, existing);
merged.SaveAs("complete.pdf");
var cover = renderer.RenderHtmlAsPdf("<h1>Cover</h1>");
var content = renderer.RenderHtmlAsPdf(reportHtml);
var existing = PdfDocument.FromFile("appendix.pdf");

var merged = PdfDocument.Merge(cover, content, existing);
merged.SaveAs("complete.pdf");
$vbLabelText   $csharpLabel

PDF 安全性

var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SecuritySettings.OwnerPassword = "admin";
pdf.SecuritySettings.UserPassword = "reader";
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights;
pdf.SaveAs("protected.pdf");
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SecuritySettings.OwnerPassword = "admin";
pdf.SecuritySettings.UserPassword = "reader";
pdf.SecuritySettings.AllowUserPrinting = PdfPrintSecurity.FullPrintRights;
pdf.SaveAs("protected.pdf");
$vbLabelText   $csharpLabel

PDF檔案的URL

var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.EnableJavaScript = true;

var pdf = renderer.RenderUrlAsPdf("https://example.com/report");
pdf.SaveAs("webpage.pdf");
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.EnableJavaScript = true;

var pdf = renderer.RenderUrlAsPdf("https://example.com/report");
pdf.SaveAs("webpage.pdf");
$vbLabelText   $csharpLabel

載入和編輯現有PDF文件

var pdf = PdfDocument.FromFile("existing.pdf");
// Modify, merge, add security, etc.
pdf.SaveAs("modified.pdf");
var pdf = PdfDocument.FromFile("existing.pdf");
// Modify, merge, add security, etc.
pdf.SaveAs("modified.pdf");
$vbLabelText   $csharpLabel

功能對比總結

特徵QuestPDFIronPDF
HTML 轉 PDF不支援主要特徵
學習曲線專有DSL標準網路技能
模板預覽需要插件任何瀏覽器
設計協作僅限開發者設計師 + 開發人員
現有資產必須重建重複使用 HTML/CSS
PDF 處理不支援全力支持
安全/簽名不支援全力支持
許可模式基於收入每個開發商
客戶影響可能需要許可證沒有任何
引導/順風不支援全力支持
PDF檔案的URL不支援全力支持

遷移清單

遷移前

  • 識別所有 QuestPDF 文件範本( Document.Create.GeneratePdf
  • 記錄所使用的DSL模式( .Column() 、. .Row() 、. .Table() 、. .Text() ) 將樣式方法對應到等效的 CSS 樣式
  • ironpdf.com取得 IronPDF 許可證金鑰

軟體包變更

  • 刪除QuestPDF NuGet 套件 安裝IronPdf NuGet 套件: dotnet add package IronPdf

程式碼更改

  • 更新命名空間匯入
  • 移除QuestPDF.Settings.License = LicenseType.CommunityDocument.Create()模式轉換為ChromePdfRenderer + HTML
  • .Column() / .Row()替換為 CSS Flexbox
  • .Table()替換為 HTML<table>元素
  • .Text().Bold().FontSize(24)轉換為<h1> style="...">
  • page.Header() / page.Footer()替換為TextHeaderFooter
  • .CurrentPageNumber()替換為{page}佔位符
  • .GeneratePdf()轉換為pdf.SaveAs()
  • 在應用程式啟動時新增許可證初始化

移民後

  • PDF 輸出的視覺比較
  • 測試多頁文件的分頁符號是否正確
  • 依需求新增功能(安全性、合併、URL 轉 PDF)

柯蒂斯·週
技術撰稿人

Curtis Chau擁有卡爾頓大學電腦科學學士學位,專長於前端開發,精通Node.js、TypeScript、JavaScript和React。他熱衷於打造直覺美觀的使用者介面,喜歡使用現代框架,並擅長撰寫結構清晰、視覺效果出色的使用者手冊。

除了開發工作之外,柯蒂斯對物聯網 (IoT) 也抱有濃厚的興趣,致力於探索硬體和軟體整合的創新方法。閒暇時,他喜歡玩遊戲和製作 Discord 機器人,將他對科技的熱愛與創造力結合。