基于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 相关文章推荐
cookie 最近浏览记录(中文escape转码)具体实现
Jun 08 Javascript
Javascript学习笔记之函数篇(五) : 构造函数
Nov 23 Javascript
JavaScript生成的动态下雨背景效果实现方法
Feb 25 Javascript
JavaScript简单获取页面图片原始尺寸的方法
Jun 21 Javascript
Javascript实现图片懒加载插件的方法
Oct 20 Javascript
整理一些最近经常遇到的前端面试题
Apr 25 Javascript
详解webpack性能优化——DLL
Oct 20 Javascript
浅谈实现vue2.0响应式的基本思路
Feb 13 Javascript
Angular模版驱动表单的使用总结
May 05 Javascript
简谈创建React Component的几种方式
Jun 15 Javascript
《javascript设计模式》学习笔记五:Javascript面向对象程序设计工厂模式实例分析
Apr 08 Javascript
JS实现移动端可折叠导航菜单(现代都市风)
Jul 07 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
example1.php
2006/10/09 PHP
PHP 获取目录下的图片并随机显示的代码
2009/12/28 PHP
PHP获取文件的MD5值并判断是否被修改的例子
2014/06/19 PHP
PHP结合Mysql数据库实现留言板功能
2016/03/04 PHP
搭建PhpStorm+PhpStudy开发环境的超详细教程
2020/09/17 PHP
js模拟实现Array的sort方法
2007/12/11 Javascript
使用JS进行目录上传(相当于批量上传)
2010/12/05 Javascript
JavaScript中的toLocaleDateString()方法使用简介
2015/06/12 Javascript
Node.js中的process.nextTick使用实例
2015/06/25 Javascript
jQuery mobile转换url地址及获取url中目录部分的方法
2015/12/04 Javascript
基于JavaScript实现简单的随机抽奖小程序
2016/01/05 Javascript
基于jQuery实现仿搜狐辩论投票动画代码(附源码下载)
2016/02/18 Javascript
jQuery控制div实现随滚动条滚动效果
2016/06/07 Javascript
Ext JS动态加载JavaScript创建窗体的方法
2016/06/23 Javascript
ionic cordova一次上传多张图片(类似input file提交表单)的实现方法
2016/12/16 Javascript
详解vue-meta如何让你更优雅的管理头部标签
2018/01/18 Javascript
玩转Koa之koa-router原理解析
2018/12/29 Javascript
JS数据类型判断的几种常用方法
2020/07/07 Javascript
three.js 利用uv和ThreeBSP制作一个快递柜功能
2020/08/18 Javascript
js实现点击按钮随机生成背景颜色
2020/09/05 Javascript
ant design的table组件实现全选功能以及自定义分页
2020/11/17 Javascript
Vue+scss白天和夜间模式切换功能的实现方法
2021/01/05 Vue.js
[54:06]OG vs TNC 2018国际邀请赛小组赛BO2 第二场 8.19
2018/08/21 DOTA
Python+django实现文件上传
2016/01/17 Python
Python正则表达式知识汇总
2017/09/22 Python
Numpy数组的保存与读取方法
2018/04/04 Python
Python网络编程之TCP套接字简单用法示例
2018/04/09 Python
Django高级编程之自定义Field实现多语言
2019/07/02 Python
Python3自动生成MySQL数据字典的markdown文本的实现
2020/05/07 Python
大学生实习思想汇报
2014/01/12 职场文书
致1500米运动员广播稿
2014/02/07 职场文书
新闻学专业大学生职业生涯规划范文
2014/03/02 职场文书
2014报到证办理个人委托书
2014/10/08 职场文书
信息技术教研组工作总结
2015/08/13 职场文书
八年级英语教学反思
2016/02/15 职场文书
总结Java对象被序列化的两种方法
2021/06/30 Java/Android