当前位置: 首页 > 后端技术 > Node.js

基于前端技术生成PDF解决方案

时间:2023-04-03 20:35:02 Node.js

需求背景业务系统需要预览报表(如产品周报、体检报告等)并生成pdf格式供用户下载,或定时发送给指定用户.报表格式比较固定,由文字、图片和图表组成,与前端页面基本一致解决方案需求分为两个步骤:报表预览和报表生成。报表预览在前端展示,可以使用React/Vue等前端技术还原,数据从服务端获取。报告生成需要将第一步生成的HTML转成PDF。HTML2PDF的方式分为两种:基于nodejs的canvas-based客户端生成方案+puppeteer服务端生成方案。一个完整的案例如下,附带一份体检报告案例说明了两种解决方案:体检报告的展示形式如下,格式比较固定,分为四个页面:个人信息页,建议页、原则页、个人信息页和建议页。数据来自服务器。report.png基于canvas的客户端生成解决方案canvas是HTML5标准中的一个新元素,可以使用JS脚本来绘制图形。Canvas提供toDataURL/toBlob方法将画布中的内容转换为图片。API文档如下(来自MDN):由于HTML文档在浏览器中以DOM树的形式存在,我们可以分三步完成。HTML转PDF:将DOM树转成canvas对象,可以使用html2canvas完成canvas到图片的转换,可以使用canvas.toDataURL完成图片到PDF的转换,可以使用jsPDF完成完整代码实现:https://github。com/simonwoo/d...截图如下,点击下载按钮开始pdf制作:本方案完全基于客户端生成,不需要服务端支持。在使用该方案的过程中,发现了一些问题:生成的PDF比较模糊,质量不高。如果HTML中有外部链接,则无法生成。由于第一步是通过DOM生成canvas,所以对于特别长的报表,在没有加载DOM的情况下点击下载,会导致报表生成出现问题。因为是客户端解决方案,需要用户主动触发生成。但是对于一些定期发送给用户的报告,这种方案无法使用基于nodejs+puppeteer的服务端生成方案。Puppeteer是谷歌推出的无头浏览器,即没有图形界面的浏览器,但它也可以渲染普通浏览器HTML/JS/CSS,以及其他基本的浏览器功能。你可以把它理解为一个没有界面的Chrome浏览器。主要有以下几种使用场景:生成页面截图和PDF抓取SPA并生成预渲染内容(即“SSR”)爬虫,抓取你需要的网站自动化测试,自动化表单提交,UI测试,键盘回车等.创建一个最新的自动化测试环境。使用最新的JavaScript和浏览器特性,直接在最新版本的Chrome中运行测试通过了解puppeteer的功能,我们可以打开一个实例渲染HTML报告,然后使用其提供的转换PDF功能生成PDF。两个重要的API:page.goto(url,[options])-打开指定url的文件,可以是本地文件(file://)也可以是网络文件(http://)page.pdf([options])-将页面转为PDF文件Puppeteer使用一个小例子将百度网页转为pdf:完整代码如下:前端部分:https://github.com/simonwoo/d...back-end部分:https://github.com/simonwoo/d...项目启动流程如下:进入webapp目录,使用npminstall和npmrunstart启动前端服务器,地址为:localhost:3000进入server目录,使用npminstall和npmrundev启动节点服务器地址为:localhost:7001。整个服务架构如下:node服务器通过路由添加一个pdf生成的controller,controller通过启动puppeteer实例加载localhost:3000的页面并生成pdf。生成的pdf可以直接在浏览器中通过http://localhost:7001/pdf访问。在实际环境中,前端页面可以部署在nginx服务器上,也可以直接放在Node服务器上。Puppeteer也支持使用cookies操作,可以避免一些需要认证的问题。与客户端生成方式相比,puppeteer生成的pdf质量相对较高,可以满足生产需求。本文提到的两种方案都省略了ajax后端请求数据部分,读者可以根据需要添加。参考html2canvas-https://html2canvas.hertzen.c...jsPDF-https://github.com/MrRio/jsPDFpuppeteer-https://zhaoqize.github.io/pu...Eggjs-https://eggjs。org/zh-cn/