Docker平臺下NodeJs?Puppeteer實現(xiàn)html轉pdf過程示例
Docker 平臺 NodeJs Puppeteer實現(xiàn)html轉pdf
1. 背景
PDM系統(tǒng)中有需求工藝單需要打印成PDF(客戶對細節(jié)要求極高),當時出了5個方案:
- 從DOM制作屏幕截圖 html2canvas jspdf 文字無法拷貝
- 使用PDF庫 jsPDF 或 PDFKit 按組件一個一個拼湊,不合適已有html的打印模板方式
- CSS打印規(guī)則,調用瀏覽器打印,pdf 文件導入到系統(tǒng),操作繁瑣
- itext (目前用的) 和spire功能強大,但商業(yè)用途需收費,wkhtmltopdf開源免費,后端生成,黑匣子,后端開發(fā)前端代碼,可視化麻煩通過模板生成PDF的實際效果和模板效果相差較大,修改起來不好把握
- 基于Node.js的Puppeteer和HeadlessChrome 展示效果與實際生成的PDF接近
使用方案5是可以借助puppeteer調用headless瀏覽器生成PDF,對css的支持度很高,PDF能很大限度反應模板的樣式(對css支持度很高),前端對模板的控制度更高,支持dom操作,以下是模板樣式和PDF樣式對比:
生成的pdf文件樣式和編寫的html模板樣式一致度較高,可以讓前端編寫模板文件實時查看html內(nèi)容樣式,改完之后用該模板調用后端的node服務生成的pdf模板能較高程度的還原模板內(nèi)容,前端可以通過模板引擎如EJS(類似于當前方案后端技術的freemarker模板)生成模板執(zhí)行一些復雜的dom操作和樣式控制。
2. 所需依賴
npm install express jsdom puppeteer
express: 用來和業(yè)務系統(tǒng)通信,返回pdf流給業(yè)務系統(tǒng)
jsdom: 解析DOM,在生成pdf的時候要讓前端可以自定義pdf的頁頭頁尾
puppeteer: 調用headless生成PDF
3. 核心代碼
genPdfFile.js
const puppeteer = require('puppeteer'); const fs = require('fs'); const jsdom = require("jsdom"); const { JSDOM } = jsdom; let browserInstance; async function getBrowserInstance() { if (!browserInstance) { browserInstance = await puppeteer.launch({ headless: true, args: ['--no-sandbox', '--disable-setuid-sandbox'] }); } return browserInstance; } async function generatePDFFromHTML(htmlString) { try { // 啟動Puppeteer const browser = await getBrowserInstance(); const page = await browser.newPage(); // 頁眉 let headerTemplate = ""; // 頁腳 let footerTemplate = ""; { // 構建頁眉 console.log("headerTemplate"); let dom = new JSDOM(htmlString); let document = dom.window.document; const elementsToRemove = document.querySelectorAll(".page_start"); if(elementsToRemove.length > 0) { headerTemplate = elementsToRemove[0].outerHTML; } elementsToRemove.forEach(el => el.parentNode.removeChild(el)); updatedHtmlString = dom.serialize(); } { // 構建頁腳 console.log("footerTemplate"); dom = new JSDOM(updatedHtmlString); document = dom.window.document; const endelementsToRemove = document.querySelectorAll(".page_end"); if(endelementsToRemove.length > 0) { footerTemplate = endelementsToRemove[0].outerHTML; } endelementsToRemove.forEach(el => el.parentNode.removeChild(el)); updatedHtmlString = dom.serialize(); } // 設置HTML內(nèi)容并生成PDF的Buffer await page.setContent(updatedHtmlString); // 設置 PDF 選項 const pdfOptions = { path: 'example.pdf', format: 'a4', displayHeaderFooter: true, headerTemplate, footerTemplate, margin: { top: '60px', bottom: '20px', left: '20px', right: '50px' }, }; // 生成 PDF // 如果要生成帶著 screen media的pdf,在page.pdf() 前面先調用 page.emulateMedia('screen') const pdfBuffer = await page.pdf(pdfOptions); return pdfBuffer; } catch(error) { console.log(error); } } module.exports = { getBrowserInstance, generatePDFFromHTML }
4. DockerFile
FROM ghcr.io/puppeteer/puppeteer:latest MAINTAINER weiqlog@126.com USER root RUN mkdir -p /pdfG WORKDIR /pdfG COPY package*.json ./ COPY . . RUN npm instal EXPOSE 10030 ENTRYPOINT ["node", "main.js", "10030"]
使用:
docker pull 1505774577/html_to_pdf:1.0.0.dev docker run -d -p 10030:10030 --cap-add=SYS_ADMIN 1505774577/html_to_pdf:1.0.0.dev
以上就是Docker平臺下NodeJs Puppeteer實現(xiàn)html轉pdf過程示例的詳細內(nèi)容,更多關于Docker 平臺 NodeJs Puppeteer實現(xiàn)html轉pdf的資料請關注腳本之家其它相關文章!
相關文章
快速刪除 node_modules 目錄的集中方法(多種方法)
本文介紹了三種快速刪除node_modules目錄的方法:使用rimraf工具、通過npx運行rimraf以及在Windows命令提示符中使用del命令,每種方法都適合不同的操作系統(tǒng)和使用場景2024-11-11開箱即用的Node.js+Mysql模塊封裝實現(xiàn)詳解
這篇文章主要為大家介紹了開箱即用的Node.js+Mysql模塊封裝實現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-01-01nodejs dgram模塊廣播+組播的實現(xiàn)示例
這篇文章主要介紹了nodejs dgram模塊廣播+組播的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-11-11node+express+jade制作簡單網(wǎng)站指南
上文我們介紹了使用node+express+ejs制作頁面,今天我們來看看使用node+express+jade制作簡單網(wǎng)站,本文記錄了一下整個搭建過程,給需要的小伙伴們參考下吧2014-11-11