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

在 Azure Functions 和 Azure App Services 中將 HTML 轉換為 PDF

Docotic.Pdf 提供適用於 HTML 轉 PDF 轉換的 .NET 的免費附加元件。此附加元件在轉換期間使用 Chromium。這有助於獲得優異的轉換品質。不過有一個缺點——您需要在目標環境中擁有執行 Chromium 的權限。

通常,您可以完全控制專用伺服器或虛擬伺服器。但像 Azure Functions 或 AWS Lambda 這類無伺服器或沙箱化環境則是另一回事。在那裡安裝相依性或執行 Chromium 可能會有挑戰。

本文說明如何在 Azure Functions 與 Linux 上的 Azure App Services 中使用 Docotic.Pdf 程式庫的 HTML 轉 PDF 附加元件。

Azure 中的 HTML 轉 PDF 轉換

在 Azure 的 Linux 上執行 HTML 轉 PDF 轉換

Azure Functions 和 App Services 在 沙箱 中執行。若要在 Azure 的 Linux 上將 HTML 轉換為 PDF,您需要執行以下步驟:

  1. 預先安裝 Chromium 相依性
  2. 讓附加元件在停用沙箱時執行 Chromium
  3. 讓附加元件將瀏覽器下載到自訂路徑

安裝 Linux 上的 Chromium 相依性

自 2021 年 8 月起,Azure Functions 和 Azure App Services 的 Linux 環境已預先安裝 Chromium 相依性。因此,您不需要安裝任何東西。

如有需要,您可以使用以下命令在不同 Linux 發行版中安裝 Chromium 相依性。

# Debian
apt-get -y install chromium

# CentOS
yum -y install pango.x86_64 libXcomposite.x86_64 libXcursor.x86_64 libXdamage.x86_64 libXext.x86_64 libXi.x86_64 libXtst.x86_64 cups-libs.x86_64 libXScrnSaver.x86_64 libXrandr.x86_64 GConf2.x86_64 alsa-lib.x86_64 atk.x86_64 gtk3.x86_64 ipa-gothic-fonts xorg-x11-fonts-100dpi xorg-x11-fonts-75dpi xorg-x11-utils xorg-x11-fonts-cyrillic xorg-x11-fonts-Type1 xorg-x11-fonts-misc

讓附加元件在停用沙箱時執行 Chromium

如果您在 Azure 的 Linux 上執行預設的 HTML 轉 PDF 轉換程式碼,將會看到錯誤

Failed to launch browser! Running as root without --no-sandbox is not supported

using var converter = await HtmlConverter.CreateAsync();
// ...

HtmlEngineOptions.UseSandbox 屬性設為 false,附加元件就會在不使用沙箱的情況下啟動 Chromium:

var engineOptions = new HtmlEngineOptions
{
    UseSandbox = false
};
using var converter = await HtmlConverter.CreateAsync(engineOptions);
using var pdf = await converter.CreatePdfAsync(url);
pdf.Save("output.pdf");

請注意,不建議停用 Chromium sandbox。當沙箱停用時,Chromium 可能會執行惡意的基於 Javascript 的攻擊利用。在我們的情況中,Chromium 會在 Azure 沙箱中執行,這降低了攻擊風險。您可以採取以下做法進一步降低風險:

  • 僅處理本機 HTML 範本和受信任的網站。
  • 在與其他服務隔離的 Azure Functions/App Services 中執行 HTML 轉 PDF 轉換。

讓附加元件將瀏覽器下載到自訂路徑

Azure Functions 和 App Services 經常 直接從 ZIP 套件執行。在這種情況下,您應指定附加元件要放置已下載 Chromium 的路徑。這是必要的,因為附加元件無法將 Chromium 下載到應用程式目錄,也無法從該目錄啟動它。使用 HtmlEngineOptions.Path 屬性指定下載的 Chromium 自訂路徑。以下 C# 範例程式碼示範如何將 Chromium 下載到目前使用者的暫存資料夾:

var engineOptions = new HtmlEngineOptions
{
    Path = System.IO.Path.GetTempPath(),
    UseSandbox = false
};
using var converter = await HtmlConverter.CreateAsync(engineOptions);
using var pdf = await converter.CreatePdfAsync(url);
pdf.Save("output.pdf");

就是這樣!使用上面的程式碼,透過 Docotic.Pdf.HtmlToPdf 附加元件 在 Azure 的 Linux 上將 HTML 轉換為 PDF。

在 Azure 的 Windows 上執行 HTML 轉 PDF 轉換

目前(2024 年 2 月),Azure Functions 和 Azure App Services 在 Windows 上不允許執行 Chromium。啟動時會看到以下錯誤:

System.ComponentModel.Win32Exception (14001): The application has failed to start because its
side-by-side configuration is incorrect. Please see the application event log or use the
command-line sxstrace.exe tool for more detail.

因此,目前附加元件不支援在 Windows 上的 Azure Functions 和 Azure App Services。

在 Docker 容器中將 HTML 轉換為 PDF

在 Azure 中使用 HTML 轉 PDF 附加元件還有另一種選擇。您可以在 Docker 容器中執行轉換。只要在 Dockerfile 中安裝相依性,並在 C# 程式碼中停用 Chromium 沙箱即可。以下是用於 ASP.NET Core 應用程式中 HTML 轉 PDF 轉換的範例 Dockerfile:

FROM mcr.microsoft.com/dotnet/aspnet:3.1 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

RUN apt-get update && apt-get install -y chromium

FROM mcr.microsoft.com/dotnet/sdk:3.1 AS build
WORKDIR /src
COPY ["HtmlToPdfWebApp/HtmlToPdfWebApp.csproj", "HtmlToPdfWebApp/"]
RUN dotnet restore "HtmlToPdfWebApp/HtmlToPdfWebApp.csproj"
COPY . .
WORKDIR "/src/HtmlToPdfWebApp"
RUN dotnet build "HtmlToPdfWebApp.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "HtmlToPdfWebApp.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "HtmlToPdfWebApp.dll"]

以下是類似 Azure Functions 應用程式的範例 Dockerfile:

FROM mcr.microsoft.com/azure-functions/dotnet:3.0 AS base
WORKDIR /home/site/wwwroot
EXPOSE 80

RUN apt-get update && apt-get install -y chromium

FROM mcr.microsoft.com/dotnet/sdk:3.1 AS build
WORKDIR /src
COPY ["HtmlToPdfFunction/HtmlToPdfFunction.csproj", "HtmlToPdfFunction/"]
RUN dotnet restore "HtmlToPdfFunction/HtmlToPdfFunction.csproj"
COPY . .
WORKDIR "/src/HtmlToPdfFunction"
RUN dotnet build "HtmlToPdfFunction.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "HtmlToPdfFunction.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /home/site/wwwroot
COPY --from=publish /app/publish .
ENV AzureWebJobsScriptRoot=/home/site/wwwroot \
    AzureFunctionsJobHost__Logging__Console__IsEnabled=true