基于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 相关文章推荐
js判断是否为数组的函数: isArray()
Oct 30 Javascript
jquery实现页面图片等比例放大缩小功能
Feb 12 Javascript
Egret引擎开发指南之创建项目
Sep 03 Javascript
js实现分享到随页面滚动而滑动效果的方法
Apr 10 Javascript
js兼容火狐显示上传图片预览效果的方法
May 21 Javascript
浅谈JavaScript中setInterval和setTimeout的使用问题
Aug 01 Javascript
JavaScript jquery及AJAX小结
Jan 24 Javascript
js字符串截取函数slice、substring和substr的比较
May 17 Javascript
JavaScript操作表单实例讲解(上)
Jun 20 Javascript
vue系列之动态路由详解【原创】
Sep 10 Javascript
动态统计当前输入内容的字节、字符数的实例详解
Oct 27 Javascript
在博客园博文中添加自定义右键菜单的方法详解
Feb 05 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 REMOTE_ADDR之获取访客IP的代码
2008/04/22 PHP
php empty()与isset()区别的详细介绍
2013/06/17 PHP
php无限遍历目录示例
2014/02/21 PHP
修改destoon会员公司的伪静态中的com目录的方法
2014/08/21 PHP
如何解决PHP使用mysql_query查询超大结果集超内存问题
2016/03/14 PHP
yii2中LinkPager增加总页数和总记录数的实例
2017/08/28 PHP
Yii框架学习笔记之session与cookie简单操作示例
2019/04/30 PHP
javascript中this做事件参数相关问题解答
2013/03/17 Javascript
jQuery过滤选择器用法分析
2015/02/10 Javascript
jQuery+canvas实现的球体平抛及颜色动态变换效果
2016/01/28 Javascript
基于BootStrap环境写jQuery tabs插件
2016/07/12 Javascript
jquery中each循环的简单回滚操作
2017/05/05 jQuery
百度地图去掉marker覆盖物或者去掉maker的label文字方法
2018/01/26 Javascript
vue+webpack dev本地调试全局样式引用失效的解决方案
2019/11/12 Javascript
Vue axios 跨域请求无法带上cookie的解决
2020/09/08 Javascript
[01:04:48]VGJ.S vs TNC Supermajor 败者组 BO3 第一场 6.6
2018/06/07 DOTA
[35:55]完美世界DOTA2联赛PWL S3 Rebirth vs CPG 第一场 12.11
2020/12/13 DOTA
python使用mysql数据库示例代码
2017/05/21 Python
如何实现删除numpy.array中的行或列
2018/05/08 Python
对Python中列表和数组的赋值,浅拷贝和深拷贝的实例讲解
2018/06/28 Python
python实现登录密码重置简易操作代码
2019/08/14 Python
Django接收照片储存文件的实例代码
2020/03/07 Python
python else语句在循环中的运用详解
2020/07/06 Python
浅析Python 字符编码与文件处理
2020/09/24 Python
html5利用canvas实现颜色容差抠图功能
2019/12/23 HTML / CSS
俄罗斯最大的消费电子连锁零售商:Mvideo
2017/06/25 全球购物
电子商务个人自荐信
2013/12/12 职场文书
三年大学自我鉴定
2014/01/16 职场文书
教师业务学习制度
2014/01/25 职场文书
初中学校军训方案
2014/05/09 职场文书
医学生求职信
2014/07/01 职场文书
文员试用期转正自我鉴定
2014/09/14 职场文书
导盲犬小Q观后感
2015/06/11 职场文书
2016高考冲刺决心书
2015/09/23 职场文书
Navicat for MySQL的使用教程详解
2021/05/27 MySQL
用Python编写简单的gRPC服务的详细过程
2021/07/04 Python