基于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 Archive Network 集合
May 12 Javascript
比较新旧两个数组值得增加和删除的JS代码
Oct 30 Javascript
ExtJS[Desktop]实现图标换行示例代码
Nov 17 Javascript
JS实现超简单的仿QQ折叠菜单效果
Sep 21 Javascript
js简单网速测试方法完整实例
Dec 15 Javascript
Javascript之Math对象详解
Jun 07 Javascript
在一个页面重复使用一个js函数的方法详解
Dec 26 Javascript
微信小程序 image组件binderror使用例子与js中的onerror区别
Feb 15 Javascript
JS实现发送短信验证后按钮倒计时功能(防止刷新倒计时失效)
Jul 07 Javascript
JavaScript for循环 if判断语句(学习笔记)
Oct 11 Javascript
js读取本地文件的实例
Dec 22 Javascript
JS FormData对象使用方法实例详解
Feb 12 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连接及读取和写入mysql数据库的常用代码
2014/08/11 PHP
PHP调用存储过程返回值不一致问题的解决方法分析
2016/04/26 PHP
php生成无限栏目树
2017/03/16 PHP
PHP迭代与递归实现无限级分类
2017/08/28 PHP
TP5框架实现一次选择多张图片并预览的方法示例
2020/04/04 PHP
PHP如何使用cURL实现Get和Post请求
2020/07/11 PHP
改版了网上的一个js操作userdata
2007/04/27 Javascript
学习ExtJS 访问容器对象
2009/10/07 Javascript
JavaScript 原型继承
2011/12/26 Javascript
extjs tabpanel限制选项卡数量实现思路及代码
2013/04/02 Javascript
JS保存、读取、换行、转Json报错处理方法
2013/06/14 Javascript
用jQuery获取IE9下拉框默认值问题探讨
2013/07/22 Javascript
jquery对ajax的支持介绍
2013/12/10 Javascript
js中opener与parent的区别详细解析
2014/01/14 Javascript
JS弹出可拖拽可关闭的div层完整实例
2015/02/13 Javascript
jQuery Validate验证框架经典大全
2015/09/23 Javascript
JavaScript中apply方法的应用技巧小结
2016/09/29 Javascript
微信小程序日历组件calendar详解及实例
2017/06/08 Javascript
用户管理的设计_jquery的ajax实现二级联动效果
2017/07/13 jQuery
Vue.js实现可配置的登录表单代码详解
2018/03/29 Javascript
微信小程序中遇到的iOS兼容性问题小结
2018/11/14 Javascript
用js限制网页只在微信浏览器中打开(或者只能手机端访问)
2020/12/24 Javascript
python时间整形转标准格式的示例分享
2014/02/14 Python
浅谈python内置变量-reversed(seq)
2017/06/21 Python
使用pygame模块编写贪吃蛇的实例讲解
2018/02/05 Python
Python3对称加密算法AES、DES3实例详解
2018/12/06 Python
PyQT实现菜单中的复制,全选和清空的功能的方法
2019/06/17 Python
pytorch 指定gpu训练与多gpu并行训练示例
2019/12/31 Python
Python字典dict常用方法函数实例
2020/11/09 Python
h5页面唤起app如果没安装就跳转下载(iOS和Android)
2020/06/03 HTML / CSS
应届生保险求职信
2013/11/11 职场文书
国培教师自我鉴定
2014/02/12 职场文书
2014年社会实践活动总结范文
2014/04/29 职场文书
大三学年自我鉴定范文(3篇)
2014/09/28 职场文书
党政领导班子群众路线对照检查材料
2014/10/26 职场文书
致我们终将逝去的青春观后感
2015/06/10 职场文书