基于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之学会吝啬 精简代码
Apr 25 Javascript
Javascript冒泡排序算法详解
Dec 03 Javascript
JS+CSS实现带关闭按钮DIV弹出窗口的方法
Feb 27 Javascript
深入学习jQuery Validate表单验证
Jan 18 Javascript
微信小程序 WebSocket详解及应用
Jan 21 Javascript
JavaScript中的编码和解码函数
Feb 15 Javascript
JavaScript设计模式之代理模式详解
Jun 09 Javascript
浅谈ECMAScript6新特性之let、const
Aug 02 Javascript
json数据传到前台并解析展示成列表的方法
Aug 06 Javascript
帮你彻底搞懂JS中的prototype、__proto__与constructor(图解)
Aug 23 Javascript
深入解析微信小程序开发中遇到的几个小问题
Jul 11 Javascript
浅谈vue在html中出现{{}}的原因及解决方式
Nov 16 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教程 预定义变量
2009/10/23 PHP
PHP中开发XML应用程序之基础篇 添加节点 删除节点 查询节点 查询节
2010/07/09 PHP
探讨PHP JSON中文乱码的解决方法详解
2013/06/06 PHP
php通过数组实现多条件查询实现方法(字符串分割)
2014/05/06 PHP
隐藏Nginx或Apache以及PHP的版本号的方法
2016/01/03 PHP
Laravel5框架自定义错误页面配置操作示例
2019/04/17 PHP
javascript 函数式编程
2007/08/16 Javascript
jQuery源码分析-01总体架构分析
2011/11/14 Javascript
Javascript面向对象设计一 工厂模式
2011/12/20 Javascript
js数组常用操作方法小结(增加,删除,合并,分割等)
2016/08/02 Javascript
基于JQuery的购物车添加删除以及结算功能示例
2017/03/08 Javascript
详解Node项目部署到云服务器上
2017/07/12 Javascript
微信小程序实现星级评分和展示
2018/07/05 Javascript
小程序自定义日历效果
2018/12/29 Javascript
详解微信小程序-canvas绘制文字实现自动换行
2019/04/26 Javascript
微信小程序云开发如何使用npm安装依赖
2019/05/18 Javascript
使用p5.js实现动态GIF图片临摹重现
2019/10/23 Javascript
vuex实现像调用模板方法一样调用Mutations方法
2019/11/06 Javascript
python中精确输出JSON浮点数的方法
2014/04/18 Python
python中的__init__ 、__new__、__call__小结
2014/04/25 Python
Python IDE PyCharm的基本快捷键和配置简介
2015/11/04 Python
Python实现定时备份mysql数据库并把备份数据库邮件发送
2018/03/08 Python
pytorch:model.train和model.eval用法及区别详解
2020/02/20 Python
Python多线程:主线程等待所有子线程结束代码
2020/04/25 Python
Mybag美国/加拿大:英国奢华包包和名牌手袋网站
2020/02/16 全球购物
在对linux系统分区进行格式化时需要对磁盘簇(或i节点密度)的大小进行选择,请说明选择的原则
2012/11/24 面试题
一套软件测试笔试题
2014/07/25 面试题
交警正风肃纪剖析材料
2014/10/29 职场文书
2014年教师教学工作总结
2014/11/08 职场文书
2015年教研室工作总结范文
2015/05/23 职场文书
李强为自己工作观后感
2015/06/11 职场文书
大学生实习证明
2015/06/16 职场文书
公司食堂管理制度
2015/08/05 职场文书
三好学生主要事迹材料
2015/11/03 职场文书
个人售房合同协议书
2016/03/21 职场文书
详解Python中下划线的5种含义
2021/07/15 Python