比较

Gotenberg 与 IronPDF:技术比较指南

当 .NET 开发人员评估 PDF 生成解决方案时,Gotenberg 脱颖而出,它是一个基于 Docker 的微服务,通过 REST API 调用将 HTML 转换为 PDF。 虽然高登堡能够适应各种不同的架构,但它也带来了显著的基础设施开销——Docker 容器、网络延迟和操作复杂性。IronPDF提供了一种替代方案:一个进程内 NuGet 包,提供相同的基于 Chromium 的渲染,而无需容器、网络调用或基础架构管理。

本次比较从技术相关维度对两种解决方案进行了考察,以帮助专业开发人员和架构师根据其 .NET PDF 需求做出明智的决策。

了解哥登堡

Gotenberg 是一种基于 Docker 的 PDF 生成微服务架构。 它作为一个单独的容器运行,可提供 REST API 端点,用于将 HTML、URL 和其他格式转换为 PDF。 每个 PDF 操作都需要对高登堡服务进行 HTTP 调用。

Gotenberg 使用类似 POST /forms/chromium/convert/html 的端点进行 HTML 到 PDF 的转换,使用 POST /forms/chromium/convert/url 进行 URL 到 PDF 的转换。 配置通过 multipart/form-data 传递,使用字符串为基础的参数,如 marginTopmarginBottom(单位为英寸)。 该服务需要 Docker 部署、容器编排(Kubernetes/Docker Compose)和网络基础设施。

架构要求

  • Docker 容器部署和管理
  • 每个 PDF 请求的网络通信(容器 HTTP 往返)
  • 容器冷启动处理(第一次请求的初始化延迟)
  • 健康检查端点和服务监控
  • 为每个请求提供多格式/表单数据结构

了解IronPDF

IronPDF 是一个本地 .NET 库,作为一个 NuGet 包在进程中运行。 它提供基于 Chromium 的 HTML 渲染,无需外部服务、网络调用或容器基础架构。

IronPDF 使用 ChromePdfRenderer 作为其主要渲染类,带有类似 RenderHtmlAsPdf()RenderUrlAsPdf() 的方法。 配置使用 RenderingOptions 上的类型化 C# 属性,包括 MarginBottom(单位为毫米)。 文档可使用 SaveAs() 保存,或作为 BinaryData 访问。

该库只需要

  • NuGet 包安装 (dotnet add package IronPdf)
  • 许可证密钥配置
  • 标准 .NET 项目设置

架构和基础架构比较

这些解决方案的根本区别在于其部署和运行时架构。

因素高登堡IronPDF
部署Docker 容器 + 协调单个 NuGet 软件包
架构微服务(REST API)在建库
每次请求的延迟时间容器 HTTP 往返进程内(最小开销)
冷启动容器初始化延迟引擎初始化(仅首次渲染)
基础设施Docker、Kubernetes、负载平衡器无要求
网络依赖性要求None
失败模式网络、容器、服务故障.NET Standard例外情况
API 风格REST 多art/表单数据本地 C# 方法调用
扩展横向(更多容器)纵向(处理中)
调试分布式跟踪标准调试器
内存管理单独的容器分配共享应用程序内存
版本控制容器图像标签NuGet 软件包版本
健康检查所需的 HTTP 端点不需要(处理中)
CI/CD复杂性容器构建、注册表推送标准 .NET 构建

Gotenberg 基于 Docker 的方法需要容器部署、健康监控和网络基础设施管理。IronPDF通过在进程中运行,完全消除了这一基础架构层。

代码比较:常见的 PDF 操作

基本 HTML 到 PDF 的转换

最基本的操作清楚地展示了架构上的差异。

戈登堡:

using System;
using System.Net.Http;
using System.Threading.Tasks;
using System.IO;

class GotenbergExample
{
    static async Task Main()
    {
        var gotenbergUrl = "http://localhost:3000/forms/chromium/convert/html";

        using var client = new HttpClient();
        using var content = new MultipartFormDataContent();

        var html = "<html><body><h1>Hello from Gotenberg</h1></body></html>";
        content.Add(new StringContent(html), "files", "index.html");

        var response = await client.PostAsync(gotenbergUrl, content);
        var pdfBytes = await response.Content.ReadAsByteArrayAsync();

        await File.WriteAllBytesAsync("output.pdf", pdfBytes);
        Console.WriteLine("PDF generated successfully");
    }
}
using System;
using System.Net.Http;
using System.Threading.Tasks;
using System.IO;

class GotenbergExample
{
    static async Task Main()
    {
        var gotenbergUrl = "http://localhost:3000/forms/chromium/convert/html";

        using var client = new HttpClient();
        using var content = new MultipartFormDataContent();

        var html = "<html><body><h1>Hello from Gotenberg</h1></body></html>";
        content.Add(new StringContent(html), "files", "index.html");

        var response = await client.PostAsync(gotenbergUrl, content);
        var pdfBytes = await response.Content.ReadAsByteArrayAsync();

        await File.WriteAllBytesAsync("output.pdf", pdfBytes);
        Console.WriteLine("PDF generated successfully");
    }
}
Imports System
Imports System.Net.Http
Imports System.Threading.Tasks
Imports System.IO

Module GotenbergExample
    Async Function Main() As Task
        Dim gotenbergUrl = "http://localhost:3000/forms/chromium/convert/html"

        Using client As New HttpClient()
            Using content As New MultipartFormDataContent()
                Dim html = "<html><body><h1>Hello from Gotenberg</h1></body></html>"
                content.Add(New StringContent(html), "files", "index.html")

                Dim response = Await client.PostAsync(gotenbergUrl, content)
                Dim pdfBytes = Await response.Content.ReadAsByteArrayAsync()

                Await File.WriteAllBytesAsync("output.pdf", pdfBytes)
                Console.WriteLine("PDF generated successfully")
            End Using
        End Using
    End Function
End Module
$vbLabelText   $csharpLabel

IronPDF:

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

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

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

        pdf.SaveAs("output.pdf");
        Console.WriteLine("PDF generated successfully");
    }
}
// NuGet: Install-Package IronPdf
using System;
using IronPdf;

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

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

        pdf.SaveAs("output.pdf");
        Console.WriteLine("PDF generated successfully");
    }
}
Imports System
Imports IronPdf

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

        Dim html = "<html><body><h1>Hello from IronPDF</h1></body></html>"
        Dim pdf = renderer.RenderHtmlAsPdf(html)

        pdf.SaveAs("output.pdf")
        Console.WriteLine("PDF generated successfully")
    End Sub
End Class
$vbLabelText   $csharpLabel

该服务需要创建一个 HttpClient,构建 MultipartFormDataContent,以特定的文件名 (index.html) 附加 HTML 作为文件,进行异步 HTTP POST 到端点,读取响应字节,并写入磁盘。 每个请求都要通过网络,并伴有延迟和故障模式。

IronPDF 创建 ChromePdfRenderer,调用 RenderHtmlAsPdf(),传入 HTML 字符串,然后用 SaveAs() 保存。 操作是同步的、进程中的,并使用类型化方法而不是基于字符串的表单数据。

有关高级 HTML 渲染选项,请浏览 HTML 到 PDF 转换指南

URL到PDF转换

将实时网页转换为 PDF 显示了类似的架构模式。

戈登堡:

using System;
using System.Net.Http;
using System.Threading.Tasks;
using System.IO;

class GotenbergUrlToPdf
{
    static async Task Main()
    {
        var gotenbergUrl = "http://localhost:3000/forms/chromium/convert/url";

        using var client = new HttpClient();
        using var content = new MultipartFormDataContent();

        content.Add(new StringContent("https://example.com"), "url");

        var response = await client.PostAsync(gotenbergUrl, content);
        var pdfBytes = await response.Content.ReadAsByteArrayAsync();

        await File.WriteAllBytesAsync("webpage.pdf", pdfBytes);
        Console.WriteLine("PDF from URL generated successfully");
    }
}
using System;
using System.Net.Http;
using System.Threading.Tasks;
using System.IO;

class GotenbergUrlToPdf
{
    static async Task Main()
    {
        var gotenbergUrl = "http://localhost:3000/forms/chromium/convert/url";

        using var client = new HttpClient();
        using var content = new MultipartFormDataContent();

        content.Add(new StringContent("https://example.com"), "url");

        var response = await client.PostAsync(gotenbergUrl, content);
        var pdfBytes = await response.Content.ReadAsByteArrayAsync();

        await File.WriteAllBytesAsync("webpage.pdf", pdfBytes);
        Console.WriteLine("PDF from URL generated successfully");
    }
}
Imports System
Imports System.Net.Http
Imports System.Threading.Tasks
Imports System.IO

Module GotenbergUrlToPdf
    Async Function Main() As Task
        Dim gotenbergUrl As String = "http://localhost:3000/forms/chromium/convert/url"

        Using client As New HttpClient()
            Using content As New MultipartFormDataContent()
                content.Add(New StringContent("https://example.com"), "url")

                Dim response As HttpResponseMessage = Await client.PostAsync(gotenbergUrl, content)
                Dim pdfBytes As Byte() = Await response.Content.ReadAsByteArrayAsync()

                Await File.WriteAllBytesAsync("webpage.pdf", pdfBytes)
                Console.WriteLine("PDF from URL generated successfully")
            End Using
        End Using
    End Function
End Module
$vbLabelText   $csharpLabel

IronPDF:

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

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

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

        pdf.SaveAs("webpage.pdf");
        Console.WriteLine("PDF from URL generated successfully");
    }
}
// NuGet: Install-Package IronPdf
using System;
using IronPdf;

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

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

        pdf.SaveAs("webpage.pdf");
        Console.WriteLine("PDF from URL generated successfully");
    }
}
Imports System
Imports IronPdf

Class IronPdfUrlToPdf
    Shared Sub Main()
        Dim renderer As New ChromePdfRenderer()

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

        pdf.SaveAs("webpage.pdf")
        Console.WriteLine("PDF from URL generated successfully")
    End Sub
End Class
$vbLabelText   $csharpLabel

容器使用 /forms/chromium/convert/url 端点,并将 URL 作为表单数据传递。IronPDF直接调用 RenderUrlAsPdf(),传入 URL 字符串,一个方法调用代替了 HTTP 基础设施。

自定义页面大小和页边距

配置处理揭示了 API 的设计差异。

戈登堡:

using System;
using System.Net.Http;
using System.Threading.Tasks;
using System.IO;

class GotenbergCustomSize
{
    static async Task Main()
    {
        var gotenbergUrl = "http://localhost:3000/forms/chromium/convert/html";

        using var client = new HttpClient();
        using var content = new MultipartFormDataContent();

        var html = "<html><body><h1>Custom Size PDF</h1></body></html>";
        content.Add(new StringContent(html), "files", "index.html");
        content.Add(new StringContent("8.5"), "paperWidth");
        content.Add(new StringContent("11"), "paperHeight");
        content.Add(new StringContent("0.5"), "marginTop");
        content.Add(new StringContent("0.5"), "marginBottom");

        var response = await client.PostAsync(gotenbergUrl, content);
        var pdfBytes = await response.Content.ReadAsByteArrayAsync();

        await File.WriteAllBytesAsync("custom-size.pdf", pdfBytes);
        Console.WriteLine("Custom size PDF generated successfully");
    }
}
using System;
using System.Net.Http;
using System.Threading.Tasks;
using System.IO;

class GotenbergCustomSize
{
    static async Task Main()
    {
        var gotenbergUrl = "http://localhost:3000/forms/chromium/convert/html";

        using var client = new HttpClient();
        using var content = new MultipartFormDataContent();

        var html = "<html><body><h1>Custom Size PDF</h1></body></html>";
        content.Add(new StringContent(html), "files", "index.html");
        content.Add(new StringContent("8.5"), "paperWidth");
        content.Add(new StringContent("11"), "paperHeight");
        content.Add(new StringContent("0.5"), "marginTop");
        content.Add(new StringContent("0.5"), "marginBottom");

        var response = await client.PostAsync(gotenbergUrl, content);
        var pdfBytes = await response.Content.ReadAsByteArrayAsync();

        await File.WriteAllBytesAsync("custom-size.pdf", pdfBytes);
        Console.WriteLine("Custom size PDF generated successfully");
    }
}
Imports System
Imports System.Net.Http
Imports System.Threading.Tasks
Imports System.IO

Class GotenbergCustomSize
    Shared Async Function Main() As Task
        Dim gotenbergUrl = "http://localhost:3000/forms/chromium/convert/html"

        Using client As New HttpClient()
            Using content As New MultipartFormDataContent()
                Dim html = "<html><body><h1>Custom Size PDF</h1></body></html>"
                content.Add(New StringContent(html), "files", "index.html")
                content.Add(New StringContent("8.5"), "paperWidth")
                content.Add(New StringContent("11"), "paperHeight")
                content.Add(New StringContent("0.5"), "marginTop")
                content.Add(New StringContent("0.5"), "marginBottom")

                Dim response = Await client.PostAsync(gotenbergUrl, content)
                Dim pdfBytes = Await response.Content.ReadAsByteArrayAsync()

                Await File.WriteAllBytesAsync("custom-size.pdf", pdfBytes)
                Console.WriteLine("Custom size PDF generated successfully")
            End Using
        End Using
    End Function
End Class
$vbLabelText   $csharpLabel

IronPDF:

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

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

        renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter;
        renderer.RenderingOptions.MarginTop = 50;
        renderer.RenderingOptions.MarginBottom = 50;

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

        pdf.SaveAs("custom-size.pdf");
        Console.WriteLine("Custom size PDF generated successfully");
    }
}
// NuGet: Install-Package IronPdf
using System;
using IronPdf;
using IronPdf.Rendering;

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

        renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter;
        renderer.RenderingOptions.MarginTop = 50;
        renderer.RenderingOptions.MarginBottom = 50;

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

        pdf.SaveAs("custom-size.pdf");
        Console.WriteLine("Custom size PDF generated successfully");
    }
}
Imports System
Imports IronPdf
Imports IronPdf.Rendering

Module IronPdfCustomSize

    Sub Main()
        Dim renderer As New ChromePdfRenderer()

        renderer.RenderingOptions.PaperSize = PdfPaperSize.Letter
        renderer.RenderingOptions.MarginTop = 50
        renderer.RenderingOptions.MarginBottom = 50

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

        pdf.SaveAs("custom-size.pdf")
        Console.WriteLine("Custom size PDF generated successfully")
    End Sub

End Module
$vbLabelText   $csharpLabel

这种方法使用字符串为基础的参数 ("8.5", "11", "0.5"),它们被添加到 multipart 表单数据中。 纸张尺寸以英寸为单位。 每个参数是一个单独的 Add() 调用,没有类型检查或 IntelliSense 支持。

IronPDF 在 RenderingOptions 上使用类型化属性。 PaperSize 接受一个枚举 (PdfPaperSize.Letter),边距是以毫米为单位的数值。 类型化 API 提供编译时检查和 IDE 支持。

IronPDF 教程中了解有关渲染配置的更多信息。

API 映射参考

对于正在评估高登堡迁移或比较功能的开发人员,本映射说明了等价操作:

端点到方法映射

哥登堡路线IronPDF 同等产品
POST /forms/chromium/convert/htmlChromePdfRenderer.RenderHtmlAsPdf()
POST /forms/chromium/convert/urlChromePdfRenderer.RenderUrlAsPdf()
POST /forms/chromium/convert/markdown先将 Markdown 渲染为 HTML
POST /forms/pdfengines/mergePdfDocument.Merge()
POST /forms/pdfengines/metadata/readpdf.MetaData
POST /forms/pdfengines/metadata/writepdf.MetaData.Author = "..."
GET /health不适用

表单参数到渲染选项映射

高登贝格参数IronPDF 属性转换注意事项
paperWidth (英寸)RenderingOptions.SetCustomPaperSizeInInches()自定义使用方法
paperHeight (英寸)RenderingOptions.SetCustomPaperSizeInInches()自定义使用方法
marginTop (英寸)RenderingOptions.MarginTop毫米数乘以 25.4
marginBottom (英寸)RenderingOptions.MarginBottom毫米数乘以 25.4
marginLeft (英寸)RenderingOptions.MarginLeft毫米数乘以 25.4
marginRight (英寸)RenderingOptions.MarginRight毫米数乘以 25.4
printBackgroundRenderingOptions.PrintHtmlBackgrounds布尔
landscapeRenderingOptions.PaperOrientationLandscape 枚举
scaleRenderingOptions.Zoom百分比(100 = 1.0)
waitDelayRenderingOptions.RenderDelay转换为毫秒
emulatedMediaTypeRenderingOptions.CssMediaTypeScreenPrint

注意单位转换:Gotenberg 使用英寸作为边距单位(例如,"0.5" = 0.5 英寸 = 12.7mm),而IronPDF使用毫米。

基础架构比较

哥登堡 Docker Compose

Gotenberg 需要容器基础设施:

#高登堡requires container management
version: '3.8'
services:
  app:
    depends_on:
      - gotenberg
    environment:
      - GOTENBERG_URL=http://gotenberg:3000

  gotenberg:
    image: gotenberg/gotenberg:8
    ports:
      - "3000:3000"
    deploy:
      resources:
        limits:
          memory: 2G
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
#高登堡requires container management
version: '3.8'
services:
  app:
    depends_on:
      - gotenberg
    environment:
      - GOTENBERG_URL=http://gotenberg:3000

  gotenberg:
    image: gotenberg/gotenberg:8
    ports:
      - "3000:3000"
    deploy:
      resources:
        limits:
          memory: 2G
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
YAML

IronPDF配置

IronPDF 无需额外服务:

#IronPDF- No additional services needed
version: '3.8'
services:
  app:
    environment:
      - IRONPDF_LICENSE_KEY=${IRONPDF_LICENSE_KEY}
# No高登堡service. No health checks. No resource limits.
#IronPDF- No additional services needed
version: '3.8'
services:
  app:
    environment:
      - IRONPDF_LICENSE_KEY=${IRONPDF_LICENSE_KEY}
# No高登堡service. No health checks. No resource limits.
YAML

基础设施差异很大:Gotenberg 需要容器部署、健康监控、资源分配和服务依赖性。IronPDF与应用程序一起在进程中运行。

性能特点

因素高登堡IronPDF
加工每个请求的容器 HTTP 往返进程内(无网络开销)
启动每次部署/扩展事件时容器初始化每个应用程序生命周期中引擎初始化一次
内存单独的容器分配共享应用程序内存
后续渲染网络开销在每次请求时持续存在初始化后开销最小

Gotenberg 的架构为每个请求添加了网络往返开销,并且在每次部署或扩展事件时发生容器冷启动。IronPDF的首次渲染会产生引擎初始化,但后续渲染以进程内方式运行,并且开销最小。

团队何时考虑从高登堡迁移到 IronPDF?

开发团队评估从高登堡向IronPDF过渡的原因有以下几点:

基础设施开销: 该服务需要 Docker,容器编排(Kubernetes/Docker Compose),服务发现和负载均衡。 寻求更简单部署的团队发现IronPDF的 NuGet 方法消除了这些基础架构方面的顾虑。

网络延迟: 通过容器进行的每个 PDF 操作需要 HTTP 调用到一个单独的服务,为每个请求添加网络往返开销。对于高流量应用程序,这种开销会累积。IronPDF的进程内方法在初始化后的开销可以忽略不计。

冷启动问题: 容器启动时为首次请求添加初始化延迟。 即使是温暖的容器也有网络开销。 每次 pod 重启、扩展事件或部署都会触发冷启动。IronPDF的初始化发生在每个应用程序生命周期中一次。

运营复杂性: 需要单独管理容器的健康状况、缩放、日志和监控。 网络超时、服务不可用和容器崩溃成为应用程序关注的问题。IronPDF使用标准的 .NET 异常处理。

多部分表单数据 API: 每次向服务发出的请求都需要构建带有基于字符串参数的 multipart/form-data 负载 - 冗长且无编译时类型检查。IronPDF提供类型化的 C# 属性,并支持 IntelliSense。

版本管理: 其容器镜像与应用程序分开更新。 API 的更改可能会破坏集成。IronPDF版本通过 NuGet 与标准 .NET 依赖关系管理进行管理。

优势和考虑因素

高登堡的优势

-多语言架构:可与任何能够发起 HTTP 请求的语言配合使用 -语言无关:不局限于 .NET 生态系统

  • MIT许可证:自由开源软件 微服务模式:适用于容器化架构

戈登堡注意事项

-基础设施开销:需要 Docker、Kubernetes 和负载均衡器。

  • 网络延迟: 每个请求的容器 HTTP 往返
  • 冷启动: 容器初始化延迟 -基于字符串的 API:没有类型安全或智能感知功能 -分布式调试:需要分布式跟踪 -健康监测:需要管理的其他端点

IronPDF的优势

-零基础架构:仅 NuGet 包 -进程内性能:初始化后无网络延迟 -类型安全的 API:支持强类型属性和智能感知 -标准调试:普通的 .NET 调试器正常工作 -丰富的资源:大量的教程文档 专业支持:商业许可包含支持服务

IronPDF注意事项

  • .NET 专用:专为 .NET 生态系统设计 -商业许可:生产用途必需

Gotenberg 和IronPDF代表了在 .NET 应用程序中生成 PDF 的根本不同方法。高登堡基于 Docker 的微服务架构引入了容器管理、网络延迟和操作复杂性。 每个 PDF 操作都需要 HTTP 通信以及相关的故障模式和冷启动惩罚。

IronPDF 提供与进程内库一样的基于 Chromium 的渲染。 NuGet 软件包取消了 Docker 容器、网络调用和基础设施管理。 类型化的 C# API 取代了基于字符串的多部分表单数据。 标准的 .NET 异常处理取代了 HTTP 状态代码和网络故障模式。

随着企业对 .NET 10、C# 14 以及 2026 年之前的应用程序开发进行规划,在微服务基础架构开销和进程内库简易性之间做出选择会极大地影响部署和操作的复杂性。 寻求在保持 HTML/CSS/JavaScript 渲染保真度的同时减轻基础架构负担的团队会发现IronPDF能有效满足这些要求。

通过免费试用开始评估 IronPDF,并浏览全面的文档以评估是否适合您的特定需求。

[{i:(Gotenberg 是其各自所有者的注册商标。 本网站与高登堡无关联、未获其认可或赞助。所有产品名称、徽标和品牌均为其各自所有者的财产。 比较仅供参考,反映撰写时公开可用的信息。)}]