在系統開發中,有需求需要實現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({...})