比較

BitMiracle Docotic PDF與IronPDF:技術比較指南

當.NET開發者評估PDF生成解決方案時,Gotenberg作為一個基於Docker的微服務,通過REST API調用將HTML轉換為PDF脫穎而出。 雖然能適應不同的架構,Gotenberg引入了顯著的基礎設施開銷——Docker容器、網路延遲和操作複雜性。 IronPDF提供了一個替代方案:一個內部處理的NuGet包,提供相同的基於Chromium的渲染,而不需要容器、網路調用或基礎設施管理。

此比較從技術相關的維度來看兩種解決方案,以幫助專業開發者和建築師為其.NET PDF需求做出明智的決策。

了解Gotenberg

Gotenberg是一個基於Docker的PDF生成微服務架構。 它作為一個獨立容器運行,公開REST API端點用於將HTML、URL和其他格式轉換為PDF。 每個PDF操作都需要發送HTTP調用到Gotenberg服務。

Gotenberg使用POST /forms/chromium/convert/url作為URL到PDF的端點。 配置通過multipart/form-data傳遞,使用以字串為基礎的參數,如marginBottom(以英寸計)。 該服務需要Docker部署、容器編排(Kubernetes/Docker Compose)和網路基礎設施。

該架構需要:

  • Docker容器部署和管理
  • 每個PDF請求的網路通信(容器HTTP往返)
  • 容器冷啟動處理(首次請求的初始化延遲)
  • 健康檢查端點和服務監控
  • 每次請求的multipart/form-data構建

了解IronPDF

IronPDF是一個原生的.NET程式庫,作為NuGet包在內部處理運行。 它提供基於Chromium的HTML渲染,無需外部服務、網路調用或容器基礎設施。

IronPDF使用RenderUrlAsPdf()。 配置上使用的C#型別屬性為MarginBottom(以毫米計)。 文件使用BinaryData存取。

該程式庫僅需要:

  • NuGet包安裝(dotnet add package IronPdf
  • 授權金鑰配置
  • 標準.NET專案設置

架構與基礎設施比較

這些解決方案之間的基本區別在於其部署和運行時架構。

因素GotenbergIronPDF
部署Docker容器+編排單一NuGet套件
架構微服務(REST API)內部程式庫
每次請求的延遲容器HTTP往返內部處理(最小開銷)
冷啟動容器初始化延遲引擎初始化(僅首次渲染)
基礎設施Docker,Kubernetes,負載平衡器不需要
網路依賴需要None
故障模式網路,容器,服務故障標準.NET例外
API風格REST multipart/form-data原生C#方法調用
擴展性水平擴展(更多容器)垂直擴展(內部處理)
除錯分佈式跟踪標準除錯器
記憶體管理獨立容器分配共享應用程式記憶體
版本控制容器映像標籤NuGet包版本
健康檢查需要HTTP端點不需要(內部處理)
CI/CD複雜性容器構建、註冊表推送標準.NET構建

Gotenberg的基於Docker方法需要容器部署、健康監控和網路基礎設施管理。 IronPDF通過運行在內部處理中完全消除了這個基礎設施層。

程式碼比較:常見的 PDF 操作

基本的HTML到PDF轉換

最基本的操作明顯展示了架構的差異。

Gotenberg:

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

該服務需要建立index.html)作為文件附件新增HTML,對端點進行異步HTTP POST,讀取響應字節並寫入磁盤。 每次請求都經過網路,帶有相關的延遲和故障模式。

IronPDF建立SaveAs()保存。 該操作是同步的、內部處理的,使用型別化方法而不是基於字串的表單資料。

想了解進階HTML渲染選項,請參閱HTML到PDF轉換指南

URL 到 PDF 轉換

將在線網頁轉換為PDF顯示了類似的架構模式。

Gotenberg:

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設計的差異。

Gotenberg:

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

此方法使用基於字串的參數("0.5")新增到multipart form資料中。 紙張尺寸以英寸計算。 每個參數都是一個獨立的Add()調用,沒有型別檢查或IntelliSense支持。

IronPDF使用RenderingOptions上的型別屬性。 PdfPaperSize.Letter),且邊距以毫米為單位。 型別化API提供編譯時檢查和IDE支持。

IronPDF教程中了解有關渲染配置的更多資訊。

API映射參考

對於評估Gotenberg遷移或比較功能的開發者,這個映射顯示了等效操作:

端點到方法的映射

Gotenberg路由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不適用

表單參數到RenderingOptions的映射

Gotenberg參數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.CssMediaTypePrint

注意單位轉換:Gotenberg使用英寸為邊距(例如,"0.5"=0.5英寸=12.7毫米),而IronPDF使用毫米。

基礎設施比較

Gotenberg Docker Compose

Gotenberg需要容器基礎設施:

# 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
# 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
YAML

IronPDF配置

IronPDF不需要額外的服務:

# IronPDF - No additional services needed
version: '3.8'
services:
  app:
    environment:
      - IRONPDF_LICENSE_KEY=${IRONPDF_LICENSE_KEY}
# No Gotenberg 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 Gotenberg service. No health checks. No resource limits.
YAML

基礎設施差異是巨大的:Gotenberg需要容器部署、健康監控、資源分配和服務依賴。 IronPDF隨應用程式內部運行。

性能特徵

因素GotenbergIronPDF
處理每次請求的容器HTTP往返內部處理(無網路開銷)
啟動每次部署/擴展事件的容器初始化每個應用程式生命周期僅需一次引擎初始化
記憶體獨立容器分配共享應用程式記憶體
後續渲染每次請求持續的網路開銷初始化後的最小開銷

Gotenberg的架構為每個請求增加了網路往返開銷,且容器冷啟動在每次部署或擴展事件中發生。 IronPDF的首次渲染會引起引擎初始化,但後續渲染在內部處理中運行,開銷最小。

當團隊考慮從Gotenberg轉向IronPDF時

開發團隊評估從Gotenberg轉向IronPDF有幾個原因:

基礎設施開銷:該服務需要Docker、容器編排(Kubernetes/Docker Compose)、服務發現和負載平衡。 尋求簡化部署的團隊會發現IronPDF的僅需NuGet方法消除了這些基礎設施問題。

網路延遲: 每一次通過容器的PDF操作都需要對單獨的服務進行HTTP調用,這對於每個請求都增加了網路往返開銷。對於高並發的應用程式,這些開銷會累積。 IronPDF的內部處理方法在初始化後幾乎沒有開銷。

冷啟動問題: 容器啟動給首次請求增加了初始化延遲。 即便是暖容器也有網路開銷。 每次傳遞啟動、擴展事件或部署都會觸發冷啟動。 IronPDF的初始化在每應用程式生命週期中僅發生一次。

操作複雜性: 需要將容器健康、擴展、日誌和監控作為獨立問題進行管理。 網路超時、服務無法存取和容器崩潰成為應用程式問題。 IronPDF使用標準.NET異常處理。

Multipart Form資料API: 每次服務請求都需要構建帶有基於字串參數的multipart/form-data資料負載——冗長且沒有編譯時型別檢查。 IronPDF提供了帶有IntelliSense支持的型別化C#屬性。

版本管理: 它的容器鏡像獨立於您的應用程式更新。 API變更可能會破壞整合。 通過NuGet管理IronPDF版本,使用標準的.NET依賴管理。

優勢和考量

Gotenberg優勢

  • 多語言架構: 可與任何能夠發起HTTP調用的語言一起使用
  • 語言無關: 不依賴於.NET生態系統
  • MIT授權: 免費且開源
  • 微服務模式: 適合容器化架構

Gotenberg考量

  • 基礎設施開銷: 需要Docker、Kubernetes、負載平衡器
  • 網路延遲: 每次請求的容器HTTP往返
  • 冷啟動: 容器初始化延遲
  • 基於字串的API: 沒有型別安全或IntelliSense
  • 分佈式除錯: 需要分佈式跟踪
  • 健康監控: 需要額外的端點來管理

IronPDF的優勢

  • 零基礎設施: 僅需要NuGet包
  • 內部處理性能: 初始化後無網路延遲
  • 型別安全的API: 強型別屬性並具有IntelliSense
  • 標準除錯: 普通.NET除錯器可用
  • 全面的資源: 豐富的教程文件
  • 專業支持: 商業授權包括支持

IronPDF考量

  • .NET特定: 為.NET生態系統設計
  • 商業許可:生產使用需要商業許可

Gotenberg和IronPDF代表了在.NET應用中生成PDF的根本不同的兩種方法。 Gotenberg的基於Docker的微服務架構引入了容器管理、網路延遲和運行複雜性。 每次PDF操作都需要HTTP通信,帶有相關的失敗模式和冷啟動懲罰。

IronPDF提供了與內部處理程式庫相同的基於Chromium的渲染。 NuGet包消除了Docker容器、網路調用和基礎設施管理。 型別化的C# API取代了基於字串的multipart form資料。 標準.NET異常處理取代了HTTP狀態碼和網路故障模式。

隨著組織計劃.NET 10、C# 14及應用程式開發到2026年,在微服務基礎設施開銷和內部程式庫簡單性之間的選擇對部署和運行複雜性影響甚大。 尋求在保持HTML/CSS/JavaScript渲染保真度的同時減少基礎設施負擔的團隊會發現IronPDF有效地解決了這些需求。

免費試用 開始評估 IronPDF,並探索全面的文件以評估特定需求的適用性。

請注意Gotenberg是其註冊所有者的註冊商標。 本站與Gotenberg無關、未經其認可或贊助。所有產品名稱、標誌和品牌均屬各自所有者。 比較僅供資訊參考,並反映了撰寫時公開的資訊。)}