基于Phantomjs生成PDF的实现方法


Posted in Javascript onNovember 07, 2016

本文实例讲述了基于Phantomjs生成PDF的实现方法。分享给大家供大家参考,具体如下:

最近在node.js项目开发中,遇见生成PDF的需求,当然生成PDF不是一个新意的需求;我可以选择利用开源的pdfkit或者其他node pdf模块,或者通过edge.js调用.net/python下的pdf库去做生成pdf。但是在我看来对于这些东西不管如何也需要花费我们太多的时间(pdf报表的内容报表很复杂),不如把所有的画图实现逻辑推向大家所熟悉的html+css来的简洁,快速,这样对于pdf格式变化和图形计算逻辑的变化推到ejs、jade之类的模板引擎,对于以后的修改维护扩展是个很不错的选择。所以选择phantomjs加载页面生成PDF对于我来说不是个不错的选择,同时对于html+css我所需要兼容的仅有webkit一种浏览器,没有厌恶的浏览器兼容性顾虑。所以说做就做,我在项目上花了半个小时配置phantomjs的自动化脚本(在各环境能够自动勾践),以及实现了一个简单页面的PDF转化。

rasterize.js(来自官方pdf demo):

var page = require('webpage').create(),
    system = require('system'),
    address, output, size;
  if (system.args.length < 3 || system.args.length > 5) {
    console.log('Usage: rasterize.js URL filename [paperwidth*paperheight|paperformat] [zoom]');
    console.log(' paper (pdf output) examples: "5in*7.5in", "10cm*20cm", "A4", "Letter"');
    phantom.exit(1);
  } else {
    address = system.args[1];
    output = system.args[2];
    page.viewportSize = { width: 600, height: 600 };
    if (system.args.length > 3 && system.args[2].substr(-4) === ".pdf") {
      size = system.args[3].split('*');
      page.paperSize = size.length === 2 ? { width: size[0], height: size[1], margin: '0px' }
        : { format: system.args[3], orientation: 'portrait', margin: '1cm' };
    }
    if (system.args.length > 4) {
      page.zoomFactor = system.args[4];
    }
    page.open(address, function (status) {
      if (status !== 'success') {
        console.log('Unable to load the address!');
        phantom.exit();
      } else {
        window.setTimeout(function () {
          page.render(output);
          phantom.exit();
        });
      }
    });
  }

在node调用端,使用exec调用命令行输入得到文件并返回到node response流:

guid utils:

'use strict';
  var guid = function () {
    var uid = 0;
    this.newId = function () {
      uid = uid % 1000;
      var now = new Date();
      var utc = new Date(now.getTime() + now.getTimezoneOffset() * 60000);
      return utc.getTime() + uid++;
    }
  }
  exports.utils = {
    guid: new guid()
  };

pdfutil:

'use strict';
  var exec = require('child_process').exec;
  var utils = require('./utils').utils;
  var nodeUtil = require('util');
  var outPut = function (id, req, res) {
    var path = nodeUtil.format("tmp/%s.pdf", utils.guid.newId());
    var port = req.app.settings.port;
    var pdfUrl = nodeUtil.format("%s://%s%s/pdf/%s", req.protocol, req.host, ( port == 80 || port == 443 ? '' : ':' + port ), id);
    exec(nodeUtil.format("phantomjs tool/rasterize.js %s %s A4", pdfUrl, path), function (error, stdout, stderr) {
      if (error || stderr) {
        res.send(500, error || stderr);
        return;
      }
      res.set('Content-Type', 'application/pdf');
      res.download(path);
    });
  };
  exports.pdfUtils = {
    outPut: outPut
  };

响应的代码也可以很好的转换为java/c#...的命令行调用来得到pdf并推送到response流中。一切都这么简单搞定。

node也有node-phantom模块,但是用它生成的pdf样式有点怪,所以最后还是坚持采用了exec方式去做。

还有就是phantomjs生成PDF不会把css的背景色和背景图片带进去,所以对于这块专门利用了纯色图片img标签,并position:relative或者absolute去定位文字.这点还好因为这个页面上用户不会看的。

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
javascript cookie解码函数(兼容ff)
Mar 17 Javascript
情人节专属 纯js脚本1k大小的3D玫瑰效果
Feb 11 Javascript
JavaScript高级程序设计(第3版)学习笔记2 js基础语法
Oct 11 Javascript
仿百度输入框智能提示的js代码
Aug 22 Javascript
jQuery带进度条全屏图片轮播特效代码分享
Jun 28 Javascript
js实现页面跳转的五种方法推荐
Mar 10 Javascript
jQuery实现的超链接提示效果示例【附demo源码下载】
Sep 09 Javascript
js中document.referrer实现移动端返回上一页
Feb 22 Javascript
vue中post请求以a=a&amp;b=b 的格式写遇到的问题
Apr 27 Javascript
Vue.js实现开发购物车功能的方法详解
Feb 22 Javascript
koa2 从入门到精通(小结)
Jul 23 Javascript
layui: layer.open加载窗体时出现遮罩层的解决方法
Sep 26 Javascript
扩展Bootstrap Tooltip插件使其可交互的方法
Nov 07 #Javascript
js提示框替代系统alert,自动关闭alert对话框的实现方法
Nov 07 #Javascript
jQuery插件WebUploader实现文件上传
Nov 07 #Javascript
jQuery利用sort对DOM元素进行排序操作
Nov 07 #Javascript
AngularJS的ng Http Request与response格式转换方法
Nov 07 #Javascript
easyUI实现(alert)提示框自动关闭的实例代码
Nov 07 #Javascript
AngularJS ng-template寄宿方式用法分析
Nov 07 #Javascript
You might like
php curl基本操作详解
2013/07/23 PHP
PHP curl使用实例
2015/07/02 PHP
PHP基于phpqrcode类生成二维码的方法示例详解
2020/08/07 PHP
改善用户体验的五款jQuery插件分享
2011/05/22 Javascript
javascript:window.open弹出窗口的位置问题
2014/03/18 Javascript
js统计录入文本框中字符的个数并加以限制不超过多少
2014/05/23 Javascript
jQuery焦点控制图层展示延迟隐藏的方法
2015/03/09 Javascript
javascript实现验证IP地址等相关信息代码
2015/05/10 Javascript
jQuery替换textarea中换行的方法
2015/06/10 Javascript
Nodejs的express使用教程
2015/11/23 NodeJs
AngularJS基础 ng-show 指令简单示例
2016/08/03 Javascript
javascript实现简单的可随机变色网页计算器示例
2016/12/30 Javascript
AngularJS实现controller控制器间共享数据的方法示例
2017/10/30 Javascript
解决vue build打包之后首页白屏的问题
2018/03/06 Javascript
video.js 实现视频只能后退不能快进的思路详解
2018/08/09 Javascript
在Vue methods中调用filters里的过滤器实例
2018/08/30 Javascript
基于axios 解决跨域cookie丢失的问题
2018/09/26 Javascript
jQuery实现动态加载(按需加载)javascript文件的方法分析
2019/05/31 jQuery
vue把输入框的内容添加到页面的实例讲解
2019/11/11 Javascript
[01:03:59]2018DOTA2亚洲邀请赛3月30日 小组赛B组VGJ.T VS Secret
2018/03/31 DOTA
[01:27:30]LGD vs Newbee 2019国际邀请赛小组赛 BO2 第二场 8.16
2019/08/19 DOTA
Python Web框架Tornado运行和部署
2020/10/19 Python
Python 登录网站详解及实例
2017/04/11 Python
python中利用Future对象异步返回结果示例代码
2017/09/07 Python
Python3学习笔记之列表方法示例详解
2017/10/06 Python
Python常见数据类型转换操作示例
2019/05/08 Python
利用Django模版生成树状结构实例代码
2019/05/19 Python
Python 虚拟空间的使用代码详解
2019/06/10 Python
Python利用matplotlib做图中图及次坐标轴的实例
2019/07/08 Python
Python之Numpy的超实用基础详细教程
2019/10/23 Python
英国排名第一的最新设计师品牌手表独立零售商:TIC Watches
2016/09/24 全球购物
中邮全球便购:中国邮政速递物流
2017/03/04 全球购物
美国正宗设计师眼镜在线零售商:EYEZZ
2019/03/23 全球购物
学生操行评语大全
2014/04/24 职场文书
道德与公民自我评价
2015/03/09 职场文书
一文简单了解MySQL前缀索引
2022/04/03 MySQL