使用 Puppeteer 从 HTML 生成 PDF 简介 解决方案!已完成

2025-05-24

使用 puppeteer 从 HTML 生成 PDF

介绍

解决方案!

完毕

介绍

这篇文章真是让人沮丧,我花了好几个小时找到一个可行的解决方案。我学到了很多东西,但我觉得这不应该花我那么多时间……

无论如何,目标是从 HTML 生成 PDF,然后将其发送回浏览器,以便用户下载。我尝试了很多不同的方法,我的解决方案很可能不是最优雅或最快速的,但管它呢,总之,它有效。

我把这篇文章当作一个可以保存解决方案的地方,以防将来忘记。这样我就知道该去哪里找了。让我们开始实际的解决方案吧。

解决方案!

前端

让我们从前端开始。

const downloadPDF = () => {
        fetch('/api/invoices/create-pdf', {
            data: {
                invoiceDetails,
                invoiceSettings,
                itemsDetails,
                organisationInfos,
                otherDetails,
                clientDetails
            },
            method: 'POST'
        }).then(res => {
            return res
                .arrayBuffer()
                .then(res => {
                    const blob = new Blob([res], { type: 'application/pdf' })
                    saveAs(blob, 'invoice.pdf')
                })
                .catch(e => alert(e))
        })
    }

这是完成所有操作的函数。就我而言,我们正在生成发票。

1) 使用 POST 方法获取数据。这部分我们会使用正确的数据生成 PDF 文件,并在服务器上生成。(服务器代码会随后发布)

3)我们得到的响应需要转换为数组缓冲区。

4) 我们使用 new Blob() 构造函数创建一个 Blob(二进制大对象)。该 Blob 接受一个可迭代对象作为第一个参数。注意,我们的响应数组缓冲区是如何被方括号 ( [res] ) 包围的。要创建一个可以作为 PDF 读取的 Blob,数据需要先被迭代成二进制形式(我猜是这样的……)。另外,请注意application/pdf类型

5)最后,我使用文件保存包中的 saveAs 函数在前端创建文件!

后端

这是后端部分。这里有一个完整的 Express 应用,以及所有东西。我只是向你展示了这个 PDF 问题中两个方法所在的控制器。

module.exports = {
    createPDF: async function(req, res, next) {
        const content = fs.readFileSync(
            path.resolve(__dirname, '../invoices/templates/basic-template.html'),
            'utf-8'
        )
        const browser = await puppeteer.launch({ headless: true })
        const page = await browser.newPage()
        await page.setContent(content)
        const buffer = await page.pdf({
            format: 'A4',
            printBackground: true,
            margin: {
                left: '0px',
                top: '0px',
                right: '0px',
                bottom: '0px'
            }
        })
                await browser.close()
        res.end(buffer)
    }
}

1) 我正在使用Puppeteer将 HTML 内容创建为 PDF。HTML 内容是从我使用readFileSync获取的 HTML 文件中读取的。

2) 我们存储page.pdf()返回的缓冲区数据,并将其返回给前端。这是稍后转换为数组缓冲区的响应。

完毕

嗯,现在看看代码,它看起来确实比我之前尝试解决这个问题时简单多了。我花了将近10个小时才找到一个合适的答案。10个小时!!!!

提醒自己:如果你感到沮丧,就离开电脑,呼吸新鲜空气,稍后再回来……

编码愉快 <3

文章来源:https://dev.to/damcosset/generate-a-pdf-from-html-and-back-on-the-front-5ff5
PREV
高阶函数 JavaScript JavaScript 中的高阶函数
NEXT
Aura 主题 v2.0.0 现已发布!🥳 🎉