基于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 相关文章推荐
jQuery 一个图片切换的插件
Oct 09 Javascript
onclick与listeners的执行先后问题详细解剖
Jan 07 Javascript
JS实现div内部的文字或图片自动循环滚动代码
Apr 19 Javascript
jQuery创建DOM元素实例解析
Jan 19 Javascript
Javascript无参数和有参数类继承问题解决方法
Mar 02 Javascript
JavaScript判断按钮被点击的方法
Dec 13 Javascript
基于jQuery实现页面搜索功能
Mar 26 Javascript
jquery 动态增加删除行的简单实例(推荐)
Oct 12 Javascript
CodeMirror js代码加亮使用总结
Mar 25 Javascript
Node.js中的http请求客户端示例(request client)
May 04 Javascript
基于express中路由规则及获取请求参数的方法
Mar 12 Javascript
详解ES6数组方法find()、findIndex()的总结
May 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
文章推荐系统(三)
2006/10/09 PHP
php中使用exec,system等函数调用系统命令的方法(不建议使用,可导致安全问题)
2012/09/07 PHP
php页面防重复提交方法总结
2013/11/25 PHP
php创建sprite
2014/02/11 PHP
ThinkPHP实现将SESSION存入MYSQL的方法
2014/07/22 PHP
PHP生成压缩文件实例
2015/02/07 PHP
php简单统计字符串单词数量的方法
2015/06/19 PHP
Jquery 点击按钮显示和隐藏层的代码
2011/07/25 Javascript
仅Firefox中链接A无法实现模拟点击以触发其默认行为
2011/07/31 Javascript
基于jquery的用鼠标画出可移动的div
2012/09/06 Javascript
javascript图像处理—仿射变换深度理解
2013/01/16 Javascript
jQuery实现倒计时按钮功能代码分享
2014/09/03 Javascript
node.js中的emitter.emit方法使用说明
2014/12/10 Javascript
javascript实现 百度翻译 可折叠的分享按钮列表
2015/03/12 Javascript
浅析2种JavaScript继承方式
2015/12/04 Javascript
详解javascript高级定时器
2015/12/31 Javascript
JavaScript中的Number数字类型学习笔记
2016/05/26 Javascript
微信小程序 数据访问实例详解
2016/10/08 Javascript
jquery+ajax实现省市区三级联动 (封装和不封装两种方式)
2017/05/15 jQuery
微信小程序如何获知用户运行小程序的场景教程
2017/05/17 Javascript
Angular.js ng-file-upload结合springMVC的使用教程
2017/07/10 Javascript
vue2.0+ 从插件开发到npm发布的示例代码
2018/04/28 Javascript
通过函数作用域和块级作用域看javascript的作用域链
2018/08/05 Javascript
详解React native fetch遇到的坑
2018/08/30 Javascript
nodejs遍历文件夹下并操作HTML/CSS/JS/PNG/JPG的方法
2018/11/01 NodeJs
编写更好的JavaScript条件式和匹配条件的技巧(小结)
2019/06/27 Javascript
一次微信小程序内地图的使用实战记录
2019/09/09 Javascript
详解Vue中Axios封装API接口的思路及方法
2020/10/10 Javascript
python定时器(Timer)用法简单实例
2015/06/04 Python
对python中的 os.mkdir和os.mkdirs详解
2018/10/16 Python
windows下numpy下载与安装图文教程
2019/04/02 Python
解决python Jupyter不能导入外部包问题
2020/04/15 Python
特罗佩亚包官方网站:Tropea
2017/01/03 全球购物
New Balance美国官网:运动鞋和健身服装
2017/04/11 全球购物
小学班级特色活动方案
2014/08/31 职场文书
python 自动刷新网页的两种方法
2021/04/20 Python