該頁面可以包含自動翻譯的文字。

使用 C# 和 VB.NET 將 HTML 轉換為 PDF

如果您已經投入大量時間和金錢創建了 HTML 格式的內容,您可能想要將其轉換為 PDF 文件。對於任何想要避免重複工作的人來說,這是一個自然的選擇。

本文將詳細介紹如何使用 Docotic.Pdf 及其免費的 HtmlToPdf 外掛程式在 .NET 中將 HTML 轉換為 PDF。

有關 Docotic.Pdf 為何是最佳選擇、如何安裝該插件以及轉換過程的內部工作原理,請參閱HTML 轉 PDF API 概述頁面。

HTML 轉 PDF

簡單的 HTML 轉 PDF C# 轉換

首先,安裝插件。

Install-Package BitMiracle.Docotic.Pdf.HtmlToPdf

使用HTML 轉 PDF API,C# 轉換程式碼可以如下所示:

static async Task ConvertUrlToPdfAsync(string urlString, string pdfFileName)
{
    using var converter = await HtmlConverter.CreateAsync();
    using var pdf = await converter.CreatePdfAsync(new Uri(urlString));
    pdf.Save(pdfFileName);
}

操作非常簡單。只需兩次呼叫即可產生 PDF 文件。

程式碼會建立一個轉換器實例,並使用它來從 HTML 產生 PDF。您可以編輯 PDF文檔,或使用數位簽章對其進行簽署。為簡單起見,範例程式碼會直接儲存文件。

如您所見,該 API 是異步的,完全不提供同步方法。

在同步程式碼中使用非同步 API

有些情況下,您需要從同步程式碼中呼叫 API。例如,當您的控制台應用程式使用舊版本的 C# 且沒有非同步 Main 方法時。不用擔心,您仍然可以在應用程式中使用該插件。

以下程式碼顯示如何在常規同步方法中將 URL 轉換為 PDF:

Task.Run(async () =>
{
    using var converter = await HtmlConverter.CreateAsync();
    var uri = new Uri("https://bitmiracle.com/pdf-library/html-pdf/");
    using var pdf = await converter.CreatePdfAsync(uri);
    pdf.Save("output.pdf");
}).GetAwaiter().GetResult();

VB.NET 應用程式使用類似的程式碼。以下程式碼片段展示如何在同步 VB.NET 程式碼中將 HTML 轉換為 PDF。

Task.Run(
    Async Function()
        Using converter = Await HtmlConverter.CreateAsync()
            Dim uri = New Uri("https://bitmiracle.com/pdf-library/html-pdf/")
            Using pdf = Await converter.CreatePdfAsync(uri)
                pdf.Save("output.pdf")
            End Using
        End Using
    End Function
).GetAwaiter().GetResult()

請注意,通常不建議同步呼叫非同步方法,因此只有在別無選擇時才使用包裝器。

範例程式碼

我們提供控制台應用程式、Windows Forms 應用程式和 WPF 應用程式的範例程式碼。您可以從我們的 GitHub 程式碼庫下載完整的測試專案:

此外,還有一組HTML 轉 PDF範例。每個範例都提供 C# 和 VB.NET 版本。

使用 C# 和 VB.NET 透過 HTML 字串或檔案建立 PDF

使用此 API 可以輕鬆地將 HTML 字串轉換為 PDF。這個字串可以包含完整的 HTML 文檔,也可以只是其中的一個片段。轉換器會根據 HTML 程式碼為您建立 PDF。

using var converter = await HtmlConverter.CreateAsync();

var html = "<body><br><br><br><h1>Hello, World</h1></body>";
using var pdf = await converter.CreatePdfFromStringAsync(html);
pdf.Save("output.pdf");

HTML 程式碼可以包含圖片、腳本和 CSS 檔案的相對引用。要正確轉換此類程式碼,您需要為 HTML 中的所有相對連結指定一個基本 URL。以下是如何使用轉換選項指定基本 URL:

using var converter = await HtmlConverter.CreateAsync();

var incompleteHtml = "<img src=\"/images/team.svg\"></img>";

var options = new HtmlConversionOptions();
options.Load.BaseUri = new Uri("https://bitmiracle.com/");

using var pdf = await converter.CreatePdfFromStringAsync(incompleteHtml, options);
pdf.Save("output.pdf");

我們的 GitHub 儲存庫包含完整的測試專案

轉換 HTML 檔案與轉換 URL 幾乎相同。只需使用接受路徑而非 URL 的 CreatePdfAsync 重載即可。在 C# 或 VB.NET 程式碼中將 HTML 檔案轉換為 PDF 時,也支援基本 URL 和其他選項。

var sampleHtmlPath = @"C:\path\to\sample.html";
using var pdf = await converter.CreatePdfAsync(sampleHtmlPath);
pdf.Save("output.pdf");

您也可以使用 API 將 SVG 影像轉換為 PDF

使用自訂頁面尺寸、邊距和縮放比例

處理佈局較寬的網頁時,您可以增加輸出 PDF 的尺寸,或縮小內容以適應 PDF 頁面。為了更好地定位縮放後的內容,您還可以設定頁邊距。

縮放良好的 PDF 可以提供更佳的閱讀體驗,因為讀者無需放大或縮小即可正確查看內容。如果 HTML 文件因字體過小而難以閱讀,您可以放大內容。

預設情況下,API 產生的 PDF 頁面大小為 A4。沒有頁邊距,也沒有縮放。您可以使用轉換選項來變更這些設定。

請參閱如何設定從 HTML 產生 PDF 時的縮放因子和頁邊距。

using var converter = await HtmlConverter.CreateAsync();

var html = "<html><head><style>body { background-color: coral; margin-top: 100px;}</style></head>" +
"<body><h1>Did you notice the margins and the scale?</h1></body></html>";

var options = new HtmlConversionOptions();
options.Page.MarginLeft = 10;
options.Page.MarginTop = 20;
options.Page.MarginRight = 30;
options.Page.MarginBottom = 40;
options.Page.Scale = 1.5;

using var pdf = await converter.CreatePdfFromStringAsync(html, options);
pdf.Save("output.pdf");

Docotic.Pdf 範例儲存庫包含完整的專案

HTML 轉 PDF API 可以在產生的頁面上新增可重複的頁首/頁尾區塊。轉換器會根據頁面選項中指定的 HTML 範本建立這些區塊。我們建議在模板中使用內聯樣式和圖像資料 URI。

轉換器會將頁首和頁尾放置在頁面邊距內。由於預設頁面邊距較小,頁首和頁尾的內容可能無法顯示。我們建議明確指定上邊距和下邊距。其大小應分別與頁首和頁尾的大小相符。

了解如何將 HTML 轉換為 PDF 並新增頁首和頁尾。

using var converter = await HtmlConverter.CreateAsync();

var options = new HtmlConversionOptions();
options.Page.HeaderTemplate = File.ReadAllText("header-template.html");
options.Page.MarginTop = 50;

options.Page.FooterTemplate = File.ReadAllText("footer-template.html");
options.Page.MarginBottom = 50;

var url = new Uri("https://www.iana.org/numbers");
using var pdf = await converter.CreatePdfAsync(url, options);
pdf.Save("output.pdf");

這些模板使用標準的 HTML 程式碼,並支援一些變數。這些變數包括 datetitleurlpageNumbertotalPages頁首模板頁尾模板 都支援相同的變數集。

完整的測試項目和模板程式碼位於 Docotic.Pdf 範例庫中。範例程式碼展示如何在模板中使用變數和資料 URI。

受密碼保護的 HTML 轉 PDF C# 轉換

某些網頁需要身份驗證才能存取。當您造訪需要 HTTP 驗證的安全 URL 時,瀏覽器會要求您提供使用者名稱和密碼。

使用轉換選項,您可以指示 API 為需要登入的網頁提供憑證。

以下 C# 程式碼示範如何將受密碼保護的 HTML 轉換為 PDF。

using var converter = await HtmlConverter.CreateAsync();
var url = new Uri("http://httpbin.org/basic-auth/foo/bar");

var options = new HtmlConversionOptions();
options.Authentication.SetCredentials("foo", "bar");

using var pdf = await converter.CreatePdfAsync(url, options);
pdf.Save("output.pdf");

在範例庫中尋找完整的工作範例

如果頁面需要設定一些 cookie 才能正常運行,也很容易。只需將這些 cookie 新增到選項中即可。方法如下:

var options = new HtmlConversionOptions();
options.Cookies.Add(new Cookie("sessionID", "my-session-ID"));

using var pdf = await converter.CreatePdfAsync(url, options);
pdf.Save("output.pdf");

延遲轉換開始

預設情況下,頁面載入後會立即開始轉換。如果頁面載入後持續更新一段時間,延遲 HTML 到 PDF 的轉換會很有幫助。這種情況在處理由 JavaScript 或 AJAX 呼叫產生的動態內容時很常見。

Acid 3 測試就是一個典型的例子,它能從轉換前的延遲中獲益。此測試會執行一系列檢查,以評估瀏覽器正確渲染複雜網頁的能力。這些檢查需要時間。嘗試更改以下程式碼中的等待時間,看看它如何影響轉換結果。

var options = new HtmlConversionOptions();
options.Start.SetStartAfterDelay(10 * 1000);

using var converter = await HtmlConverter.CreateAsync();
var url = new Uri("http://acid3.acidtests.org/");
using var pdf = await converter.CreatePdfAsync(url, options);
pdf.Save("output.pdf");

以上程式碼展示如何延遲將 HTML 轉換為 PDF。雖然額外的時間有助於獲得更好的轉換結果,但請注意,添加延遲可能會影響效能。延遲時間不足則會影響轉換品質。除了使用延遲之外,另一種方法是使用腳本,該腳本會在頁面準備好後一直執行。

您可以在 Docotic.Pdf 範例庫中取得完整的測試項目

轉換前執行 JavaScript

該插件 API 提供了一種在轉換之前運行 JavaScript 程式碼的方法。程式碼可以動態產生或修改 HTML 內容。例如,它可以切換元素,或實現動態內容載入。

以下程式碼展示如何延遲 HTML 到 PDF 的轉換,直到 JavaScript 程式碼執行完畢。

using var converter = await HtmlConverter.CreateAsync();

var options = new HtmlConversionOptions();
var js = @"document.body.style.backgroundColor = 'green';";
options.Start.SetStartAfterScriptRun(js);

var url = new Uri("https://google.com");
using var pdf = await converter.CreatePdfAsync(url, options);
pdf.Save("output.pdf");

以上程式碼片段僅用於演示方法,非常簡單。如需查看更實際的範例,請造訪我們 GitHub 程式碼庫中的對應範例應用程式。該應用程式示範如何處理動態載入內容的頁面。應用程式中的 JavaScript 程式碼會捲動頁面,直到沒有新內容為止。之後,即可進行 PDF 轉換。

在 .NET 中將 HTML 轉換為 PDF,忽略 SSL 錯誤

當發送安全性請求載入 HTML 時,該外掛程式會檢查用於驗證網站身分並啟用加密連線的 SSL 憑證是否有效且可信任。

預設情況下,如果 HTML 轉 PDF 轉換器出於任何原因不信任該證書,插件將拋出異常。這種情況通常是由於憑證是自簽名憑證、已撤銷憑證或已過期憑證造成的。

如果您了解接受不受信任的憑證的風險,可以使用引擎選項指示外掛程式繞過這些檢查。

var engineOptions = new HtmlEngineOptions
{
    IgnoreSslErrors = true
};
using var converter = await HtmlConverter.CreateAsync(engineOptions);

var url = new Uri("https://self-signed.badssl.com/");
using var pdf = await converter.CreatePdfAsync(url);
pdf.Save("output.pdf");

完整程式碼請前往 Docotic.Pdf 範例倉庫。

在現有 PDF 上疊加 HTML 程式碼

有時,您可能希望使用現有的 PDF 文件作為轉換結果的背景。例如,當您有一張表單圖片,並希望在圖片中的空白區域中添加內容時,最終效果看起來就像填寫好的表單。 Docotic.Pdf 及其插件可以實現這一點。

此過程包括從 HTML(疊加內容)建立一個新的 PDF 文件,然後將其與現有 PDF 文件合併。最終文件將同時包含原始內容和新的疊加內容。以下程式碼演示了此過程。

using var converter = await HtmlConverter.CreateAsync();

var options = new HtmlConversionOptions();
options.Page.SetSizeInches(4.13, 5.83);

string htmlCode =
    "<div style=\"position: absolute; top: 270px; right: 100px;\">" +
    "I would like to put this here</div>";
using var htmlPdf = await converter.CreatePdfFromStringAsync(htmlCode, options);

using var pdf = new PdfDocument("pdf-to-merge-with.pdf");
var xObj = pdf.CreateXObject(htmlPdf.Pages[0]);

pdf.Pages[0].Canvas.DrawXObject(xObj, 0, 0);
pdf.Save("output.pdf");

指定疊加層的頁面大小非常重要。通常,疊加層的大小應與您要疊加的頁面大小相同。然後,您需要產生包含疊加內容的新 PDF 檔案。請注意,預設情況下背景是透明的。如有需要,您可以在轉換之前執行腳本來更改背景。

以上程式碼:

  • 根據 HTML 建立一個帶有透明頁面的 PDF 文檔
  • 開啟一個現有的 PDF 文件
  • 根據轉換後的文件的第一頁在現有文件中建立一個 XObject
  • 將該 XObject 繪製到現有文件的第一頁上

完整的帶有範例來源 PDF 的測試項目位於 Docotic.Pdf 範例儲存庫中。