使用 puppeteer 将 PDF 保存到文件

Posted

技术标签:

【中文标题】使用 puppeteer 将 PDF 保存到文件【英文标题】:Save PDF to File using puppeteer 【发布时间】:2019-04-09 06:29:48 【问题描述】:

我正在使用 puppeteer 通过 Fetch API 获取 PDF 并将文件保存到磁盘。

我正在尝试将 PDF 保存到磁盘上的文件,但是当我打开 pdf 时,我看到一个白屏。

!!已编辑!!

在这里找到解决方案https://github.com/GoogleChrome/puppeteer/issues/299#issuecomment-340199753

【问题讨论】:

在十六进制编辑器中查看 robo2 文件可能会有所帮助,因为它可能是文本文件而不是有效的 pdf。 【参考方案1】:
await page.pdf( path: 'path/to/save/pdf', format: 'A4' );

这会将 PDF 保存到磁盘中。

【讨论】:

【参考方案2】:

由于您已经在使用 Puppeteer,将网页保存为 PDF 的最佳方法是使用 Puppeteer 打开它,然后使用 Puppeteer API 保存 PDF。

page.pdf() 函数就是这样做的。 See docs.

我假设通过使用 fetch(),您只下载了 getPdf.asp,它本身不会产生有效的 PDF 响应流。也许它只响应客户端 html,包括从某个远程资源获取 PDF 的脚本。

因此我会尝试:

await page.goto(PDF_PAGE_URL);
const pdfBuffer = await page.pdf();
// process the buffer

希望对你有帮助!

【讨论】:

如何处理缓冲区以流式传输响应?【参考方案3】:

后端


如果您将路径选项添加到page.pdf(),它将直接保存到托管服务器的磁盘。

前端


如果您从服务器 page.pdf() 返回 pdf 缓冲区并将其发送到客户端/前端。您必须处理 pdf。

...
 const pdfBuffer = await page.pdf(
   printBackground: true,
   format: 'A4',
 );
 res.send(pdfBuffer);
...

假设您有一条路线 /download,它将从 puppeteer 的 page.pdf() 选项返回 pdf 缓冲区。在前端,您有一个 ID 为“下载”的按钮来处理流。以下是你的做法

    处理缓冲区 使用该缓冲区创建一个 ObjectURL。 创建一个a 标记,将href 指向对象网址。 添加下载属性并模拟对该链接的虚假点击。 将下载按钮绑定到处理函数的“点击”事件。

代码

function handleClick() 
    fetch('/download')
        .then((res) => res.blob()) // --- 1.
        .then((readableStream) => 
            const blob = new Blob([readableStream],  type: 'application/pdf' ); // --- 1.
            blobToSaveAs('invoice', blob); // --- 2.
        )
        .catch((e) => console.error(e));


function blobToSaveAs(fileName, blob) 
    try 
        const url = window.URL.createObjectURL(blob); // --- 2.
        const link = document.createElement('a'); // --- 3.
        if (link.download !== undefined) 
            link.setAttribute('href', url); // --- 3.
            link.setAttribute('download', fileName); // --- 4.
            link.style.visibility = 'hidden';
            document.body.appendChild(link);
            link.click(); // --- 4.
            document.body.removeChild(link);
        
     catch (e) 
        console.error('BlobToSaveAs error', e);
    


document.getElementById('download').addEventListener('click', handleClick); // --- 5.

【讨论】:

以上是关于使用 puppeteer 将 PDF 保存到文件的主要内容,如果未能解决你的问题,请参考以下文章

如何将屏幕截图从 puppeteer 上传到 cloudinary 或 google bucket?

使用特定配置打开 Puppeteer(下载 PDF 而不是 PDF 查看器)

有没有办法使用 Puppeteer 定位特定元素并在将 html 转换为 pdf 时保留 CSS?

使用 php 将 PDF 文件保存到 XML 文件

如何对加密PDF进行注释(图文详解)

如何对加密PDF进行注释(图文详解)