我们正在使用 headless chrome 和 puppeteer Sharp 生成 PDF。这一直工作得很好,直到有一天它停止加载 css 文件,并且我们的 PDF 丢失了所有引导样式。
近期活动:
16号我们升级到.NET 8
28 日,PDF 被报告为损坏(我们的计费团队每天都使用此 pdf 生成器)
我们没有对 pdf 生成过程进行任何更改
下面是我使用 puppeteer Sharp 生成 PDF 的代码。
public async Task<byte[]> GetPdf(Controller controller, string view, object model, string pdfName, string? headerHtml = null, string? footerHtml = null)
{
using (var browserFetcher = new BrowserFetcher())
{
await browserFetcher.DownloadAsync(PuppeteerSharp.BrowserData.Chrome.DefaultBuildId);
using (var browser = await Puppeteer.LaunchAsync(new LaunchOptions
{
Headless = true
}))
{
if (string.IsNullOrWhiteSpace(footerHtml))
{
footerHtml = await this.RenderView(controller, "_ReportFooter", "");
}
PdfOptions pdfOptions = new PdfOptions()
{
DisplayHeaderFooter = true,
FooterTemplate = footerHtml,
HeaderTemplate = headerHtml ?? "<span></span>",
PrintBackground = true,
Format = PaperFormat.A4,
MarginOptions =
{
Top = "20px",
Bottom = "60px",
Left = "40px",
Right = "40px"
}
};
using (var page = await browser.NewPageAsync())
{
//await page.GoToAsync("https://***domainName***/Workorders/ViewWorkorderPDF?workorderIdsAsString=239379", new NavigationOptions
//{
// WaitUntil = [WaitUntilNavigation.Load, WaitUntilNavigation.DOMContentLoaded, WaitUntilNavigation.Networkidle0, WaitUntilNavigation.Networkidle2]
//});
//await page.SetContentAsync(await RenderView(controller, view, model, true), new NavigationOptions { Timeout = 60000, WaitUntil = [WaitUntilNavigation.Load, WaitUntilNavigation.DOMContentLoaded, WaitUntilNavigation.Networkidle0, WaitUntilNavigation.Networkidle2] });
await page.SetContentAsync(await RenderView(controller, view, model, true), new NavigationOptions { WaitUntil = [WaitUntilNavigation.Load, WaitUntilNavigation.Networkidle0] });
await page.WaitForNavigationAsync();
var toReturn = await page.PdfDataAsync(pdfOptions);
await browser.CloseAsync();
return toReturn;
}
}
}
这是我用来生成 html 的视图的示例。 注意:@host 替换为我们的主机名
<html>
<head>
<meta charset="utf-8">
<base href="https://@host/">
@*<link href="https://@host/lib/WorkordersPrintable-BootStrap/css/bootstrap.min.css" rel="stylesheet" asp-append-version="true" />*@
<link href="https://@host/lib/bootstrap-3.4.1-dist/css/bootstrap.min.css" rel="stylesheet" asp-append-version="true" />
<link href="https://@host/css/WorkordersPrintable.css" rel="stylesheet" asp-append-version="true" />
@*<link href="https://@host/css/WorkordersPrintableMedia.css" rel="stylesheet" asp-append-version="true" />*@
</head>
<body>
<div class="container PrintView">
<div class="row">
@if (Model.BulkSummary != null && Model.BulkSummary.Count() > 0)
{
<div class="col-12">
<div class="d-flex justify-content-center">
@if (Model.CompanyName != null)
{
<h3>@Model.CompanyName - Bulk Report</h3>
}
<h3>@Model.StartDate - @Model.EndDate</h3>
</div>
</div>
....
下面是一些有效和无效 PDF 的 PDF 示例。我把机密信息涂黑了
这在我们的开发环境中每次都运行良好。这促使我尝试通过导航到托管 Web 应用程序的 Web 服务器上的生成器来生成 PDF,如果我在 Web 服务器上使用浏览器,它工作得完全正常。这让我相信这可能是某种网络更改或对已安装的 chrome 的更改,因此我更新了网络服务器(运行 Windows Server 2016)
当我将 headless 设置为 false 并发布到测试版时,它就开始工作了,测试版在同一网络服务器上运行,但我使用的是不同的版本,这样我就不会经常降低发布的生产量。当我在测试版上以 headless = false 运行浏览器时,它可以在生产环境中运行,而无需对该版本进行任何更改。我不知道这是巧合还是这就是解决方案。我与我的运营团队进行了交谈,他们当时没有做出任何改变。如果有人更多地了解这里发生的事情,我欢迎任何解释。
如果再次发生这种情况,我会添加更新。