跳至页脚内容
视频

如何使用C#将RTF转换为PDF

为什么要从 NReco PDF 生成器迁移到 IronPDF?

NReco PDF 生成器的关键安全问题

NReco PDF Generator 包装了 wkhtmltopdf 二进制文件,继承了其已知的安全漏洞。 wkhtmltopdf 项目的最后一个稳定版本是 0.12.6 (2020年6月),其上游仓库于 2023年1月2日归档,因此不会有任何补丁发布:

  • CVE-2020-21365: 目录遍历/ Crafted HTML 的本地文件读取 (同源策略弱点)
  • CVE-2022-35583: 通过在 0.12.6 中注入的<iframe>进行服务器端请求伪造 (SSRF) (CVSS 9.8)

NReco PDF 生成器的其他限制

  1. 大规模许可摩擦: 对于非SaaS的单服务器生产部署免费; SaaS、多服务器或再分发场景需要从nrecosite.com购买199美元的企业源代码包。

  2. 弃用的渲染引擎: WebKit Qt (约2012年) 仅支持有限的CSS3/JS:

    • 无 CSS 网格或 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 生成器与IronPDF的比较

方面 NReco PDF 生成器 IronPDF
渲染引擎 WebKit Qt (2012) Chromium (当前)
安全性 多个未修补的 CVEs (例如 CVE-2020-21365, CVE-2022-35583); 引擎于2023年1月2日归档 主动安全更新
CSS 支持 CSS2.1, 有限 CSS3 完全 CSS3、网格、Flexbox
JavaScript 基本 ES5 完整的 ES6+、async/await
依赖关系 外部 wkhtmltopdf 二进制文件 自成一体
异步支持 仅同步 完整的Async/Await
网络字体 有限的 完整的谷歌字体,@font-face
许可 非SaaS单服务器免费; SaaS/多服务器199美元企业包 透明的商业定价
免费级别 非SaaS单服务器许可证下免费 试用不需要水印

开始之前

前提条件

  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 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.exe, wkhtmltox.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)
(不支持异步) RenderHtmlAsPdfAsync(html)
(不支持异步) 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) new MemoryStream(pdf.BinaryData)

代码迁移示例

示例 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 生成器的File.WriteAllBytes()手动将其写入磁盘。IronPDF的PdfDocument对象。

这种面向对象的方法还有其他好处:您可以在保存之前对 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 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 生成器):

// 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 使用令人困惑的GeneratePdfFromFile()方法来处理本地文件和 URL,第二个参数是可为空的。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 生成器通常每次调用都会创建一个新的转换器。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 返回错误类型

问题: 代码期望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:页码未显示

问题: [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的使用情况
  • 记录所有CustomWkHtmlPageArgs值 列出所有带有占位符的页眉/页脚HTML模板
  • 确定异步需求(Web 控制器、服务)
  • 检查缩放和边距设置
  • 备份现有 PDF 输出以进行比较
  • 获取IronPDF许可证密钥

软件包变更

  • 移除NReco.PdfGenerator NuGet 包
  • 安装IronPdf NuGet 包: dotnet add package IronPdf
  • 将命名空间导入从using IronPdf;

代码更改

  • 在启动时添加许可证密钥配置
  • HtmlToPdfConverter
  • GeneratePdf(html)
  • GeneratePdfFromFile(url, null)
  • PageMargins对象转换为单独的边距属性
  • 将缩放值从浮点数更新为百分比
  • 更新占位符语法:[page]{page}, [topage]{total-pages}
  • File.WriteAllBytes()
  • 在有利的情况下,将同步调用转换为异步调用。

后迁移

  • 从项目/部署中移除 wkhtmltopdf 二进制文件
  • 更新 Docker 文件以移除 wkhtmltopdf 安装
  • 运行回归测试,比较 PDF 输出
  • 验证页眉/页脚占位符是否正确渲染。
  • 在所有目标平台(Windows、Linux、macOS)上进行测试
  • 更新 CI/CD 流水线,移除 wkhtmltopdf 步骤
  • 更新安全扫描以确认 CVE 已移除

请注意NReco和wkhtmltopdf是其各自所有者的注册商标。 此网站与NReco或wkhtmltopdf无隶属关系、授权或赞助。 所有产品名称、徽标和品牌均为各自所有者的财产。 比较仅供参考,反映撰写时公开可用的信息。

Curtis Chau
技术作家

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

除了开发之外,Curtis 对物联网 (IoT) 有浓厚的兴趣,探索将硬件和软件集成的新方法。在空闲时间,他喜欢玩游戏和构建 Discord 机器人,将他对技术的热爱与创造力相结合。

钢铁支援团队

我们每周 5 天,每天 24 小时在线。
聊天
电子邮件
打电话给我