比较

TuesPechkin 与 IronPDF:技术比较指南

当.NET 开发人员需要将 HTML 转换为 PDF 时,有几个围绕传统渲染引擎构建的封装库可供选择。TuesPechkin就是这样一种解决方案,它封装了 wkhtmltopdf 库,提供 PDF 生成功能。 本技术比较将研究TuesPechkin和 IronPDF,以帮助架构师和开发人员了解传统封装器和现代 PDF 库之间的权衡。

了解 TuesPechkin

TuesPechkin 是 wkhtmltopdf 库的线程安全封装程序,旨在帮助开发人员从 HTML 内容生成 PDF 文档。 该库通过提供ThreadSafeConverter实现来应对wkhtmltopdf固有的并发挑战。

但TuesPechkin继承了其底层技术的基本局限性:

-已弃用的基金会:TuesPechkin为 wkhtmltopdf 提供转载服务,该项目上次更新于 2015 年,并于 2022 年 12 月正式弃用。 -渲染引擎过时:使用 Qt WebKit 4.8,这是 Chrome 时代之前的渲染引擎。

  • 复杂线程管理:需要开发人员通过RemotingToolset和部署模式手动配置线程安全
  • 负载下的稳定性:即使配置了线程安全,库在高并发时可能会因AccessViolationException或进程挂起而崩溃
  • CSS 支持有限:不支持 Flexbox 或 CSS Grid 等现代 CSS 特性。
  • JavaScript 的局限性: JavaScript 执行不稳定,不支持 ES6+。

安全考虑因素

TuesPechkin 继承了 wkhtmltopdf 的所有安全漏洞。 CVE-2022-35583 被评为 "严重"(9.8/10),是一个影响所有TuesPechkin版本的服务器端请求伪造漏洞。 由于 wkhtmltopdf 已被弃用,此漏洞将永远不会被修补,这意味着使用TuesPechkin的应用程序将永远暴露在漏洞中。

了解IronPDF

IronPDF 采用了一种根本不同的方法,它提供了一个具有本地线程安全和基于 Chromium 的渲染引擎的现代商用 PDF 库。IronPDF 并未对传统工具进行封装,而是将 PDF 生成作为其主要重点。

IronPDF的主要特点包括:

-现代 Chromium 引擎:支持 HTML5、CSS3、Flexbox、CSS Grid 和 ES6+ JavaScript -原生线程安全:无需手动线程管理——并发操作自动运行 -积极开发:每周更新和持续改进 -全面的 PDF 功能:除了生成 PDF 之外,还包括编辑、数字签名、PDF/A 合规性和表单填写。 -集成简便:无需原生二进制部署,即可通过 NuGet 直接安装

功能对比

下表重点介绍了TuesPechkin和IronPDF之间的技术差异:

特征TuesPechkinIronPDF
许可免费(MIT 许可)商业翻译
线程安全需要人工管理本地支持
货币有局限性,在负载情况下可能会崩溃稳健,可处理高并发
开发状态不活跃,最后更新时间为 2015 年积极、持续的改进
易用性复杂的设置方便用户使用的指南
文档基本的包含大量示例
渲染引擎Qt WebKit 4.8(已过时)现代 Chromium
CSS3 支持部分翻译支持
Flexbox/网格不支持支持
JavaScript语言不可靠完整的 ES6+
PDF 操作不可用支持
数字签名不可用支持
PDF/A合规性不可用支持
表格填写不可用支持
水印不可用支持
合并/拆分不可用支持
页眉/页脚仅限基本文本完全支持 HTML
安全补丁永不(放弃)定期更新

API 架构差异

在研究初始化模式和基本用法时,可以立即发现TuesPechkin和IronPDF在架构上的差异。

TuesPechkin初始化复杂性

TuesPechkin 需要一个复杂的初始化过程,涉及转换器、工具集和部署配置:

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

class Program
{
    static void Main()
    {
        var converter = new StandardConverter(
            new RemotingToolset<PdfToolset>(
                new Win64EmbeddedDeployment(
                    new TempFolderDeployment())));

        string html = "<html><body><h1>Hello World</h1></body></html>";
        byte[] pdfBytes = converter.Convert(new HtmlToPdfDocument
        {
            Objects = { new ObjectSettings { HtmlText = html } }
        });

        File.WriteAllBytes("output.pdf", pdfBytes);
    }
}
// NuGet: Install-Package TuesPechkin
using TuesPechkin;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new StandardConverter(
            new RemotingToolset<PdfToolset>(
                new Win64EmbeddedDeployment(
                    new TempFolderDeployment())));

        string html = "<html><body><h1>Hello World</h1></body></html>";
        byte[] pdfBytes = converter.Convert(new HtmlToPdfDocument
        {
            Objects = { new ObjectSettings { HtmlText = html } }
        });

        File.WriteAllBytes("output.pdf", pdfBytes);
    }
}
Imports TuesPechkin
Imports System.IO

Class Program
    Shared Sub Main()
        Dim converter = New StandardConverter(
            New RemotingToolset(Of PdfToolset)(
                New Win64EmbeddedDeployment(
                    New TempFolderDeployment())))

        Dim html As String = "<html><body><h1>Hello World</h1></body></html>"
        Dim pdfBytes As Byte() = converter.Convert(New HtmlToPdfDocument With {
            .Objects = {New ObjectSettings With {.HtmlText = html}}
        })

        File.WriteAllBytes("output.pdf", pdfBytes)
    End Sub
End Class
$vbLabelText   $csharpLabel

这种模式需要理解多个嵌套类:TempFolderDeployment。 部署配置也必须与目标平台架构(x86/x64)相匹配。

IronPDF简化方法

IronPDF 通过简单明了的 API 完全消除了部署的复杂性:

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

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();

        string html = "<html><body><h1>Hello World</h1></body></html>";
        var pdf = renderer.RenderHtmlAsPdf(html);

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

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();

        string html = "<html><body><h1>Hello World</h1></body></html>";
        var pdf = renderer.RenderHtmlAsPdf(html);

        pdf.SaveAs("output.pdf");
    }
}
Imports IronPdf
Imports System

Class Program
    Shared Sub Main()
        Dim renderer = New ChromePdfRenderer()

        Dim html As String = "<html><body><h1>Hello World</h1></body></html>"
        Dim pdf = renderer.RenderHtmlAsPdf(html)

        pdf.SaveAs("output.pdf")
    End Sub
End Class
$vbLabelText   $csharpLabel

ChromePdfRenderer 类可立即访问 PDF 生成,无需特定平台配置。 有关全面的 HTML 转换指导,请参阅 HTML 转 PDF 教程

将 URL 转换为 PDF.

将网页转换为 PDF 文档展示了两个库之间的 API 可用性差异。

TuesPechkin实现

TuesPechkin在PageUrl属性来指定URL:

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

class Program
{
    static void Main()
    {
        var converter = new StandardConverter(
            new RemotingToolset<PdfToolset>(
                new Win64EmbeddedDeployment(
                    new TempFolderDeployment())));

        byte[] pdfBytes = converter.Convert(new HtmlToPdfDocument
        {
            Objects = {
                new ObjectSettings {
                    PageUrl = "https://www.example.com"
                }
            }
        });

        File.WriteAllBytes("webpage.pdf", pdfBytes);
    }
}
// NuGet: Install-Package TuesPechkin
using TuesPechkin;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new StandardConverter(
            new RemotingToolset<PdfToolset>(
                new Win64EmbeddedDeployment(
                    new TempFolderDeployment())));

        byte[] pdfBytes = converter.Convert(new HtmlToPdfDocument
        {
            Objects = {
                new ObjectSettings {
                    PageUrl = "https://www.example.com"
                }
            }
        });

        File.WriteAllBytes("webpage.pdf", pdfBytes);
    }
}
Imports TuesPechkin
Imports System.IO

Class Program
    Shared Sub Main()
        Dim converter = New StandardConverter(
            New RemotingToolset(Of PdfToolset)(
                New Win64EmbeddedDeployment(
                    New TempFolderDeployment())))

        Dim pdfBytes As Byte() = converter.Convert(New HtmlToPdfDocument With {
            .Objects = {
                New ObjectSettings With {
                    .PageUrl = "https://www.example.com"
                }
            }
        })

        File.WriteAllBytes("webpage.pdf", pdfBytes)
    End Sub
End Class
$vbLabelText   $csharpLabel

由于缺少 CSS3 和 JavaScript 支持,过时的 WebKit 引擎可能会错误地呈现现代网站。

IronPDF的实现

IronPDF 利用其现代 Chromium 引擎为 URL 渲染提供了专用方法:

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

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;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();

        var pdf = renderer.RenderUrlAsPdf("https://www.example.com");

        pdf.SaveAs("webpage.pdf");
    }
}
Imports IronPdf
Imports System

Class Program
    Shared Sub Main()
        Dim renderer = New ChromePdfRenderer()

        Dim pdf = renderer.RenderUrlAsPdf("https://www.example.com")

        pdf.SaveAs("webpage.pdf")
    End Sub
End Class
$vbLabelText   $csharpLabel

RenderUrlAsPdf 方法可在无头 Chromium 浏览器中加载页面,执行 JavaScript 并准确应用所有现代 CSS 样式。 这对于使用 React、Angular 或 Vue.js 等框架构建的网络应用程序至关重要,因为TuesPechkin无法正确呈现这些网络应用程序。

自定义渲染设置

配置页面尺寸、页边距和方向揭示了文档设置的不同方法。

TuesPechkin配置

TuesPechkin使用ObjectSettings类配置嵌套:

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

class Program
{
    static void Main()
    {
        var converter = new StandardConverter(
            new RemotingToolset<PdfToolset>(
                new Win64EmbeddedDeployment(
                    new TempFolderDeployment())));

        string html = "<html><body><h1>Custom PDF</h1></body></html>";

        var document = new HtmlToPdfDocument
        {
            GlobalSettings = {
                Orientation = GlobalSettings.PdfOrientation.Landscape,
                PaperSize = GlobalSettings.PdfPaperSize.A4,
                Margins = new MarginSettings { Unit = Unit.Millimeters, Top = 10, Bottom = 10 }
            },
            Objects = {
                new ObjectSettings { HtmlText = html }
            }
        };

        byte[] pdfBytes = converter.Convert(document);
        File.WriteAllBytes("custom.pdf", pdfBytes);
    }
}
// NuGet: Install-Package TuesPechkin
using TuesPechkin;
using System.IO;

class Program
{
    static void Main()
    {
        var converter = new StandardConverter(
            new RemotingToolset<PdfToolset>(
                new Win64EmbeddedDeployment(
                    new TempFolderDeployment())));

        string html = "<html><body><h1>Custom PDF</h1></body></html>";

        var document = new HtmlToPdfDocument
        {
            GlobalSettings = {
                Orientation = GlobalSettings.PdfOrientation.Landscape,
                PaperSize = GlobalSettings.PdfPaperSize.A4,
                Margins = new MarginSettings { Unit = Unit.Millimeters, Top = 10, Bottom = 10 }
            },
            Objects = {
                new ObjectSettings { HtmlText = html }
            }
        };

        byte[] pdfBytes = converter.Convert(document);
        File.WriteAllBytes("custom.pdf", pdfBytes);
    }
}
Imports TuesPechkin
Imports System.IO

Module Program
    Sub Main()
        Dim converter = New StandardConverter(
            New RemotingToolset(Of PdfToolset)(
                New Win64EmbeddedDeployment(
                    New TempFolderDeployment())))

        Dim html As String = "<html><body><h1>Custom PDF</h1></body></html>"

        Dim document = New HtmlToPdfDocument With {
            .GlobalSettings = New GlobalSettings With {
                .Orientation = GlobalSettings.PdfOrientation.Landscape,
                .PaperSize = GlobalSettings.PdfPaperSize.A4,
                .Margins = New MarginSettings With {.Unit = Unit.Millimeters, .Top = 10, .Bottom = 10}
            },
            .Objects = {
                New ObjectSettings With {.HtmlText = html}
            }
        }

        Dim pdfBytes As Byte() = converter.Convert(document)
        File.WriteAllBytes("custom.pdf", pdfBytes)
    End Sub
End Module
$vbLabelText   $csharpLabel

IronPDF配置

IronPDF在RenderingOptions属性中集中设置,具有直观的属性名称:

// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Engines.Chrome;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();

        renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;
        renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
        renderer.RenderingOptions.MarginTop = 10;
        renderer.RenderingOptions.MarginBottom = 10;

        string html = "<html><body><h1>Custom PDF</h1></body></html>";
        var pdf = renderer.RenderHtmlAsPdf(html);

        pdf.SaveAs("custom.pdf");
    }
}
// NuGet: Install-Package IronPdf
using IronPdf;
using IronPdf.Engines.Chrome;
using System;

class Program
{
    static void Main()
    {
        var renderer = new ChromePdfRenderer();

        renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape;
        renderer.RenderingOptions.PaperSize = PdfPaperSize.A4;
        renderer.RenderingOptions.MarginTop = 10;
        renderer.RenderingOptions.MarginBottom = 10;

        string html = "<html><body><h1>Custom PDF</h1></body></html>";
        var pdf = renderer.RenderHtmlAsPdf(html);

        pdf.SaveAs("custom.pdf");
    }
}
Imports IronPdf
Imports IronPdf.Engines.Chrome
Imports System

Module Program
    Sub Main()
        Dim renderer As New ChromePdfRenderer()

        renderer.RenderingOptions.PaperOrientation = PdfPaperOrientation.Landscape
        renderer.RenderingOptions.PaperSize = PdfPaperSize.A4
        renderer.RenderingOptions.MarginTop = 10
        renderer.RenderingOptions.MarginBottom = 10

        Dim html As String = "<html><body><h1>Custom PDF</h1></body></html>"
        Dim pdf = renderer.RenderHtmlAsPdf(html)

        pdf.SaveAs("custom.pdf")
    End Sub
End Module
$vbLabelText   $csharpLabel

RenderingOptions 类提供了一种统一的配置方法,在该方法中,边距值直接以毫米为单位指定,而无需包装对象。

线程安全和并发性

线程安全是服务器端 PDF 生成的一个重要考虑因素,而这两个库采用了根本不同的方法。

TuesPechkin线程管理

TuesPechkin通过其ThreadSafeConverter宣传线程安全操作,但实现上有文档记录的限制:

//TuesPechkin- Even with ThreadSafeConverter, crashes under load
var converter = new TuesPechkin.ThreadSafeConverter(
    new TuesPechkin.RemotingToolset<PechkinBindings>());

// Under high load, applications may experience:
// - System.AccessViolationException
// - StackOverflowException
// - Process hangs indefinitely
// - Memory corruption
//TuesPechkin- Even with ThreadSafeConverter, crashes under load
var converter = new TuesPechkin.ThreadSafeConverter(
    new TuesPechkin.RemotingToolset<PechkinBindings>());

// Under high load, applications may experience:
// - System.AccessViolationException
// - StackOverflowException
// - Process hangs indefinitely
// - Memory corruption
' TuesPechkin- Even with ThreadSafeConverter, crashes under load
Dim converter = New TuesPechkin.ThreadSafeConverter(
    New TuesPechkin.RemotingToolset(Of PechkinBindings)())

' Under high load, applications may experience:
' - System.AccessViolationException
' - StackOverflowException
' - Process hangs indefinitely
' - Memory corruption
$vbLabelText   $csharpLabel

底层的 wkhtmltopdf 库并不是为高并发场景而设计的,即使采用了封装级线程管理,在高负载情况下仍会出现稳定性问题。

IronPDF本地并发性

IronPDF 提供本地线程安全,无需任何配置:

//IronPDF- Native thread safety
var renderer = new ChromePdfRenderer();

// Safe for concurrent use across multiple threads
// No AccessViolationException
// No process hangs
// Stable under high load
//IronPDF- Native thread safety
var renderer = new ChromePdfRenderer();

// Safe for concurrent use across multiple threads
// No AccessViolationException
// No process hangs
// Stable under high load
'IronPDF- Native thread safety
Dim renderer As New ChromePdfRenderer()

' Safe for concurrent use across multiple threads
' No AccessViolationException
' No process hangs
' Stable under high load
$vbLabelText   $csharpLabel

ChromePdfRenderer在内部处理并发性,允许开发人员专注于应用程序逻辑而非线程同步。

支持现代 CSS 和 JavaScript.

在使用现代网络技术时,TruesPechkin 和IronPDF之间的渲染引擎差异最为明显。

TuesPechkin渲染限制

TuesPechkin 的 Qt WebKit 4.8 引擎早于现代 CSS 布局系统:


<div style="display: flex; justify-content: space-between; gap: 20px;">
    <div style="flex: 1;">Column 1</div>
    <div style="flex: 1;">Column 2</div>
</div>

<div style="display: grid; grid-template-columns: repeat(3, 1fr);">
    <div>Grid Item 1</div>
    <div>Grid Item 2</div>
    <div>Grid Item 3</div>
</div>

<div style="display: flex; justify-content: space-between; gap: 20px;">
    <div style="flex: 1;">Column 1</div>
    <div style="flex: 1;">Column 2</div>
</div>

<div style="display: grid; grid-template-columns: repeat(3, 1fr);">
    <div>Grid Item 1</div>
    <div>Grid Item 2</div>
    <div>Grid Item 3</div>
</div>
HTML

使用TuesPechkin的应用程序必须依靠基于表格的布局或其他 CSS2.1 变通方法来实现多栏设计。

IronPDF现代渲染

IronPDF 的 Chromium 引擎支持所有现代 CSS 和 JavaScript:

// Modern CSS works correctly with IronPDF
var html = @"
    <div style='display: flex; justify-content: space-between;'>
        <div>Left</div>
        <div>Right</div>
    </div>";

var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
// Renders correctly with full Flexbox support
// Modern CSS works correctly with IronPDF
var html = @"
    <div style='display: flex; justify-content: space-between;'>
        <div>Left</div>
        <div>Right</div>
    </div>";

var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);
// Renders correctly with full Flexbox support
Dim html As String = "
    <div style='display: flex; justify-content: space-between;'>
        <div>Left</div>
        <div>Right</div>
    </div>"

Dim renderer As New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf(html)
' Renders correctly with full Flexbox support
$vbLabelText   $csharpLabel

这样,开发人员就可以使用相同的 HTML/CSS 进行网页显示和 PDF 生成,而无需维护单独的模板。

当团队考虑替代TuesPechkin时

有几种情况通常会促使开发团队评估TuesPechkin的替代方案:

安全要求

随着 CVE-2022-35583 被评为危急(9.8/10),以及底层 wkhtmltopdf 库被正式放弃,有安全合规性要求的组织不能继续使用 TuesPechkin。 SSRF 漏洞允许攻击者通过恶意 HTML 内容访问内部网络、窃取凭证和外泄数据。

现代网络技术的采用

采用现代前端框架(React、Angular、Vue.js)或 CSS 布局系统(Flexbox、Grid)的团队发现TuesPechkin无法准确呈现他们的内容。 过时的 WebKit 4.8 引擎不支持近十年来一直作为标准的技术。

负载下的稳定性

服务器端应用程序在并发PDF生成负载下遇到崩溃、挂起或AccessViolationException错误时,通常将这些问题追溯到TuesPechkin的线程限制。 即使有ThreadSafeConverter配置,底层的wkhtmltopdf库也不是为高并发环境设计的。

PDF 功能要求

TuesPechkin 只提供 HTML 到 PDF 的转换。 需要进行 PDF 操作(合并、拆分)、数字签名、PDF/A 合规性、表格填充或水印的团队必须添加额外的库,或考虑IronPDF等原生提供这些功能的替代工具。

简化部署

TuesPechkin的初始化模式与TempFolderDeployment增加了部署复杂性。 必须为每个目标环境正确配置特定平台的本地二进制文件。IronPDF通过标准的 NuGet 安装消除了这种复杂性。

API 映射参考

正在评估从TuesPechkin向IronPDF过渡的团队会发现此映射有助于理解概念等同:

TuesPechkinIronPDF
StandardConverter / ThreadSafeConverterChromePdfRenderer
HtmlToPdfDocument方法参数
GlobalSettings.PaperSizeRenderingOptions.PaperSize
GlobalSettings.OrientationRenderingOptions.PaperOrientation
GlobalSettings.MarginsRenderingOptions.MarginTop/Bottom/Left/Right
ObjectSettings.HtmlTextRenderHtmlAsPdf(html)
ObjectSettings.PageUrlRenderUrlAsPdf(url)
RemotingToolset + Deployment不需要
[page] placeholder{page} placeholder
[toPage] placeholder{total-pages} placeholder

其他 PDF 功能

除了 HTML 到 PDF 的转换之外,IronPDF 还提供了TuesPechkin无法提供的文档操作功能:

-合并 PDF将多个文档合并成单个文件 -拆分文档将页面范围提取到单独的 PDF 文件中 -数字签名应用加密签名来验证文档的真实性 -水印通过 HTML/CSS 添加文本或图像水印

.NET兼容性和未来准备情况

TuesPechkin 的非活跃开发状态意味着不会对较新的 .NET 版本进行更新。IronPDFfor .NET 保持着定期更新的积极开发态势,确保与 .NET 8、.NET 9 和未来版本(包括预计于 2026 年发布的 .NET 10)的兼容性。该库的整个 API 均支持 async/await,符合现代 C# 开发实践,包括 C# 13 中的可用功能和预期的 C# 14 功能。

结论

TuesPechkin 和IronPDF代表了 .NET PDF 生成的不同时代。TuesPechkin提供了一个免费的、获得 MIT 许可的 wkhtmltopdf 封装器,但继承了严重的安全漏洞、过时的渲染引擎、复杂的线程管理要求以及负载下的稳定性问题。 底层技术已于 2022 年被弃用,没有安全补丁。

IronPDF 提供了一个现代化的、积极维护的替代方案,其基于 Chromium 的渲染引擎支持当前的网络技术。 它的本地线程安全性、全面的 PDF 功能和直接的 API 设计解决了 wkhtmltopdf 封装器固有的局限性。

对于目前使用TuesPechkin的团队来说,迁移的决定往往源于安全要求、渲染质量需要、稳定性问题或对基本 HTML 转换之外的 PDF 功能的要求。 这两个库之间的 API 映射简单明了,IronPDF 由于简化了初始化和配置模式,通常需要较少的代码。

有关更多实施指导,请浏览 IronPDF 文档和涵盖特定用例和高级功能的 教程

请注意TuesPechkin和wkhtmltopdf是其各自所有者的注册商标。 本站与TuesPechkin或wkhtmltopdf无关联、无认证或赞助关系。 所有产品名称、徽标和品牌均为各自所有者的财产。 比较仅供参考,反映撰写时公开可用的信息。)}]