Docker平台下NodeJs Puppeteer实现html转pdf过程示例
Docker 平台 NodeJs Puppeteer实现html转pdf
1. 背景
PDM系统中有需求工艺单需要打印成PDF(客户对细节要求极高),当时出了5个方案:
- 从DOM制作屏幕截图 html2canvas jspdf 文字无法拷贝
- 使用PDF库 jsPDF 或 PDFKit 按组件一个一个拼凑,不合适已有html的打印模板方式
- CSS打印规则,调用浏览器打印,pdf 文件导入到系统,操作繁琐
- itext (目前用的) 和spire功能强大,但商业用途需收费,wkhtmltopdf开源免费,后端生成,黑匣子,后端开发前端代码,可视化麻烦通过模板生成PDF的实际效果和模板效果相差较大,修改起来不好把握
- 基于Node.js的Puppeteer和HeadlessChrome 展示效果与实际生成的PDF接近
使用方案5是可以借助puppeteer调用headless浏览器生成PDF,对css的支持度很高,PDF能很大限度反应模板的样式(对css支持度很高),前端对模板的控制度更高,支持dom操作,以下是模板样式和PDF样式对比:
生成的pdf文件样式和编写的html模板样式一致度较高,可以让前端编写模板文件实时查看html内容样式,改完之后用该模板调用后端的node服务生成的pdf模板能较高程度的还原模板内容,前端可以通过模板引擎如EJS(类似于当前方案后端技术的freemarker模板)生成模板执行一些复杂的dom操作和样式控制。
2. 所需依赖
npm install express jsdom puppeteer
express: 用来和业务系统通信,返回pdf流给业务系统
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内容并生成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实现html转pdf过程示例的详细内容,更多关于Docker 平台 NodeJs Puppeteer实现html转pdf的资料请关注脚本之家其它相关文章!
相关文章
node.js中的querystring.parse方法使用说明
这篇文章主要介绍了node.js中的querystring.parse方法使用说明,本文介绍了querystring.parse的方法说明、语法、接收参数、使用实例和实现源码,需要的朋友可以参考下2014-12-12使用nodejs、Python写的一个简易HTTP静态文件服务器
这篇文章主要介绍了使用nodejs、Python写的一个简易HTTP静态文件服务器,分为nodejs和Python两个版本,用类似淘宝的CSS、JS文件加载方式处理静态文件加载,需要的朋友可以参考下2014-07-07安装使用Mongoose配合Node.js操作MongoDB的基础教程
这篇文章主要介绍了安装使用Mongoose来让Node.js操作MongoDB的基础教程,前端js+后端node+js操作MongoDB正是所谓最流行的一种JavaScript全栈开发方案,需要的朋友可以参考下2016-03-03nodejs部署到腾讯云服务器的实现(宝塔面板linux系统)
本文主要介绍了nodejs部署到腾讯云服务器的实现(宝塔面板linux系统),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2022-06-06npm安装淘宝镜像报错问题解决(npm install -g cnpm)
本文主要介绍了npm安装淘宝镜像报错问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2024-01-01
最新评论