基于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 判断中文字符长度的函数代码
Aug 27 Javascript
js中判断Object、Array、Function等引用类型对象是否相等
Aug 29 Javascript
js Array对象的扩展函数代码
Apr 24 Javascript
js实现日期级联效果
Jan 23 Javascript
jQuery实现个性翻牌效果导航菜单的方法
Mar 09 Javascript
JS实现移动端按首字母检索城市列表附源码下载
Jul 05 Javascript
Node.js使用Express.Router的方法
Nov 14 Javascript
vue-router 组件复用问题详解
Jan 22 Javascript
vue源码学习之Object.defineProperty 对数组监听
May 30 Javascript
详解Angular如何正确的操作DOM
Jul 06 Javascript
JavaScript 双向链表操作实例分析【创建、增加、查找、删除等】
Apr 28 Javascript
OpenLayers加载缩放控件使用方法详解
Sep 25 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初学者头疼十四条问题大总结
2008/11/12 PHP
zend optimizer在wamp的基础上安装图文教程
2013/10/26 PHP
[原创]PHPCMS遭遇会员投稿审核无效的解决方法
2017/01/11 PHP
Phpstorm+Xdebug断点调试PHP的方法
2018/05/14 PHP
Cookie 注入是怎样产生的
2009/04/08 Javascript
用js实现计算加载页面所用的时间
2010/04/02 Javascript
js判断样式className同时增加class或删除class
2013/01/30 Javascript
选择复选框按钮置灰否则按钮可用
2014/05/22 Javascript
JavaScript字符串对象substring方法入门实例(用于截取字符串)
2014/10/17 Javascript
nodejs URL模块操作URL相关方法介绍
2015/03/03 NodeJs
Vue进度条progressbar组件功能
2018/04/17 Javascript
vue-router的HTML5 History 模式设置
2018/09/08 Javascript
ES6知识点整理之数组解构和字符串解构的应用示例
2019/04/17 Javascript
js计算两个时间差 天 时 分 秒 毫秒的代码
2019/05/21 Javascript
python+POP3实现批量下载邮件附件
2018/06/19 Python
使用Python调取任意数字资产钱包余额功能
2019/08/15 Python
Keras搭建自编码器操作
2020/07/03 Python
Python是怎样处理json模块的
2020/07/16 Python
详解Django中views数据查询使用locals()函数进行优化
2020/08/24 Python
HTML5之HTML元素扩展(上)—新增加的元素及使用概述
2013/01/31 HTML / CSS
一个基于canvas的移动端图片编辑器的实现
2020/10/28 HTML / CSS
时装界的“朋克之母”:Vivienne Westwood
2017/07/06 全球购物
39美元购买一副眼镜或太阳镜:39DollarGlasses.com
2018/06/17 全球购物
super关键字的用法
2012/04/10 面试题
实习协议书范本
2014/04/22 职场文书
驻村工作先进事迹
2014/08/14 职场文书
个人主要事迹材料
2014/08/26 职场文书
七夕相亲活动策划方案
2014/08/31 职场文书
乡党政领导班子群众路线教育实践活动个人对照检查材料
2014/09/20 职场文书
教师节主持词开场白
2015/05/29 职场文书
观看禁毒宣传片后的感想
2015/08/11 职场文书
严以用权学习心得体会
2016/01/12 职场文书
交通安全学习心得体会
2016/01/18 职场文书
2019大学生预备党员转正思想汇报
2019/06/21 职场文书
使用pandas模块实现数据的标准化操作
2021/05/14 Python
SQLServer之常用函数总结详解
2021/08/30 SQL Server