跳過到頁腳內容
遷移指南

如何在 C# 中從 NReco PDF 生成器轉換到 IronPDF

為何要從NReco PDF 生成器移轉至 IronPDF?

NReco PDF 生成器的關鍵安全問題

NReco PDF Generator 包覆了已廢棄的 wkhtmltopdf 二進位檔,繼承了其所有的安全漏洞。 這並非理論上的問題,自 wkhtmltopdf 於 2020 年被棄用後,已有 20 多個記錄在案的 CVE,但卻沒有可用的修補程式:

  • CVE-2020-21365:伺服器端請求偽造 (SSRF)
  • CVE-2022-35583:透過 HTML 注入讀取本機文件
  • CVE-2022-35580:遠端程式碼執行漏洞

這些漏洞無法修補,因為底層的 wkhtmltopdf 專案已不再維護。

額外的 NReco PDF 生成器限制

1.有浮水印的免費版本:生產用途需要付費許可證,定價不透明,需要聯絡銷售人員。

2.已棄用的渲染引擎: WebKit Qt(大約在 2012 年)提供的現代 Web 支援有限:

  • 無 CSS Grid 或 Flexbox
  • 不使用現代JavaScript(ES6+)
  • 網頁字型支援不佳
  • 無 CSS 變數或自訂屬性

3.外部二進位依賴:需要管理每個平台的 wkhtmltopdf 二進位(wkhtmltopdf.exewkhtmltox.dll)。

4.無主動開發:封裝器得到維護,但底層引擎沒有更新。

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

NReco PDF 生成器與IronPDF的比較

範疇 NReco PDF 生成器 IronPDF
渲染引擎 WebKit Qt (2012) Chromium (目前)
安全性 20 多個 CVE,沒有修補程式 主動安全更新
CSS 支援 CSS2.1, 有限的 CSS3 完整的 CSS3、網格、Flexbox
JavaScript 基本 ES5 完整的 ES6+、async/await
依賴 外部 wkhtmltopdf 二進位 自成一格
同步支援 僅同步 完整的 async/await
網頁字型 限額 完整的 Google 字型,@font-face
授權 價格不透明,請聯絡銷售人員 透明的定價
免費試用 水印 完整功能

對於計劃在 2025 年和 2026 年之前採用 .NET 10 和 C# 14 的團隊而言,IronPDF 提供了一個面向未來的基礎,具有積極的開發和現代化的渲染能力。


開始之前

先決條件

  1. .NET環境: .NET Framework 4.6.2+ 或.NET Core 3.1+ / .NET 5/6/7/8/9+
  2. NuGet存取權限:能夠安裝NuGet套件
  3. IronPDF許可證:請從IronPDF取得您的許可證密鑰。

NuGet 套件變更

# Remove NReco.PdfGenerator
dotnet remove package NReco.PdfGenerator

# Install IronPDF
dotnet add package IronPdf
# Remove NReco.PdfGenerator
dotnet remove package NReco.PdfGenerator

# Install IronPDF
dotnet add package IronPdf
SHELL

同時從您的部署中移除 wkhtmltopdf 二進位檔案

  • 從項目中刪除 wkhtmltopdf.exewkhtmltox.dll
  • 移除任何 wkhtmltopdf 安裝腳本
  • 刪除特定平台的二進位資料夾

授權組態

// Add at application startup (Program.cs or Startup.cs)
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
// 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"
$vbLabelText   $csharpLabel

識別 NReco PDF 生成器用法

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

完整的 API 參考資料

核心類對應

NReco PDF 生成器 IronPDF
HtmlToPdfConverter ChromePdfRenderer
PageMargins 個別邊界屬性
PageOrientation PdfPaperOrientation
PageSize PdfPaperSize

渲染方法映射

NReco PDF 生成器 IronPDF
GeneratePdf(html) RenderHtmlAsPdf(html)
GeneratePdfFromFile(url, output) RenderUrlAsPdf(url)
GeneratePdfFromFile(htmlPath, output) RenderHtmlFileAsPdf(path)
(不支援 async) RenderHtmlAsPdfAsync(html)
(不支援 async) RenderUrlAsPdfAsync(url)

頁面組態對應

NReco PDF 生成器 IronPDF
PageWidth = 210 RenderingOptions.PaperSize = PdfPaperSize.A4
PageHeight = 297 RenderingOptions.SetCustomPaperSizeinMilimeters(w, h)
Orientation = PageOrientation.Landscape RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape
Size = PageSize.A4 RenderingOptions.PaperSize = PdfPaperSize.A4

邊界對應

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

頁首/頁尾占位符對應

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

輸出處理映射

NReco PDF 生成器 IronPDF
byte[] pdfBytes = GeneratePdf(html) PdfDocument pdf = RenderHtmlAsPdf(html)
File.WriteAllBytes(path, bytes) pdf.SaveAs(path)
return pdfBytes return pdf.BinaryData
new MemoryStream(pdfBytes) pdf.Stream

程式碼遷移範例

範例 1:基本 HTML 到 PDF

之前 (NReco PDF 生成器):

// 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);
    }
}
// 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);
    }
}
Imports NReco.PdfGenerator
Imports System.IO

Class Program
    Shared Sub Main()
        Dim htmlToPdf = New HtmlToPdfConverter()
        Dim htmlContent = "<html><body><h1>Hello World</h1><p>This is a PDF document.</p></body></html>"
        Dim pdfBytes = htmlToPdf.GeneratePdf(htmlContent)
        File.WriteAllBytes("output.pdf", pdfBytes)
    End Sub
End Class
$vbLabelText   $csharpLabel

After (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");
    }
}
// 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");
    }
}
Imports IronPdf
Imports System.IO

Class Program
    Shared Sub Main()
        Dim renderer = New ChromePdfRenderer()
        Dim htmlContent = "<html><body><h1>Hello World</h1><p>This is a PDF document.</p></body></html>"
        Dim pdf = renderer.RenderHtmlAsPdf(htmlContent)
        pdf.SaveAs("output.pdf")
    End Sub
End Class
$vbLabelText   $csharpLabel

基本差異在於回傳類型和儲存模式。NReco PDF 生成器的 HtmlToPdfConverter.GeneratePdf() 傳回一個 byte[],您必須使用 File.WriteAllBytes() 手動將其寫入磁碟。IronPDF的 ChromePdfRenderer.RenderHtmlAsPdf() 傳回一個 PdfDocument 對象,該物件具有內建的 SaveAs() 方法。

這種物件導向的方法提供了額外的好處:您可以在儲存之前對 PDF 進行操作(新增水印、合併文件、新增安全性)。 如果您需要原始位元組以與現有程式碼相容,請使用 pdf.BinaryData。 請參閱 HTML to PDF 文件,以瞭解其他渲染選項。

範例 2:自訂頁面大小與頁邊空白

之前 (NReco PDF 生成器):

// 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);
    }
}
// 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);
    }
}
Imports NReco.PdfGenerator
Imports System.IO

Class Program
    Shared Sub Main()
        Dim htmlToPdf = New HtmlToPdfConverter()
        htmlToPdf.PageWidth = 210
        htmlToPdf.PageHeight = 297
        htmlToPdf.Margins = New PageMargins With {.Top = 10, .Bottom = 10, .Left = 10, .Right = 10}
        Dim htmlContent = "<html><body><h1>Custom Page Size</h1><p>A4 size document with margins.</p></body></html>"
        Dim pdfBytes = htmlToPdf.GeneratePdf(htmlContent)
        File.WriteAllBytes("custom-size.pdf", pdfBytes)
    End Sub
End Class
$vbLabelText   $csharpLabel

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.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");
    }
}
// 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");
    }
}
Imports IronPdf
Imports IronPdf.Rendering

Class Program
    Shared Sub Main()
        Dim renderer = New ChromePdfRenderer()
        renderer.RenderingOptions.PaperSize = PdfPaperSize.A4
        renderer.RenderingOptions.MarginTop = 10
        renderer.RenderingOptions.MarginBottom = 10
        renderer.RenderingOptions.MarginLeft = 10
        renderer.RenderingOptions.MarginRight = 10
        Dim htmlContent = "<html><body><h1>Custom Page Size</h1><p>A4 size document with margins.</p></body></html>"
        Dim pdf = renderer.RenderHtmlAsPdf(htmlContent)
        pdf.SaveAs("custom-size.pdf")
    End Sub
End Class
$vbLabelText   $csharpLabel

NReco PDF 產生器使用數值維度(PageWidth = 210PageHeight = 297)和 PageMargins 物件。IronPDF使用 PdfPaperSize 枚舉(包括 A4、Letter、Legal 等標準尺寸)和 RenderingOptions 物件上的各個邊距屬性。

主要的轉移變化:

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

對於枚舉未涵蓋的自訂紙張尺寸,請使用 RenderingOptions.SetCustomPaperSizeinMilimeters(width, height)。 進一步瞭解 頁面配置選項

範例 3:URL 到 PDF 的轉換

之前 (NReco PDF 生成器):

// 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);
    }
}
// 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);
    }
}
Imports NReco.PdfGenerator
Imports System.IO

Class Program
    Shared Sub Main()
        Dim htmlToPdf As New HtmlToPdfConverter()
        Dim pdfBytes As Byte() = htmlToPdf.GeneratePdfFromFile("https://www.example.com", Nothing)
        File.WriteAllBytes("webpage.pdf", pdfBytes)
    End Sub
End Class
$vbLabelText   $csharpLabel

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

Class Program
    Shared Sub Main()
        Dim renderer As New ChromePdfRenderer()
        Dim pdf = renderer.RenderUrlAsPdf("https://www.example.com")
        pdf.SaveAs("webpage.pdf")
    End Sub
End Class
$vbLabelText   $csharpLabel

NReco PDF Generator 對本機檔案和 URL 都使用了名稱令人困惑的 GeneratePdfFromFile() 方法,並且第二個參數可以為空。IronPDF提供專用方法:RenderUrlAsPdf() 用於 URL,RenderHtmlFileAsPdf() 用於本機 HTML 檔案。

IronPDF 的方法更簡潔、更直覺。對於非同步 Web 應用程序,請使用 await renderer.RenderUrlAsPdfAsync(url) 來避免阻塞線程——這是NReco PDF 生成器無法做到的。


關鍵遷移注意事項

縮放值轉換

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 Generator: Zoom = 0.9f (90%)
// IronPDF: Zoom = 90

// Conversion formula:
int ironPdfZoom = (int)(nrecoZoom * 100);
' NReco PDF Generator: Zoom = 0.9F (90%)
' IronPDF: Zoom = 90

' Conversion formula:
Dim ironPdfZoom As Integer = CInt(nrecoZoom * 100)
$vbLabelText   $csharpLabel

占位符語法更新

所有頁首/頁尾的占位符都必須更新:

NReco PDF 生成器 IronPDF
[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:
converter.PageFooterHtml = "<div>Page [page] of [topage]</div>";

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

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

' IronPDF:
renderer.RenderingOptions.HtmlFooter = New HtmlHeaderFooter With {
    .HtmlFragment = "<div>Page {page} of {total-pages}</div>",
    .MaxHeight = 20
}
$vbLabelText   $csharpLabel

返回類型變更

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

//NReco PDF 生成器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 生成器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;
Imports System.IO

' NReco PDF 生成器pattern:
Dim pdfBytes As Byte() = converter.GeneratePdf(html)
File.WriteAllBytes("output.pdf", pdfBytes)

' IronPDFpattern:
Dim pdf = renderer.RenderHtmlAsPdf(html)
pdf.SaveAs("output.pdf")

' Or if you need bytes:
Dim pdfBytes As Byte() = renderer.RenderHtmlAsPdf(html).BinaryData
$vbLabelText   $csharpLabel

線程安全與重複性

NReco PDF Generator 通常會在每次呼叫時建立新的轉換器。IronPDF的 ChromePdfRenderer 是線程安全的,可以重複使用:

//NReco PDF 生成器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;
}
//NReco PDF 生成器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;
}
Imports NReco.PdfGenerator
Imports IronPdf

' NReco PDF 生成器pattern (creates new each time):
Public Function Generate(html As String) As Byte()
    Dim converter As New HtmlToPdfConverter()
    Return converter.GeneratePdf(html)
End Function

' IronPDFpattern (reuse renderer, thread-safe):
Private ReadOnly _renderer As New ChromePdfRenderer()

Public Function Generate(html As String) As Byte()
    Return _renderer.RenderHtmlAsPdf(html).BinaryData
End Function
$vbLabelText   $csharpLabel

同步支援(新功能)

IronPDF 支援NReco PDF 生成器無法提供的 async/await 模式:

// 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;
}
// 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;
}
Imports System.Threading.Tasks

' NReco PDF Generator: No async support available

' IronPDF: Full async support
Public Async Function GenerateAsync(html As String) As Task(Of Byte())
    Dim pdf = Await _renderer.RenderHtmlAsPdfAsync(html)
    Return pdf.BinaryData
End Function
$vbLabelText   $csharpLabel

疑難排解

問題 1:HtmlToPdfConverter 未找到

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

解:使用 ChromePdfRenderer:

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

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

// IronPDF
var renderer = new ChromePdfRenderer();
' NReco PDF Generator
Dim converter As New HtmlToPdfConverter()

' IronPDF
Dim renderer As New ChromePdfRenderer()
$vbLabelText   $csharpLabel

問題 2:GeneratePdf 返回錯誤的類型

問題:代碼期望 byte[],但得到 PdfDocument

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

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

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

// IronPDF
byte[] pdfBytes = renderer.RenderHtmlAsPdf(html).BinaryData;
' NReco PDF Generator
Dim pdfBytes As Byte() = converter.GeneratePdf(html)

' IronPDF
Dim pdfBytes As Byte() = renderer.RenderHtmlAsPdf(html).BinaryData
$vbLabelText   $csharpLabel

問題 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;
// 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;
' NReco PDF Generator
converter.Margins = New PageMargins With {.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
$vbLabelText   $csharpLabel

問題 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 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
};
Imports NReco.PdfGenerator
Imports IronPdf

converter.PageFooterHtml = "<div>Page [page] of [topage]</div>"

renderer.RenderingOptions.HtmlFooter = New HtmlHeaderFooter With {
    .HtmlFragment = "<div>Page {page} of {total-pages}</div>",
    .MaxHeight = 20
}
$vbLabelText   $csharpLabel

遷移清單

預遷移

  • 清點程式碼庫中所有 NReco.PdfGenerator 的使用情況
  • 記錄所有 CustomWkHtmlArgsCustomWkHtmlPageArgs 值 列出所有有佔位符的頁首/頁尾HTML模板
  • 確定非同步需求(Web 控制器、服務)
  • 檢查縮放和邊距設置
  • 備份現有 PDF 輸出以進行比較
  • 取得IronPDF許可證密鑰

套件變更

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

程式碼變更

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

後遷移

  • 從專案/部署移除 wkhtmltopdf 二進位文件
  • 更新 Docker 檔案以移除 wkhtmltopdf 安裝
  • 執行迴歸測試,比較 PDF 輸出
  • 驗證頁首/頁尾佔位符是否正確渲染。
  • 在所有目標平台(Windows、Linux、macOS)上進行測試
  • 更新 CI/CD 管線,移除 wkhtmltopdf 步驟
  • 更新安全掃描以確認 CVE 已移除

Curtis Chau
技術作家

Curtis Chau 擁有卡爾頓大學計算機科學學士學位,專注於前端開發,擅長於 Node.js、TypeScript、JavaScript 和 React。Curtis 熱衷於創建直觀且美觀的用戶界面,喜歡使用現代框架並打造結構良好、視覺吸引人的手冊。

除了開發之外,Curtis 對物聯網 (IoT) 有著濃厚的興趣,探索將硬體和軟體結合的創新方式。在閒暇時間,他喜愛遊戲並構建 Discord 機器人,結合科技與創意的樂趣。

鋼鐵支援團隊

我們每週 5 天,每天 24 小時在線上。
聊天
電子郵件
打電話給我