IRONSOFTWAREHOME
影片

如何使用 C# 將 RTF 轉換為 PDF

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

為什麼從NReco PDF Generator遷移到IronPDF

NReco PDF Generator的關鍵安全問題

NReco PDF Generator 包裝了 wkhtmltopdf 二進位檔,因此它繼承了已知的安全漏洞。 wkhtmltopdf 專案的最後一個穩定版本是 0.12.6(2020 年 6 月),而上游倉庫於 2023 年 1 月 2 日存檔,因此不再有補丁:

  • CVE-2020-21365: 目錄遍歷/透過精心製作的 HTML (相同來源策略弱點)讀取本地檔案
  • CVE-2022-35583: 透過版本 0.12.6 中的注入 <iframe> 實現的伺服器端請求偽造 (SSRF)(CVSS 9.8)

其他 NReco PDF Generator 限制

  1. **大規模授權摩擦:**非SaaS單伺服器生產部署免費; SaaS、多伺服器或再分發方案需要從 nrecosite.com 購買 $199 的企業源程式碼包。

  2. 已淘汰的渲染引擎: WebKit Qt(約 2012 年),對 CSS3/JS 支援有限:

    • 無 CSS Grid 或 Flexbox
    • 不支持現代JavaScript(ES6+)
    • 網頁字體支援較差
    • 無 CSS 變數或自訂屬性
  3. 外部二進位檔相依: 需要根據平台管理 wkhtmltopdf 二進位檔 (wkhtmltopdf.exe, wkhtmltox.dll)。

  4. 維護停滯: NReco.PdfGenerator 1.2.1 於 2023年1月8日發布,但在 nuget.org 上未有進一步的版本發布; 底層的 wkhtmltopdf 引擎不再更新。

  5. **有限的非同步支援:**同步 API 阻塞了 Web 應用程式中的執行緒。

NReco PDF Generator 與IronPDF比較

方面NReco PDF GeneratorIronPDF
渲染引擎WebKit Qt (2012)Chromium (當前)
安全性多個未修補的 CVE(例如 CVE-2020-21365, CVE-2022-35583); 引擎於 2023 年 1 月 2 日存檔活躍的安全更新
CSS支持CSS2.1,有限的 CSS3完全支援 CSS3、Grid、Flexbox
JavaScript基本的 ES5完全支援 ES6+,async/await
依賴關係外部 wkhtmltopdf 二進位檔自包含
異步支援只有同步完全支持 async/await
Web 字體有限完整的 Google 字體,@font-face
授權非SaaS單伺服器免費; $199 的企業包適用於SaaS/多伺服器透明的商業定價
免費層級非SaaS單伺服器授權免費試用不需要浮水印

開始之前

前提條件

  1. .NET Environment: .NET Framework 4.6.2+ or .NET Core 3.1+ / .NET 5/6/7/8/9+
  2. NuGet存取: 有能力安裝NuGet套件
  3. IronPDF授權:ironpdf.com獲取您的授權金鑰

NuGet包變更

# Remove NReco.PdfGenerator
dotnet remove package NReco.PdfGenerator

# Install IronPDF
dotnet add package IronPdf
SHELL

從您的部署中刪除 wkhtmltopdf 二進位檔

  • 刪除專案中的 wkhtmltopdf.exe, wkhtmltox.dll
  • 移除任何 wkhtmltopdf 安裝腳本
  • 刪除平台特定的二進位檔資料夾

授權配置

// Add at application startup (Program.cs or Startup.cs)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";

識別 NReco PDF Generator 使用

# Find all NReco.PdfGenerator references
grep -r "NReco.PdfGenerator\|HtmlToPdfConverter\|GeneratePdf" --include="*.cs" .
SHELL

完整API參考

核心類別映射

NReco PDF GeneratorIronPDF
HtmlToPdfConverterChromePdfRenderer
PageMargins個別邊距屬性
PageOrientationPdfPaperOrientation
PageSizePdfPaperSize

渲染方法映射

NReco PDF GeneratorIronPDF
GeneratePdf(html)RenderHtmlAsPdf(html)
GeneratePdfFromFile(url, output)RenderUrlAsPdf(url)
GeneratePdfFromFile(htmlPath, output)RenderHtmlFileAsPdf(path)
(不支援非同步)RenderHtmlAsPdfAsync(html)
(不支援非同步)RenderUrlAsPdfAsync(url)

頁面配置映射

NReco PDF GeneratorIronPDF
PageWidth = 210RenderingOptions.PaperSize = PdfPaperSize.A4
PageHeight = 297RenderingOptions.SetCustomPaperSizeinMilimeters(w, h)
Orientation = PageOrientation.LandscapeRenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape
Size = PageSize.A4RenderingOptions.PaperSize = PdfPaperSize.A4

邊距映射

NReco PDF GeneratorIronPDF
Margins.Top = 10RenderingOptions.MarginTop = 10
Margins.Bottom = 10RenderingOptions.MarginBottom = 10
Margins.Left = 10RenderingOptions.MarginLeft = 10
Margins.Right = 10RenderingOptions.MarginRight = 10
new PageMargins { ... }個別屬性

頁眉/頁腳佔位符映射

NReco PDF Generator (wkhtmltopdf)IronPDF
[page]{page}
[topage]{total-pages}
[date]{date}
[time]{time}
[title]{html-title}

輸出處理映射

NReco PDF GeneratorIronPDF
byte[] pdfBytes = GeneratePdf(html)PdfDocument pdf = RenderHtmlAsPdf(html)
File.WriteAllBytes(path, bytes)pdf.SaveAs(path)
return pdfBytesreturn pdf.BinaryData
new MemoryStream(pdfBytes)new MemoryStream(pdf.BinaryData)

程式碼遷移範例

範例1:基本HTML到PDF

之前(NReco PDF Generator):

// NuGet: Install-Package NReco.PdfGenerator
using NReco.PdfGenerator;
using System.IO;

class Program
{
    static void Main()
    {
        var htmlToPdf = new HtmlToPdfConverter();
        var htmlContent = "<html><body><h1>Hello World</h1><p>This is a PDF document.</p></body></html>";
        var pdfBytes = htmlToPdf.GeneratePdf(htmlContent);
        File.WriteAllBytes("output.pdf", pdfBytes);
    }
}

之後(IronPDF):

// NuGet: Install-Package IronPdf
using IronPdf;
using System.IO;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var htmlContent = "<html><body><h1>Hello World</h1><p>This is a PDF document.</p></body></html>";
        var pdf = renderer.RenderHtmlAsPdf(htmlContent);
        pdf.SaveAs("output.pdf");
    }
}

根本的區別在於回傳型別和保存模式。 NReco PDF Generator 的 HtmlToPdfConverter.GeneratePdf() 回傳一個 byte[],您必須手動使用 File.WriteAllBytes() 寫入磁碟。IronPDF的 ChromePdfRenderer.RenderHtmlAsPdf() 回傳一個具有內建 SaveAs() 方法的 PdfDocument 物件。

這種面向物件的方法提供了額外的好處:您可以在保存前操作 PDF(新增浮水印、合併文件、新增安全性)。 如果您需要原始位元組以與現有程式碼相容,請使用 pdf.BinaryData。 查看HTML到PDF文件以獲取其他渲染選項。

範例2:自訂頁面大小及邊距

之前(NReco PDF Generator):

// NuGet: Install-Package NReco.PdfGenerator
using NReco.PdfGenerator;
using System.IO;

class Program
{
    static void Main()
    {
        var htmlToPdf = new HtmlToPdfConverter();
        htmlToPdf.PageWidth = 210;
        htmlToPdf.PageHeight = 297;
        htmlToPdf.Margins = new PageMargins { Top = 10, Bottom = 10, Left = 10, Right = 10 };
        var htmlContent = "<html><body><h1>Custom Page Size</h1><p>A4 size document with margins.</p></body></html>";
        var pdfBytes = htmlToPdf.GeneratePdf(htmlContent);
        File.WriteAllBytes("custom-size.pdf", pdfBytes);
    }
}

之後(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.MarginTop = 10;
        renderer.RenderingOptions.MarginBottom = 10;
        renderer.RenderingOptions.MarginLeft = 10;
        renderer.RenderingOptions.MarginRight = 10;
        var htmlContent = "<html><body><h1>Custom Page Size</h1><p>A4 size document with margins.</p></body></html>";
        var pdf = renderer.RenderHtmlAsPdf(htmlContent);
        pdf.SaveAs("custom-size.pdf");
    }
}

NReco PDF Generator 使用數字維度 (PageWidth = 210, PageHeight = 297) 和一個 PageMargins 物件。IronPDF使用 PdfPaperSize 列舉(包括標準尺寸如 A4、Letter、Legal)和 RenderingOptions 物件上的單獨邊距屬性。

遷移的關鍵改變:

  • PageHeightRenderingOptions.PaperSize = PdfPaperSize.A4
  • new PageMargins { Top = 10, ... } → Individual properties: RenderingOptions.MarginTop = 10

對列舉未涵蓋的自訂紙張大小使用 RenderingOptions.SetCustomPaperSizeinMilimeters(width, height)。 了解更多 頁面配置選項

範例3:URL 至 PDF 轉換

之前(NReco PDF Generator):

// NuGet: Install-Package NReco.PdfGenerator
using NReco.PdfGenerator;
using System.IO;

class Program
{
    static void Main()
    {
        var htmlToPdf = new HtmlToPdfConverter();
        var pdfBytes = htmlToPdf.GeneratePdfFromFile("https://www.example.com", null);
        File.WriteAllBytes("webpage.pdf", pdfBytes);
    }
}

之後(IronPDF):

// NuGet: Install-Package IronPdf
using IronPdf;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();
        var pdf = renderer.RenderUrlAsPdf("https://www.example.com");
        pdf.SaveAs("webpage.pdf");
    }
}

NReco PDF Generator 使用混亂命名的 GeneratePdfFromFile() 方法同時處理本地檔案和 URL,具有可空的第二個參數。IronPDF提供專用方法:RenderUrlAsPdf() 用於 URL 和 RenderHtmlFileAsPdf() 用於本地 HTML 檔案。

IronPDF 的方法更清晰和直觀。對於非同步網頁應用程式,使用 await renderer.RenderUrlAsPdfAsync(url) 以避免阻塞執行緒—這是 NReco PDF Generator 無法做到的。


關鍵遷移注意事項

縮放值轉換

NReco PDF Generator 使用浮點數值 (0.0-2.0),而IronPDF則使用百分比整數:

// NReco PDF Generator: Zoom = 0.9f (90%)
// IronPDF: Zoom = 90

// Conversion formula:
int ironPdfZoom = (int)(nrecoZoom * 100);

佔位符語法更新

所有頁眉/頁腳佔位符必須更新:

NReco PDF GeneratorIronPDF
[page]{page}
[topage]{total-pages}
[date]{date}
[title]{html-title}
// NReco PDF Generator:
converter.PageFooterHtml = "<div>Page [page] of [topage]</div>";

// IronPDF:
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
    HtmlFragment = "<div>Page {page} of {total-pages}</div>",
    MaxHeight = 20
};

返回型別變更

NReco PDF Generator 直接回傳 byte[];IronPDF回傳 PdfDocument

// NReco PDF Generator pattern:
byte[] pdfBytes = converter.GeneratePdf(html);
File.WriteAllBytes("output.pdf", pdfBytes);

//IronPDFpattern:
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");

// Or if you need bytes:
byte[] pdfBytes = renderer.RenderHtmlAsPdf(html).BinaryData;

執行緒安全性和可重用性

NReco PDF Generator 通常每次呼叫建立一個新轉換器。IronPDF的 ChromePdfRenderer 是執行緒安全的並且可以重用:

// NReco PDF Generator pattern (creates new each time):
public byte[] Generate(string html)
{
    var converter = new HtmlToPdfConverter();
    return converter.GeneratePdf(html);
}

//IronPDFpattern (reuse renderer, thread-safe):
private readonly ChromePdfRenderer _renderer = new ChromePdfRenderer();

public byte[] Generate(string html)
{
    return _renderer.RenderHtmlAsPdf(html).BinaryData;
}

非同步支持(新功能)

IronPDF 支持非同步/等待模式,而這是 NReco PDF Generator 無法提供的:

// NReco PDF Generator: No async support available

// IronPDF: Full async support
public async Task<byte[]> GenerateAsync(string html)
{
    var pdf = await _renderer.RenderHtmlAsPdfAsync(html);
    return pdf.BinaryData;
}

故障排除

問題 1:找不到 HtmlToPdfConverter

**問題:**IronPDF中不存在 HtmlToPdfConverter 類別。

解決方案: 使用 ChromePdfRenderer

// NReco PDF Generator
var converter = new HtmlToPdfConverter();

// IronPDF
var renderer = new ChromePdfRenderer();

問題 2:GeneratePdf 返回錯誤型別

問題: 程式碼預期回傳 byte[] 但得到 PdfDocument

解決方案: 存取 .BinaryData 屬性:

// NReco PDF Generator
byte[] pdfBytes = converter.GeneratePdf(html);

// IronPDF
byte[] pdfBytes = renderer.RenderHtmlAsPdf(html).BinaryData;

問題 3:找不到 PageMargins 物件

**問題:**IronPDF中不存在 PageMargins 類別。

解決方案: 使用個別邊距屬性:

// NReco PDF Generator
converter.Margins = new PageMargins { Top = 10, Bottom = 10, Left = 10, Right = 10 };

// IronPDF
renderer.RenderingOptions.MarginTop = 10;
renderer.RenderingOptions.MarginBottom = 10;
renderer.RenderingOptions.MarginLeft = 10;
renderer.RenderingOptions.MarginRight = 10;

問題 4:頁碼未顯示

問題: [page][topage] 佔位符無效。

解決方案: 更新為IronPDF佔位符語法:

// NReco PDF Generator
converter.PageFooterHtml = "<div>Page [page] of [topage]</div>";

// IronPDF
renderer.RenderingOptions.HtmlFooter = new HtmlHeaderFooter
{
    HtmlFragment = "<div>Page {page} of {total-pages}</div>",
    MaxHeight = 20
};

遷移檢查表

遷移前

  • 清點程式碼庫中所有 NReco.PdfGenerator 的用法
  • 記錄所有 CustomWkHtmlArgsCustomWkHtmlPageArgs
  • 列出所有帶有佔位符的頁眉/頁腳 HTML 模板
  • 確定非同步需求(網頁控制器、服務)
  • 查看縮放和邊距設置
  • 備份現有 PDF 輸出以供比較
  • 獲得IronPDF授權金鑰

套件變更

  • 移除 NReco.PdfGenerator NuGet 套件
  • 安裝 IronPdf NuGet 套件:dotnet add package IronPdf
  • 更新命名空間導入從 using NReco.PdfGenerator;using IronPdf;

程式碼變更

  • 在啟動時加入授權金鑰配置
  • ChromePdfRenderer 替換 HtmlToPdfConverter
  • RenderHtmlAsPdf(html) 替換 GeneratePdf(html)
  • RenderUrlAsPdf(url) 替換 GeneratePdfFromFile(url, null)
  • PageMargins 物件轉換為個別邊距屬性
  • 將縮放值從浮點數更新為百分比
  • 更新佔位符語法:[page]{page}, [topage]{total-pages}
  • pdf.SaveAs() 替換 File.WriteAllBytes()
  • 在有益的情況下將同步呼叫轉換為非同步

遷移後

  • 從專案/部署中刪除 wkhtmltopdf 二進位檔
  • 更新 Docker 檔案以移除 wkhtmltopdf 安裝
  • 執行回歸測試比較 PDF 輸出
  • 驗證頁眉/頁腳佔位符正確呈現
  • 在所有目標平台(Windows, Linux, macOS)上進行測試
  • 更新 CI/CD 管道以移除 wkhtmltopdf 步驟
  • 更新安全掃描以確認 CVE 的移除

請注意: NReco 和 wkhtmltopdf 是各自所有者的註冊商標。 本網站與 NReco 或 wkhtmltopdf 無關、未被批准或贊助。 所有產品名稱、標誌和品牌均為其各自所有者的財產。 比較僅供參考,反映撰寫時公開可用的資訊。
Curtis Chau
技術作家

Curtis Chau擁有Carleton大學的電腦科學學士學位,專精於前端開發,擁有Node.js、TypeScript、JavaScript和React的專業知識。Curtis熱衷於建立直觀且美觀的使用者介面,喜愛使用現代框架並建立結構良好、視覺吸引力的手冊。

...
閱讀更多

相關文章

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天試用金鑰
無需信用卡或帳戶建立