如何确保在生成 PDF 之前加载图像?

Posted

技术标签:

【中文标题】如何确保在生成 PDF 之前加载图像?【英文标题】:How to ensure images load before generating PDF? 【发布时间】:2012-05-16 02:57:41 【问题描述】:

我有一个 php 循环,它执行以下操作:

    通过 CURL 登录网页 需要登录的捕获和内部页面 将页面的 html 保存到本地文件 使用 WKHTMLTOPDF 将页面呈现为 PDF

我遇到的问题是每隔一段时间(大约 30% 的时间),图像不会在 PDF 中呈现。如果我打开其中一个保存的 HTML 文件,我会发现我需要进入并手动刷新页面才能显示图像。

关于如何务实地确保图像加载有什么想法吗?我尝试过的事情:

    sleep(n) 在每一行之间 将 --javascript-delay 30000 添加到我的 WKHTMLTOPDF 调用中,以确保它有足够的时间来加载任何图像。

#1 使情况变得更糟,而#2 什么也没做。

谢谢!

【问题讨论】:

本地HTML中的图片引用还有效吗?因此,您必须从远程服务器获取每张图像并将其复制到本地的正确位置。我想知道是否更容易获取有效的 cookie(通过 CURL 等),然后将其提供给 wkhtmltopdf,然后直接进入远程身份验证页面? wkhtmltopdf 实际上有一个生成 cookie 的方法,但是在这种特殊情况下开始工作是一场噩梦(因此是 CURL 路由)。当我在 HTML 中阅读时,我正在替换远程图像路径的所有路径,这绝对有效,因为我可以打开 HTML 文件并硬刷新以查看图像,就好像没有足够的魅力来获取图像每次。最坏的情况我想我可以尝试让该 cookie 与 wkhtmltopdf 一起使用。 对于另一种方法,您可以尝试使用 wget 及其 --page-requisites--convert-links 选项将 HTML/CSS/图像下载到本地位置,同时更改链接。然后对本地副本运行 PDF 渲染器。 【参考方案1】:

在示例的第 3 步和第 4 步之间,您可能需要考虑解析所有图像链接的 HTML 文件并使用 curl 单独下载它们,并将它们保存在本地,然后更新保存的 HTML 文件中的链接以指向新的本地图像资源而不是远程图像资源。

在将 HTML 呈现为 PDF 时,这将大大缩短图像的加载时间。

【讨论】:

谢谢,史蒂夫——这就是我最终要做的,而且效果很好。【参考方案2】:

也许您可以处理下载的 HTML,搜索 img 标签,然后将图像下载到本地存储并替换 src 属性。这样,您应该在所有图像可用后生成 pdf。

【讨论】:

【参考方案3】:

您不能为您需要知道正在加载的图像添加 onLoad 吗?像

<img src='foo.jpg' onLoad='callbackFuncion();'/>

【讨论】:

【参考方案4】:

如果用 cURL 抓取 html 后,让 php 循环遍历每个 img 元素并读取图像文件的二进制数据并将图像 src url 属性替换为打开的图像文件的 base64 编码值,例如:

'&lt;img src="data:image/jpg;base64,'. base64_encode($imagedata) . '"/&gt;'

如果 base64 图像数据被硬编码到页面中,那么这将为您提供一种编程方式来验证所有图片是否已“加载”并防止在所有图片下载之前开始出现 pdf 转换问题...

【讨论】:

这需要一个全新的布局,仅用于使用视图进行 pdf 渲染。没有太多的练习。有很多图片,更容易达到 php mem 限制。【参考方案5】:

我从未这样做过,但也许您可以通过反复调用 curl_getinfo() 然后读出 CURLINFO_SIZE_DOWNLOAD 的值来确定下载是否完成 - 直到该值不再改变?

【讨论】:

以上是关于如何确保在生成 PDF 之前加载图像?的主要内容,如果未能解决你的问题,请参考以下文章

PDF 优化 - 在嵌入文本之前加载图像 - 请参阅提供的示例

如何在加载pdf文件之前显示加载图标?

如何确保图像在 DOM 中完全加载

如何确保 D3 在 javascript 运行之前完成加载多个 CSV?

TCPDF 创建 PDF 耗时太长,此时如何显示加载效果

确保在渲染组件之前加载 Vuex 状态