该页面可以包含自动翻译的文本。
在 Azure Functions 和 Azure App Services 中将 HTML 转换为 PDF
Docotic.Pdf 为 在 .NET 中进行 HTML 转 PDF 转换 提供免费附加组件。该附加组件在转换过程中使用 Chromium。这有助于获得出色的转换质量。不过也有一个缺点——你需要有权限在目标环境中运行 Chromium。
通常,你对专用服务器或虚拟服务器拥有完全控制权。但无服务器或沙盒化环境,例如 Azure Functions 或 AWS Lambda,则是另一回事。在那里安装依赖项或运行 Chromium 可能会比较困难。
本文介绍如何在 Linux 上的 Azure Functions 和 Azure App Services 中使用 Docotic.Pdf 库的 HTML 转 PDF 附加组件。

在 Azure 上的 Linux 中运行 HTML 转 PDF 转换
Azure Functions 和 App Services 运行在一个 沙盒 中。要在 Azure 的 Linux 上将 HTML 转换为 PDF,你需要执行以下操作:
- 预安装 Chromium 依赖项
- 让附加组件在禁用沙盒的情况下运行 Chromium
- 让附加组件将浏览器下载到自定义路径
在 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.
因此,目前 Azure Functions 和 Azure App Services 在 Windows 上不受该附加组件支持。
在 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 Function 应用的示例 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