在系统开发中,有需求需要实现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({...})