16

背景/需要

我正在与一个使用 Node.JS 和 Express 的 Web 应用程序组合作。我们需要能够生成可以打印为硬拷贝和硬拷贝表格的报告。最好我们希望在服务器上为报告和手写表单动态生成 PDF。我们目前在服务器上使用 EJS 模板。

选项

我在想能够使用模板来构建表单/报告并从生成的 HTML 生成 PDF 会很方便,但是据我所知,我这样做的选择似乎有限。我研究了两种不同的可能解决方案:

编辑:我发现了另一个 Node.JS 模块,它能够从名为node-wkhtml的 HTML 生成 PDF,它依赖于wkhtmltopdf。我现在正在比较使用node-phantomand node-wkhtml。我已经能够使用这两种方法在 Node 服务器上生成 PDF,而且它们似乎都能满足我的需求。

我已经看到了一些使用 PhantomJS 从网站呈现 PDF 文档的示例,但是我看到的所有示例都使用 URL 并且不向其提供 HTML 字符串。我不确定是否可以使用模板来动态生成 PDF 报告。

当收到报告请求时,我希望从 EJS 模板生成 HTML,并使用它来生成 PDF。无论如何,我是否可以使用 Phantom 在服务器上完全动态创建页面而无需发出请求?

我的另一个选择是使用允许动态生成 PDF 的 PDFkit,但它是一个类似于画布的 API,据我所知,它并不真正支持任何模板概念。

问题

有谁知道我是否可以使用 PhantomJS 和 Node 从模板生成的 HTML 动态生成 PDF?或者有谁知道我可以用来从我的 Node/Express 后端生成和提供可打印报告/表单的任何其他解决方案。

4

3 回答 3

7

我将为任何试图做类似事情的人发布一个答案node-phantom。因为node-phantom控制 PhantomJS 的本地安装,所以即使对应的 PhantomJS 操作是同步的,它也必须对所有内容使用异步方法。当设置要在 PhantomJS 中呈现的页面内容时,您可以简单地执行以下操作:

page.content = '<h1>Some Markup</h1>';
page.render('page.pdf');

但是,使用 node 中的 node-phantom 模块,您必须使用该page.set方法。这是我在下面使用的代码。

'use strict';

var phantom = require('node-phantom');

var html = '<!DOCTYPE html><html><head><title>My Webpage</title></head>' +
    '<body><h1>My Webpage</h1><p>This is my webpage. I hope you like it' +
    '!</body></html>';

phantom.create(function (error, ph) {
    ph.createPage(function (error, page) {
        page.set('content', html, function (error) {

            if (error) {
                console.log('Error setting content: %s', error);
            } else {
                page.render('page.pdf', function (error) {
                    if (error) console.log('Error rendering PDF: %s', error);
                });
            }

            ph.exit();
        });
    });
});
于 2013-10-22T15:39:29.793 回答
7

EJS 似乎在 PhantomJS 中运行良好(安装path模块后)。要在给定 HTML 字符串的 PhantomJS 中加载页面,请执行page.content = '<html><head>...';.

npm install ejsnpm install path然后:

var ejs = require('ejs'),
    page = require('webpage').create();

var html = ejs.render('<h1><%= title %></h1>', {
    title: 'wow'
});

page.content = html;
page.render('test.pdf');
phantom.exit();

phantomjs(使用,而不是运行此脚本node。)

于 2013-10-21T20:45:29.647 回答
5

这个问题的一个非常简单的解决方案是node-webshot模块 - 您可以将原始 html 作为参数直接放入并直接打印 pdf。

于 2014-01-11T21:37:00.463 回答