IRONSOFTWAREHOME
影片

如何使用 C# 用密碼和權限保護 PDF 文件

Curtis Chau
Curtis Chau
Updated: 2026年7月19日

從Gotenberg遷移到IronPDF將您的.NET PDF工作流程從基於Docker的微服務架構和HTTP API呼叫轉變為內加工本C#程式庫。 本指南提供了一個全面的逐步遷移路徑,消除了專業.NET開發者的基礎設施開銷、網路延遲和容器管理的複雜性。

為什麼從Gotenberg遷移到IronPDF

Gotenberg架構問題

Gotenberg是一個用於PDF生成的基於Docker的微服務架構。 雖然功能強大且靈活,但對C#應用程式引入了顯著的複雜性:

  1. **基礎設施開銷:**需要Docker、容器編排(Kubernetes/Docker Compose)、服務發現和負載均衡。 每次部署都變得更加複雜。

  2. **網路延遲:**每次PDF操作都需要HTTP呼叫到一個獨立的服務——每個請求額外增加10-100毫秒的延遲。在高並發場景中,這種延遲很快就會積累。

  3. **冷啟動問題:**容器啟動可能會在首次請求中增加2-5秒。 每次pods重啟、每次擴展事件和每次部署都會觸發冷啟動。

  4. **操作複雜性:**您必須管理容器健康狀況、擴展、日誌記錄和監控,這些與您的主要應用程式是分開的問題。

  5. **多部分表單資料:**每個請求需要構造多部分表單資料,有冗長,容易出錯,且維護繁瑣。

  6. **故障點:**網路超時、服務不可用和容器崩潰都成為需要您處理的責任。

  7. **版本管理:**Gotenberg映像獨立於您的應用程式進行更新; API變更可能會意外破壞整合。

Gotenberg與IronPDF比較

方面GotenbergIronPDF
部署Docker容器 + 編排單個NuGet套件
架構微服務(REST API)內加工本程式庫
每次請求延遲10-100毫秒以上(網路往返)< 1毫秒開銷
冷啟動2-5秒(容器初始化)1-2秒(僅首次渲染)
基礎設施Docker,Kubernetes,負載均衡器不需要任何基礎設施
故障模式網路、容器、服務故障標準的.NET異常
API風格REST多部分/表單資料內建C#方法呼叫
擴展水平(更多容器)垂直(內處理)
除錯需要分佈式跟踪標準除錯器
版本控制容器映像標籤NuGet套件版本

對於以當前.NET版本為目標的團隊而言,IronPDF提供了一個沒有基礎設施依賴的基礎,並能夠自然而然地與現代.NET模式整合。


遷移複雜性評估

功能的預估努力程度

功能遷移複雜性
HTML轉PDF非常低
URL到PDF非常低
自定紙張尺寸
邊距
PDF合併
頁眉/頁腳
等待延遲
PDF/A轉換

範式轉變

這次Gotenberg遷移的基礎轉變是從使用多部分表單資料的HTTP API呼叫內建C#方法呼叫:

Gotenberg:HTTP POST多部分表單數據到Docker容器
IronPDF:直接使用C#對象的方法呼叫
Text

開始之前

前提條件

  1. .NET版本: IronPDF支援.NET Framework 4.6.2+和.NET Core 3.1+ / .NET 5/6/7/8/9+
  2. **授權金鑰:**從ironpdf.com取得您的IronPDF授權金鑰
  3. **計劃移除基礎設施:**記錄Gotenberg容器以便在遷移後報廢

識別所有Gotenberg使用情況

# Find direct HTTP calls to Gotenberg
grep -r "gotenberg\|/forms/chromium\|/forms/libreoffice\|/forms/pdfengines" --include="*.cs" .

# Find GotenbergSharpApiClient usage
grep -r "GotenbergSharpClient\|Gotenberg.Sharp\|ChromiumRequest" --include="*.cs" .

# Find Docker/KubernetesGotenbergconfiguration
grep -r "gotenberg/gotenberg\|gotenberg:" --include="*.yml" --include="*.yaml" .
SHELL

NuGet包變更

# RemoveGotenbergclient (if using)
dotnet remove package Gotenberg.Sharp.API.Client

# Install IronPDF
dotnet add package IronPdf
SHELL

快速開始遷移

步驟1:更新授權配置

之前(Gotenberg):

Gotenberg不需要授權,但需要Docker基礎設施和容器URL。

private readonly string _gotenbergUrl = "http://localhost:3000";

之後(IronPDF):

// Set once at application startup
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";

步驟2:更新名稱空間的引入

// Before (Gotenberg)
using System.Net.Http;
using System.Threading.Tasks;
using System.IO;

// After (IronPDF)
using IronPdf;
using IronPdf.Rendering;

完整API參考

Gotenberg端點到IronPDF映射

Gotenberg路徑IronPDF等價
POST /forms/chromium/convert/htmlChromePdfRenderer.RenderHtmlAsPdf()
POST /forms/chromium/convert/urlChromePdfRenderer.RenderUrlAsPdf()
POST /forms/pdfengines/mergePdfDocument.Merge()
POST /forms/pdfengines/convertpdf.SaveAs()帶設置
GET /health

表單參數到RenderingOptions映射

Gotenberg參數IronPDF 屬性轉換說明
paperWidth(英寸)RenderingOptions.PaperSize使用枚舉或自定尺寸
paperHeight(英寸)RenderingOptions.PaperSize使用枚舉或自定尺寸
marginTop(英寸)RenderingOptions.MarginTop乘以25.4換算為毫米
marginBottom(英寸)RenderingOptions.MarginBottom乘以25.4換算為毫米
printBackgroundRenderingOptions.PrintHtmlBackgrounds布林值
landscapeRenderingOptions.PaperOrientationLandscape枚舉
"3s"RenderingOptions.WaitFor.RenderDelay(ms)將字串轉換為毫秒

程式碼遷移範例

範例1:基本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");
    }
}

之後(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");
    }
}

差異是很顯著的:Gotenberg需要構建一個MultipartFormDataContent,進行一個異步HTTP POST至運行的Docker容器,並處理字節陣列的響應。 IronPDF將此減少為僅需三行程式碼使用ChromePdfRenderer方法呼叫——無網路開銷,無容器依賴,無異步複雜性。 查看HTML到PDF文件以獲取其他渲染選項。

範例2:URL轉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");
    }
}

之後(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");
    }
}

Gotenberg方法需要使用不同的端點(/forms/chromium/convert/url),使用URL作為表單字段構建多部分內容,並處理異步HTTP響應。 IronPDF的PdfDocument物件。 瞭解更多關於URL到PDF轉換

範例3:自定義紙張尺寸和邊距

之前(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");
    }
}

之後(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");
    }
}

Gotenberg需要基於字串的參數("0.5")新增到多部分表單資料中——無型別安全,無IntelliSense,容易輸入錯誤。 IronPDF提供具有PdfPaperSize枚舉和數字邊距值的強型別屬性。 請注意IronPDF的邊距單位為毫米(50毫米≈2英寸),而Gotenberg使用英寸。


關鍵遷移注意事項

單位轉換

這次Gotenberg遷移中最重要的轉換是邊距單位:

// Gotenberg: margins in inches
content.Add(new StringContent("0.5"), "marginTop");    // 0.5 inches
content.Add(new StringContent("1"), "marginBottom");   // 1 inch

// IronPDF: margins in millimeters
renderer.RenderingOptions.MarginTop = 12.7;    // 0.5 inches × 25.4 = 12.7mm
renderer.RenderingOptions.MarginBottom = 25.4; // 1 inch × 25.4 = 25.4mm

轉換公式:millimeters = inches × 25.4

同步與異步

由於HTTP通信,Gotenberg需要異步操作:

// Gotenberg: Forced async due to network calls
var response = await client.PostAsync(gotenbergUrl, content);
var pdfBytes = await response.Content.ReadAsByteArrayAsync();

// IronPDF: Synchronous in-process execution
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("output.pdf");

// IronPDF: Async wrapper if needed
var pdf = await Task.Run(() => renderer.RenderHtmlAsPdf(html));

錯誤處理

// Gotenberg: HTTP error handling
try
{
    var response = await client.PostAsync(gotenbergUrl, content);
    response.EnsureSuccessStatusCode();  // What if 500? 503? Timeout?
}
catch (HttpRequestException ex) { /* Network error */ }
catch (TaskCanceledException ex) { /* Timeout */ }

// IronPDF: Standard .NET exceptions
try
{
    var pdf = renderer.RenderHtmlAsPdf(html);
}
catch (Exception ex)
{
    Console.WriteLine($"PDF generation failed: {ex.Message}");
}

移除基礎設施

遷移後,從您的基礎設施中移除Gotenberg:

# REMOVE from docker-compose.yml:
# services:
#   gotenberg:
#     image: gotenberg/gotenberg:8
#     ports:
#       - "3000:3000"
#     deploy:
#       resources:
#         limits:
#           memory: 2G
Text

效能考量

延遲比較

操作Gotenberg(熱)Gotenberg(冷啟動)IronPDF(首次渲染)IronPDF(後續渲染)
簡單的HTML150-300毫秒2-5秒1-2秒50-150毫秒
複雜的HTML500-1500毫秒3-7秒1.5-3秒200-800毫秒
URL渲染1-5秒3-10秒1-5秒500毫秒-3秒

消除基礎設施成本

資源GotenbergIronPDF
需要的容器1到N(擴展)0
每個容器的記憶體512MB到2GB
每個請求的網路開銷10-100毫秒0毫秒
健康檢查端點必需的不需要
負載均衡器通常需要不需要

故障排除

問題1:不需要HttpClient模式

**問題:**程式碼仍在使用MultipartFormDataContent

**解決方案:**完全替換為ChromePdfRenderer

// Remove all of this:
// using var client = new HttpClient();
// using var content = new MultipartFormDataContent();
// content.Add(new StringContent(html), "files", "index.html");
// var response = await client.PostAsync(url, content);

// Replace with:
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(html);

問題2:邊距單位錯誤

**問題:**遷移後PDF的邊距不正確。

**解決方案:**將英寸轉換為毫米:

//Gotenbergused inches: "0.5"
//IronPDFuses millimeters: 0.5 × 25.4 = 12.7
renderer.RenderingOptions.MarginTop = 12.7;

問題3:容器URL引用

**問題:**程式碼包含http://gotenberg:3000或類似的URL。

**解決方案:**移除所有容器URL引用——IronPDF在內部運行:

// Remove:
// private readonly string _gotenbergUrl = "http://gotenberg:3000";

//IronPDFneeds no URL - it's in-process
var renderer = new ChromePdfRenderer();

遷移檢查表

遷移前

  • 列出程式碼庫中所有Gotenberg HTTP呼叫
  • 記錄當前的Gotenberg配置(超時設置,邊距,紙張尺寸)
  • 識別所有Docker/Kubernetes的Gotenberg配置
  • 獲得IronPDF授權金鑰
  • 計劃基礎設施撤役

程式碼遷移

  • 安裝IronPDF的NuGet套件:dotnet add package IronPdf
  • 移除Gotenberg客戶端套件
  • 將所有HTTP呼叫替換為IronPDF的方法呼叫
  • 將邊距單位從英寸轉換為毫米
  • 更新錯誤處理(HTTP錯誤→.NET異常)
  • 在啟動時新增授權金鑰初始化

基礎設施遷移

  • 從Docker Compose / Kubernetes中移除Gotenberg
  • 更新CI/CD管道(移除Gotenberg映像拉取)
  • 移除Gotenberg的健康檢查
  • 從配置中移除Gotenberg URL

測試

  • 測試 HTML 到 PDF 的轉換
  • 測試 URL 到 PDF 的轉換
  • 驗證邊距和尺寸的準確性
  • 在負載下進行性能測試
  • 測試首次渲染的加熱時間

遷移後

  • 移除Gotenberg容器部署
  • 將Gotenberg配置文件存檔
  • 更新文件
  • 監控應用程式的記憶體使用
  • 確認沒有孤立的網路連接

請注意: Gotenberg是其各自所有者的註冊商標。 本網站與Gotenberg無關,並未經其協同公司支援或贊助。所有產品名稱、標誌和品牌屬於各自的擁有人。 比較僅供參考,反映撰寫時公開可用的資訊。
Curtis Chau
技術作家

Curtis Chau擁有Carleton大學的電腦科學學士學位,專精於前端開發,擁有Node.js、TypeScript、JavaScript和React的專業知識。Curtis熱衷於建立直觀且美觀的使用者介面,喜愛使用現代框架並建立結構良好、視覺吸引力的手冊。

...
閱讀更多

相關文章

Key in blue circle

立即免費取得 30 天試用金鑰

Your trial license will be sent to your email address

無任何限制。100% 解鎖。無需信用卡。

bullet_checked無需信用卡或建立帳號無任何限制。100% 解鎖。無需信用卡。
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Join Millions of Engineers who’ve tried IronPDF
預訂您的免費現場演示
Booking Badge

受到全球數百萬工程師的信任

Iron Software的客戶標誌
獲取您的無義務諮詢
填寫以下表格或電子郵件sales@ironsoftware.com
您的詳細資訊將始終保密
受到全球數百萬工程師的信任
Iron Software的客戶標誌
立即獲取您的30天試用金鑰
無需信用卡或帳戶建立