如何使用 WaitFor 类延迟 C# PDF 渲染

This article was translated from English: Does it need improvement?
Translated
View the article in English

查克尼特·宾

在渲染 PDF 文档时,会出现一个常见问题,即在所有必要的资产和 javascript 动画加载完成之前,渲染过程就已经开始。这会导致 PDF 文档呈现不完整或不正确。最初,我们通过允许用户设置任意延迟来解决这个问题。然而,依靠任意延迟并不是一种可靠或有效的方法。

为了提供更稳健的解决方案,我们实现了一个WaitFor类,以增强 PDF 渲染过程。来自RenderOptionsWaitFor对象提供了多个选项,包括

These feature are available for converting of HTML 字符串, 文件网址 到 PDF 文档。让我们来探讨一下这项新功能的主要方面。


适用于PDF的C# NuGet库

安装使用 NuGet

Install-Package IronPdf
Java PDF JAR

下载 DLL

下载DLL

手动安装到你的项目中

适用于PDF的C# NuGet库

安装使用 NuGet

Install-Package IronPdf
Java PDF JAR

下载 DLL

下载DLL

手动安装到你的项目中

开始在您的项目中使用IronPDF,并立即获取免费试用。

第一步:
green arrow pointer

查看 IronPDFNuget 用于快速安装和部署。它有超过800万次下载,正在使用C#改变PDF。

适用于PDF的C# NuGet库 nuget.org/packages/IronPdf/
Install-Package IronPdf

考虑安装 IronPDF DLL 直接。下载并手动安装到您的项目或GAC表单中: IronPdf.zip

手动安装到你的项目中

下载DLL

默认即时渲染示例

默认情况下,页面加载完成后立即进行渲染。如果想正常呈现,则无需调用 PageLoad 方法。

:path=/static-assets/pdf/content-code-examples/how-to/waitfor-pageload.cs
using IronPdf;

ChromePdfRenderer renderer = new ChromePdfRenderer();

// Render as soon as the page is loaded
renderer.RenderingOptions.WaitFor.PageLoad();

PdfDocument pdf = renderer.RenderHtmlAsPdf("<h1>testing</h1>");
IRON VB CONVERTER ERROR developers@ironsoftware.com
VB   C#

自定义渲染延迟示例

在渲染 PDF 之前需要特定延迟的情况下,可以设置任意毫秒数作为延迟。这样就能灵活地满足任何特定的时间要求。

该选项的工作方式与使用 RenderingOptions.RenderDelay 属性的旧实现方式相同。不过,旧属性已被弃用,强烈建议使用新的 API,即 RenderingOptions.WaitFor.RenderDelay

:path=/static-assets/pdf/content-code-examples/how-to/waitfor-delay-time.cs
using IronPdf;

ChromePdfRenderer renderer = new ChromePdfRenderer();

// Render after 3000ms
renderer.RenderingOptions.WaitFor.RenderDelay(3000);

PdfDocument pdf = renderer.RenderHtmlAsPdf("<h1>testing</h1>");
Imports IronPdf

Private renderer As New ChromePdfRenderer()

' Render after 3000ms
renderer.RenderingOptions.WaitFor.RenderDelay(3000)

Dim pdf As PdfDocument = renderer.RenderHtmlAsPdf("<h1>testing</h1>")
VB   C#

加载所有字体 示例

字体 已加载所有字体 方法中的 等待 类允许 PDF 渲染过程暂停,直到从谷歌字体或其他服务器等外部资源加载所有字体。这可确保最终的 PDF 包含所有必需的字体,并保留文档的预期排版和视觉外观。

:path=/static-assets/pdf/content-code-examples/how-to/waitfor-all-fonts.cs
using IronPdf;

string htmlContent = @"
<!DOCTYPE html>
<html lang=""en"">
<head>
  <meta charset=""UTF-8"">
  <title>Test Registration of Extension</title>
  <!-- for google web fonts -->
  <link rel=""preconnect"" href=""https://fonts.googleapis.com"">
  <link rel=""preconnect"" href=""https://fonts.gstatic.com"" crossorigin>
  <link rel=""stylesheet"" href=""https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap"" >

  <style>
  /* for remote fonts */
  @font-face {
    font-family: 'CustomFont';
    src: url('https://stage.gradfinale.co.uk/tcpdf/fonts/avgr65wttf.ttf');
  }
  p#p1 { font-family: CustomFont, sans-serif; }

  /* for local fonts */
  @font-face {
    font-family: 'LocalCustomFont';
    src: local('Arial');
  }
  p#p3 { font-family: LocalCustomFont, sans-serif; }
  </style>
</head>
<body>
	<h1>This is Delayed Render Test!</h1>
	<p style=""font-family: Roboto, monospace;"">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla scelerisque ligula venenatis erat <strong>scelerisque</strong> auctor.</p>
	<p id=""p1"">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla scelerisque ligula venenatis erat <strong>scelerisque</strong> auctor.</p>
	<p id=""p3"">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla scelerisque ligula venenatis erat <strong>scelerisque</strong> auctor.</p>
</body>
</html>)";

ChromePdfRenderer renderer = new ChromePdfRenderer();
renderer.RenderingOptions.WaitFor.AllFontsLoaded(10000);

PdfDocument pdf = renderer.RenderHtmlAsPdf(htmlContent);
IRON VB CONVERTER ERROR developers@ironsoftware.com
VB   C#

自定义 JavaScript 执行示例

为了对渲染过程进行更多控制,我们的功能允许您指定在渲染 PDF 文档前需要执行的自定义 JavaScript 函数。这样,您就可以在启动渲染过程之前执行任何必要的任务或检查。这样,用户就能控制何时触发渲染。

在 JavaScript 中,函数 window.ironpdf.notifyRender()用于触发渲染任务。一旦notifyRender()调用后,渲染过程将开始。您可以完全控制何时调用该函数。

:path=/static-assets/pdf/content-code-examples/how-to/waitfor-javascript.cs
using IronPdf;

string html = @"<!DOCTYPE html>
<html>
<body>
<h1>Testing</h1>
<script type='text/javascript'>

// Set delay
setTimeout(function() {
    window.ironpdf.notifyRender();
}, 1000);

</script>
</body>
</html>";

ChromePdfRenderOptions renderingOptions = new ChromePdfRenderOptions();

// Set rendering to wait for the notifyRender function
renderingOptions.WaitFor.JavaScript(5000);

PdfDocument pdf = ChromePdfRenderer.StaticRenderHtmlAsPdf(html, renderingOptions);
IRON VB CONVERTER ERROR developers@ironsoftware.com
VB   C#

HTML 元素示例

使用此选项,可将渲染过程设置为等待特定 HTML 元素,如元素 ID、名称、标签名称,甚至使用查询选择器来定位元素。

等待元素 ID

在下面的代码示例中,渲染将等待一个特定的元素 ID。

:path=/static-assets/pdf/content-code-examples/how-to/waitfor-html-element-id.cs
using IronPdf;

string htmlContent = @"
<!DOCTYPE html>
<html lang=""en"">
<head>
  <meta charset=""UTF-8"">
  <title>Delayed render tests</title>
  <script type=""text/javascript"">
	setTimeout(function() {
		var h1Tag = document.createElement(""h1"");
		h1Tag.innerHTML = ""bla bla bla"";
		h1Tag.setAttribute(""id"", ""myid"");

        var block = document.querySelector(""div#x"");
		block.appendChild(h1Tag);
	}, 1000);
  </script>
</head>
<body>
	<h1>This is Delayed Render Test!</h1>
    <div id=""x""></div>
</body>
</html>";

ChromePdfRenderer renderer = new ChromePdfRenderer();
renderer.RenderingOptions.WaitFor.HtmlElementById("myid", 5000);

PdfDocument pdf = renderer.RenderHtmlAsPdf(htmlContent);
IRON VB CONVERTER ERROR developers@ironsoftware.com
VB   C#

等待元素名称

在下面的代码示例中,渲染过程将等待一个特定的元素名称。

:path=/static-assets/pdf/content-code-examples/how-to/waitfor-html-element-name.cs
using IronPdf;

string htmlContent = @"
<!DOCTYPE html>
<html lang=""en"">
<head>
  <meta charset=""UTF-8"">
  <title>Delayed render tests</title>
  <script type=""text/javascript"">
	setTimeout(function() {
		var h1Tag = document.createElement(""h1"");
		h1Tag.innerHTML = ""bla bla bla"";
		h1Tag.setAttribute(""name"", ""myName"");

        var block = document.querySelector(""div#x"");
		block.appendChild(h1Tag);
	}, 1000);
  </script>
</head>
<body>
	<h1>This is Delayed Render Test!</h1>
    <div id=""x""></div>
</body>
</html>";

ChromePdfRenderer renderer = new ChromePdfRenderer();
renderer.RenderingOptions.WaitFor.HtmlElementByName("myName", 5000);

PdfDocument pdf = renderer.RenderHtmlAsPdf(htmlContent);
IRON VB CONVERTER ERROR developers@ironsoftware.com
VB   C#

等待元素标签名称

在下面的代码示例中,渲染过程将等待特定的元素标记名称。

:path=/static-assets/pdf/content-code-examples/how-to/waitfor-html-element-tag-name.cs
using IronPdf;

string htmlContent = @"
<!DOCTYPE html>
<html lang=""en"">
<head>
  <meta charset=""UTF-8"">
  <title>Delayed render tests</title>
  <script type=""text/javascript"">
	setTimeout(function() {
		var newElem = document.createElement(""h2"");
		newElem.innerHTML = ""bla bla bla"";

        var block = document.querySelector(""div#x"");
		block.appendChild(newElem);
	}, 1000);
  </script>
</head>
<body>
	<h1>This is Delayed Render Test!</h1>
    <div id=""x""></div>
</body>
</html>";

ChromePdfRenderer renderer = new ChromePdfRenderer();
renderer.RenderingOptions.WaitFor.HtmlElementByTagName("h2", 5000);

PdfDocument pdf = renderer.RenderHtmlAsPdf(htmlContent);
IRON VB CONVERTER ERROR developers@ironsoftware.com
VB   C#

使用查询选择器

在下面的代码示例中,渲染过程将等待查询选择器选择的元素。HtmlQuerySelector` 方法将等待一个id为 "myid "class 为 "blablastyle "的**img 标签。

:path=/static-assets/pdf/content-code-examples/how-to/waitfor-html-element-query-selector.cs
using IronPdf;

string htmlContent = @"
<!DOCTYPE html>
<html lang=""en"">
<head>
  <meta charset=""UTF-8"">
  <title>Test Registration of Extension</title>
  <script type=""text/javascript"">
	setTimeout(function() {
		var img = document.createElement(""img"");
		img.onload = function() {
			img.setAttribute(""id"", ""myid"");
			img.setAttribute(""class"", ""blablastyle"");
			var block = document.getElementById(""x"");
			block.appendChild(img);
		};
		img.src = ""https://www.w3schools.com/images/picture.jpg"";	// .src after .onload to ignore cached, if any
	}, 1000);
  </script>
</head>
<body>
	<h1>This is Delayed Render Test!</h1>
    <div id=""x""></div>
</body>
</html>";

ChromePdfRenderer renderer = new ChromePdfRenderer();
renderer.RenderingOptions.WaitFor.HtmlQuerySelector("img#myid.blablastyle", 5000);

PdfDocument pdf = renderer.RenderHtmlAsPdf(htmlContent);
IRON VB CONVERTER ERROR developers@ironsoftware.com
VB   C#

网络空闲示例

没有网络活动

这种类型的网络空闲允许您等待直到没有网络活动,这通常表示内容已完全加载。适用于单页应用程序 (SPA) 或没有任何长期轮询网络请求或持续网络活动的简单网页。

只有在没有持续的网络活动至少500毫秒**后,才会开始渲染过程。

:path=/static-assets/pdf/content-code-examples/how-to/waitfor-network-idle-0.cs
using IronPdf;

ChromePdfRenderer renderer = new ChromePdfRenderer();

// Render unless there has been no network activity for at least 500ms
renderer.RenderingOptions.WaitFor.NetworkIdle0();

PdfDocument pdf = renderer.RenderHtmlAsPdf("<h1>testing</h1>");
IRON VB CONVERTER ERROR developers@ironsoftware.com
VB   C#

允许两种网络活动

NetworkIdle2 "方法适用于需要长时间轮询网络请求或心跳 ping 的网络应用程序或网页。通常情况下,会涉及 1-2 个请求。在这种情况下,即使这些请求正在进行中,也不会被视为触发网络空闲事件的无效因素,因为最多有两个请求是可以接受的。

在启动渲染流程之前,最多应有两个网络活动,持续时间至少为 500 毫秒。该选项为处理固定数量的网络活动提供了快速配置。

:path=/static-assets/pdf/content-code-examples/how-to/waitfor-network-idle-2.cs
using IronPdf;

ChromePdfRenderer renderer = new ChromePdfRenderer();

// Render unless there are at most 2 network activities for at least 500ms
renderer.RenderingOptions.WaitFor.NetworkIdle2();

PdfDocument pdf = renderer.RenderHtmlAsPdf("<h1>testing</h1>");
IRON VB CONVERTER ERROR developers@ironsoftware.com
VB   C#

自定义网络活动津贴

在涉及多个网络请求的情况下,您可以灵活地自定义网络空闲持续时间允许的网络请求数量,这些请求不会使网络空闲事件的触发失效。此选项适用于不符合前两种方法的有特殊要求的网络应用程序或网页。通过提供这种自定义功能,我们可以确保在不同情况下处理各种使用案例。

:path=/static-assets/pdf/content-code-examples/how-to/waitfor-customize-network.cs
using IronPdf;

ChromePdfRenderer renderer = new ChromePdfRenderer();

// Render unless there are at most 5 network activities for at least 1000ms
renderer.RenderingOptions.WaitFor.NetworkIdle(1000, 5);

PdfDocument pdf = renderer.RenderHtmlAsPdf("<h1>testing</h1>");
Imports IronPdf

Private renderer As New ChromePdfRenderer()

' Render unless there are at most 5 network activities for at least 1000ms
renderer.RenderingOptions.WaitFor.NetworkIdle(1000, 5)

Dim pdf As PdfDocument = renderer.RenderHtmlAsPdf("<h1>testing</h1>")
VB   C#

设置最长等待时间

此外,"JavaScript"、"NetworkIdle"、"NetworkIdle0 "和 "NetworkIdle2 "方法还允许您设置最大等待时间,以确保等待不会是无限期的。这些方法的 maxWaitTime 参数可用于此目的。

请注意
所有指定的时间值均以毫秒为单位。

查克尼特·宾

软件工程师

Chaknith 是开发者中的福尔摩斯。他第一次意识到自己可能在软件工程方面有前途,是在他出于乐趣做代码挑战的时候。他的重点是 IronXL 和 IronBarcode,但他为能帮助客户解决每一款产品的问题而感到自豪。Chaknith 利用他从直接与客户交谈中获得的知识,帮助进一步改进产品。他的轶事反馈不仅仅局限于 Jira 票据,还支持产品开发、文档编写和市场营销,从而提升客户的整体体验。当他不在办公室时,他可能会在学习机器学习、编程或徒步旅行。