使用NodeJS,Jade和PhantomJS创建PDF

时间:2015-03-21 16:03:46

标签: css node.js pdf phantomjs pug

我想使用PhantomJS从Jade中的模板创建PDF,我可以创建PDF文档,但是CSS没有应用,我创建了两个路由,第一个路由将模板渲染到Web浏览器,第二个生成de PDF与完全相同的玉石模板,在浏览器中都是正确的,但PDF不适用CSS。

我的app.js是:

var express = require('express'),
    routes = require('./routes'),
    http = require('http'),
    path = require('path'),
    bodyParser = require('body-parser');

var app = express();

app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(express.static(path.join(__dirname, 'public')));

app.post('/api/cotizacion/generar', routes.cotizacion.generar);
app.get('/api/cotizacion/generar', routes.cotizacion.testGenerar);

app.all('*', function(req, res) {
    res.send(404);
});

http.createServer(app).listen(app.get('port'), function(){
    console.info('Express server listening on port ' + app.get('port'));
});

控制器文件是cotizacion.js:

var phantom = require('phantom');

exports.generar = function(req, res, next){
    if(!req.body.cotizacion){
        return next(new Error('No se enviaron datos de cotización'));
    }

    var cotizacion = req.body.cotizacion;

    req.app.render('test', {cotizacion: cotizacion}, function(err, html){
        generarPDF(cotizacion, html, function(){
            res.send("1");
        });
    });
};

exports.testGenerar = function(req, res, next){
    res.render('test', {});
};

generarPDF = function(cotizacion, html, callback){
    phantom.create(function(ph){
        ph.createPage(function(page){
            page.set('paperSize', { format: 'Letter' });
            page.set('content', html);
            page.render(__dirname + '/test.pdf', function(err){
                ph.exit();
                callback();
            }); 
        });
    });
}

最后我的test.jade是:

doctype html

html
    head
        title Cotización PDF
        link(rel='stylesheet', href='/css/pdf.css')

    body
        h1 Test

以下作品,但有点烦人

doctype html

html
    head
        title Cotización PDF
        | <style type="text/css">
        |   body{ color: green; }
        | </style>

    body
        h1 Test

项目结构是:

/
   app.js
   public/
      css/
         pdf.css
   routes/
      index.js
      cotizador.js
   views/
      test.jade

1 个答案:

答案 0 :(得分:0)

好的,这是我们针对类似问题的解决方案。在JADE模板下面,注意hrefs并引用JSON对象属性:

doctype html
html(lang="en")
  head
    link(rel='stylesheet', type="text/css", media="all", href=report.statics.bootstrap)
    link(rel='stylesheet', type="text/css", media="all", href=report.statics.custom)
  body

这是一段代码片段,用于向模板提供CSS路径:

var createStatics = function (req) {
  var hostName = url.format({protocol: req.protocol,
    host: req.get('host')
  });
  return {
    bootstrap: hostName + '/assets/reports/bootstrap-report.css',
    custom: hostName + '/assets/reports/custom.css',
  }
}

接下来是JADE模板编译:

var fn = jade.compile(template);

运输对象,用于JADE模板实用程序对象所需的传递:

  var report = {
    statics: statics,
    title: 'Simple report title'
  };

呈现HTML报告并以流形式检索...

  var output = fn({
    report: report
  });