利用puppeteer实现PDF文件导出

在系统开发中,有需求需要实现PDF文件的导出,其中echarts渲染的图表只能由前端生成。因此PDF模板的制作就放在了前端。

本地调试环境

后端会启动进程进行文件生成。使用的是puppeteer插件。简单来说,它是一个基于Chromium的一个无痕浏览器。使用它可以模拟浏览器操作。

  • 安装
npm install puppeteer --save-dev
  • 运行文件
// app.js

const puppeteer = require('puppeteer');
 
(async () => {
  const browser = await puppeteer.launch({args: ['--no-sandbox', '--disable-setuid-sandbox'], ignoreHTTPSErrors: true, headless: true});
  const page = await browser.newPage();
  await page.goto("https://www.baidu.com", {timeout: 3000,waitUntil: 'networkidle2'});

  await page.pdf({
      path: 'example.pdf', 
      format: 'A4',
      printBackground: true,
        preferCSSPageSize: true,
        displayHeaderFooter: true,
        format: 'A4',
        margin: {
            top: '2cm',
            bottom: '2cm'
        },
        headerTemplate: `<div style="width:100%;text-align:right;margin-right: 20px;font-size:10px">页头</div>`,
        footerTemplate: `<div style="width:100%;text-align:right;margin-right: 20px;font-size:10px">页尾</div>`
    });
 
  await browser.close();
})()
  • 说明

上面的代码其实就是创建了一个浏览器实例,然后将页面定位到https://www.baidu.com上,然后等待网络请求(waitUntil: 'networkidle2')完成后,延时3秒(timeout: 1000)等待页面渲染后。进行文件的导出(page.pdf({...}))

以上,我们就完成了本地测试环境的搭建,那在制作模板的过程中需要注意哪些呢?

模板制作

在页面业务实现和css布局上其实和平时没有任何区别。但是要实现PDF的分页就有需要一点优化。

我的需求,第一页会显示pdf标题、logo和日期。第二页声明内容、第三页之后才是报告内容。由此,固定内容部分可以使用固定高度的形式实现,而后面的内容,当做一个长页面处理即可,因为pdf导出有bottom: '2cm'设置,不至于导出的内容会贴近页面底部导致不美观。

我的第一、二页设置 height: 870px 仅供参考。

总结

致此,我们可以使用命令 node app.js 生成文件进行效果查看了。

需要注意的是,PDF模板制作的时候发送的请求可能需要携带token等信息。puppeteer打开的浏览器是没有的。我们可以进行配置:

  await page.setExtraHTTPHeaders({
     'Authorization': token内容
  });
  page.goto({...})
posted @ 2021-01-18 12:03  miku561  阅读(2007)  评论(0编辑  收藏  举报