前言:將頁(yè)面轉(zhuǎn)成pdf的方案有很多種罢荡,用node將頁(yè)面轉(zhuǎn)成pdf的方案的主要應(yīng)用場(chǎng)景是,本人在項(xiàng)目遇到批量導(dǎo)出pdf的功能紧索,并且導(dǎo)出的頁(yè)面是由前端寫的跷跪,所以主要實(shí)現(xiàn)的功能是需要配合后端實(shí)現(xiàn)批量導(dǎo)出pdf的功能
一、介紹nodejs插件
1. puppeteer
puppeteer 用于通過(guò)程序控制 Chrome 或 Chromium 瀏覽器齐板。通過(guò) Puppeteer吵瞻,你可以進(jìn)行各種自動(dòng)化任務(wù),比如網(wǎng)頁(yè)截圖甘磨、網(wǎng)頁(yè)內(nèi)容抓取橡羞、表單填充、模擬用戶交互等
npm install puppeteer
2. minimist
minimist是一個(gè) Node.js 輕量級(jí)的命令行參數(shù)解析庫(kù)济舆,用于解析命令行參數(shù)卿泽。它可以幫助你將命令行參數(shù)解析為易于處理的對(duì)象格式,使得在 Node.js 腳本中處理命令行參數(shù)變得更加簡(jiǎn)單和方便
npm install minimist
二滋觉、代碼demo (創(chuàng)建名為print.js的文件)
const puppeteer = require('puppeteer');
const arguments = require('minimist');
(async () => {
// 執(zhí)行命令時(shí)签夭,可以通過(guò) --url='http://xxxxxx.com' 方式來(lái)獲取參數(shù)
const prams = arguments(process.argv.slice(2));
console.log('prams', prams);
// 第一步:加載初始化一個(gè)新的 Chrome 或 Chromium 瀏覽器實(shí)例
const browser = await puppeteer.launch({
args: [
'--no-sandbox', // 在某些環(huán)境中避免沙箱問(wèn)題
'--disable-setuid-sandbox',// 可能需要在非標(biāo)準(zhǔn)環(huán)境下運(yùn)行
'--disable-dev-shm-usage', // 解決Linux上內(nèi)存限制問(wèn)題
],
ignoreHTTPSErrors: true,
headless: true
});
// 第二步:創(chuàng)建一個(gè)新的頁(yè)面對(duì)象
const page = await browser.newPage();
// 設(shè)置額外的HTTP請(qǐng)求標(biāo)頭(Headers),如果需要token椎侠,添加token
// await page.setExtraHTTPHeaders({
// 'Authorization': token內(nèi)容
// })
// 第三步:通過(guò)命令行接受的url參數(shù)第租,加載前端pdf打印頁(yè)面
await page.goto(
// "http://192.168.40.29:3000/print.html",
prams.url,
{
// timeout: 3000,
waitUntil: 'networkidle0'
}
);
/**
1. waitUntil: 參數(shù)用于指定 page.waitForNavigation()、page.waitForSelector() 和 page.waitForFunction() 等方法等待條件滿足的規(guī)則
2. load:等待整個(gè)頁(yè)面及其資源加載完成我纪。
3. domcontentloaded:等待頁(yè)面的 DOMContentLoaded 事件完成慎宾,即文檔解析完成,但不等待圖片等資源加載浅悉。
4. networkidle0:等待網(wǎng)絡(luò)狀態(tài)穩(wěn)定趟据,即沒(méi)有網(wǎng)絡(luò)連接數(shù)的變化,通常用于等待所有網(wǎng)絡(luò)連接都被關(guān)閉术健。
5. networkidle2:等待網(wǎng)絡(luò)空閑狀態(tài)汹碱,允許一段時(shí)間的網(wǎng)絡(luò)連接閑置,適用于大多數(shù)網(wǎng)頁(yè)荞估。
6. documentloaded:等待頁(yè)面文檔已加載(不包括樣式表咳促、圖片等資源)色难。
*/
// 等待頁(yè)面中的 iframe 加載完成
await page.waitForSelector('iframe'); // 可以根據(jù)具體的選擇器來(lái)等待特定的 iframe
// 找到頁(yè)面所有的iframe并打印出iframe鏈接,frame.url()獲取frame的url
// await page.frames().map(frame => {
// console.log('fffffff222', frame.url())
// })
// 第四步:將當(dāng)前頁(yè)面保存為 PDF 文件的
// path參數(shù):頁(yè)面輸出的路徑
await page.pdf({
// path: './print.pdf',
path: prams.path,
format: 'A4',
printBackground: true,
preferCSSPageSize: true,
displayHeaderFooter: true,
format: 'A4',
margin: {
top: '2cm',
bottom: '2cm'
},
// headerTemplate: `<div style="80%;text-align:right;margin-right: 20px;font-size:10px">頁(yè)頭</div>`,
// footerTemplate: `<div style="80%;text-align:right;margin-right: 20px;font-size:10px">頁(yè)尾</div>`
});
// 第五步:關(guān)閉整個(gè)瀏覽器實(shí)例的方法
await browser.close();
})()
三等缀、執(zhí)行命令
- 前提是需要先安裝前面安裝兩個(gè)node插件