基于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之文件操作
Mar 07 Javascript
js 判断浏览器类型 去全角、半角空格 自动关闭当前窗口
Apr 10 Javascript
情人节之礼 js项链效果
Feb 13 Javascript
JavaScript中的style.cssText使用教程
Nov 06 Javascript
js实现按钮控制图片360度翻转特效的方法
Feb 17 Javascript
在JavaScript中处理时间之setMinutes()方法的使用
Jun 11 Javascript
JQUERY表单暂存功能插件分享
Feb 23 Javascript
JavaScript制作简单分页插件
Sep 11 Javascript
Vue + Webpack + Vue-loader学习教程之功能介绍篇
Mar 14 Javascript
微信小程序scroll-view实现滚动穿透和阻止滚动的方法
Aug 20 Javascript
详解React项目如何修改打包地址(编译输出文件地址)
Mar 21 Javascript
JS如何实现在弹出窗口中加载页面
Dec 03 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调用Google translate_tts api实现代码
2013/08/07 PHP
PHPer 需要了解的 5 个 Composer 小技巧
2014/08/18 PHP
php删除txt文件指定行及按行读取txt文档数据的方法
2017/01/30 PHP
jquery 应用代码 方便的排序功能
2010/02/06 Javascript
javascript 内存回收机制理解
2011/01/17 Javascript
jquery淡化版banner异步图片文字效果切换图片特效
2014/04/08 Javascript
js变量、作用域及内存详解
2014/09/23 Javascript
使用jquery 简单实现下拉菜单
2015/01/14 Javascript
DOM基础教程之模型中的模型节点
2015/01/19 Javascript
JavaScript检测上传文件大小的方法
2015/07/22 Javascript
jquery实现全屏滚动
2015/12/28 Javascript
网页前端登录js按Enter回车键实现登陆的两种方法
2016/05/10 Javascript
浅谈vue的props,data,computed变化对组件更新的影响
2018/01/16 Javascript
关于TypeScript模块导入的那些事
2018/06/12 Javascript
微信小程序中使用ECharts 异步加载数据的方法
2018/06/27 Javascript
通过GASP让vue实现动态效果实例代码详解
2019/11/24 Javascript
Python struct.unpack
2008/09/06 Python
Python中文件遍历的两种方法
2014/06/16 Python
对Xpath 获取子标签下所有文本的方法详解
2019/01/02 Python
Python with语句和过程抽取思想
2019/12/23 Python
Python3.7安装PyQt5 运行配置Pycharm的详细教程
2020/10/15 Python
pycharm配置python 设置pip安装源为豆瓣源
2021/02/05 Python
纯css3实现图片翻牌特效
2015/03/10 HTML / CSS
H5 canvas中width、height和style的宽高区别详解
2018/11/02 HTML / CSS
2014端午节活动策划方案
2014/01/27 职场文书
工程招投标邀请书
2014/01/30 职场文书
生产部厂长职位说明书
2014/03/03 职场文书
如何写好建议书
2014/03/13 职场文书
借款担保书范文
2014/05/13 职场文书
幼儿生日活动方案
2014/08/27 职场文书
公司委托书格式范本
2014/09/16 职场文书
工作岗位职责范本
2015/02/15 职场文书
酒店辞职信怎么写
2015/02/27 职场文书
《我要的是葫芦》教学反思
2016/02/18 职场文书
标准演讲稿格式结尾应该怎么书写?
2019/07/17 职场文书
Python中文纠错的简单实现
2021/07/07 Python