基于前端技术生成PDF方案

需求背景

  • 业务系统须要预览报告(如产品周报,体检报告等)并生成pdf格式供用户下载,或者按期发送给指定用户
  • 报告格式相对固定,由文本,图片和图表组成,基本与前端页面保持一致

解决方案

需求分为两步:报告预览和报告生成。html

  • 报告预览在前端进行展现,可以使用前端技术,如React/Vue等技术栈对其进行还原,数据从服务端获取。
  • 报告生成须要对第一步生成的HTML进行PDF的转换生成,HTML2PDF的方式又分为两种:前端

    • 基于canvas的客户端生成方案
    • 基于nodejs + puppeteer的服务端生成方案

一个完整的案例

下面以一个体检报告的案例进行这两种方案的说明:
体检报告展现形式以下,格式相对固定,分为四个页面:我的信息页,建议页,原理页,我的信息页与建议页数据来源于服务器。
report.png
clipboard.pngnode

基于canvas的客户端生成方案

canvas是HTML5标准中新增的元素,可用于经过使用JS的脚原本绘制图形。canvas提供了toDataURL/toBlob方法,用于把canvas中的内容转换为图片,API文档以下(来源于MDN):nginx

canvas api

因为HTML文档再浏览器中是以DOM树的形式存在,因此咱们能够经过三步完成HTML到PDF的转换:git

  • 将DOM树转换为canvas对象,可以使用html2canvas完成
  • 将canvas转换为图片,可以使用canvas.toDataURL完成
  • 将图片转换为PDF,可以使用jsPDF完成

完整代码实现:https://github.com/simonwoo/d...github

截图以下,点击下载按钮可进行pdf生产:web

clipboard.png

该方案彻底基于客户端的方式生成,不须要服务器进行支持。在使用该方案的过程当中,发现了一些问题:ajax

  • 生产的PDF比较模糊,质量不高
  • 若是HTML中有外链图片,没法生成
  • 因为第一步是经过DOM去生成canvas,因此针对特别长的报告,DOM还没有加载完便点击下载时,会形成报告生成问题
  • 由于是客户端方案,因此须要用户主动触发生成,但对于一些按期发送给用户的报告,该方案没法使用

基于nodejs + puppeteer的服务端生成方案

puppeteer是google推出的headless浏览器,即没有图形界面的浏览器,但又能够实现普通浏览器HTML/JS/CSS的渲染,以及其余基本浏览器功能。你能够理解为一个没有界面的Chrome浏览器。主要有如下几种使用场景:npm

  • 生成页面的截图和PDF
  • 抓取SPA并生成预先呈现的内容(即“SSR”)
  • 爬虫,从网站抓取你须要的内容
  • 自动化测试,自动表单提交,UI测试,键盘输入等
  • 建立一个最新的自动化测试环境。使用最新的JavaScript和浏览器功能,直接在最新版本的Chrome中运行测试

经过理解puppeteer的功能,咱们能够开启一个实例去渲染HTML报告,而后再利用其提供的转换PDF功能进行PDF的生成。canvas

两个重要的API:

  • page.goto(url, [options]) - 打开指定url的文件,能够是本地文件(file://)也能够是网络文件(http://
  • page.pdf([options]) - 转换页面成PDF文件

puppeteer使用一个小例子,将百度网页转换为pdf:

puppeteer使用

完整代码以下:

项目启动流程以下:

  • 进入到webapp目录,使用npm install和npm run start启动前端服务器,地址为:localhost:3000
  • 进入到server目录,使用npm install和npm run dev启动node服务器,地址为:localhost:7001

整个服务架构以下:
架构图

node服务器经过路由增长一个pdf生成的controller,该controller经过启动puppeteer实例去加载localhost:3000的页面并生成pdf。直接在浏览器中经过http://localhost:7001/pdf便可访问到生成的pdf.

在实际环境中,前端页面可部署在nginx服务器上或者直接放在Node服务器上,puppeteer也支持使用cookie的操做,这样能够避免一些须要身份认证的问题。

相比客户端生成方式,使用puppeteer生成的pdf质量比较高,可知足生产要求。

本文中提到的两种方案中,均省去了ajax后端请求数据部分,读者可根据须要自行增长。

Reference

原文连接:https://juejin.im/post/5d036a...

相关文章
相关标签/搜索