Можно ли использовать PhantomJS и Node для динамического создания PDF файлов из шаблонов?
Фон/Потребность
Я работаю с группой в веб-приложении, используя Node.JS и Express. Мы должны иметь возможность создавать отчеты, которые могут быть напечатаны как печатные копии, так и печатные формы. Желательно, чтобы мы динамически генерировали PDF файлы на сервере как для отчетов, так и для письменных форм. В настоящее время мы используем шаблоны EJS на сервере.
Функции
Я думал, что было бы удобно иметь возможность использовать шаблоны, чтобы иметь возможность создавать формы/отчеты и генерировать PDF из полученного HTML, однако мои возможности сделать это кажутся ограниченными, насколько я могу найти. Я рассмотрел два разных возможных решения:
EDIT: Я нашел еще один модуль Node.JS, который может создавать PDF файлы из HTML под названием node -wkhtml, который опирается на wkhtmltopdf. Теперь я сравниваю использование node-phantom
и node-wkhtml
. Мне удалось создать PDF файлы на сервере Node с обоими из них, и они оба, похоже, способны делать то, что мне нужно.
Я видел несколько примеров использования PhantomJS для рендеринга PDF-документов с веб-сайтов, но все примеры, которые я видел, используют URL-адрес и не подают его в виде строки HTML. Я не уверен, могу ли я сделать эту работу с шаблонами, чтобы динамически генерировать отчеты в формате PDF.
Когда приходит запрос для отчета, я надеялся создать HTML из шаблона EJS и использовать его для создания PDF файла. В любом случае, для использования Phantom для динамического создания страницы на сервере без запроса?
Моим другим вариантом является использование PDFkit, который позволяет динамически генерировать PDF файлы, но это API-интерфейс, похожий на холст, и на самом деле не поддерживает какое-либо понятие шаблонов, насколько я могу судить.
Вопрос
Кто-нибудь знает, могу ли я использовать PhantomJS с Node для динамического создания PDF файлов из HTML, созданного с помощью шаблона? Или кто-нибудь знает какие-либо другие решения, которые я могу использовать для создания и обслуживания печатных отчетов/форм из моего Node/Express-back-end.
Ответы
Ответ 1
EJS работает нормально в PhantomJS (после установки модуля path
). Чтобы загрузить страницу в PhantomJS с помощью строки HTML, выполните page.content = '<html><head>...';
.
npm install ejs
и npm 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();
(Запустите это script с помощью phantomjs
, а не node
.)
Ответ 2
Я собираюсь опубликовать ответ для любого, кто пытается сделать что-то подобное с node-phantom
. Поскольку node-phantom
управляет локальной установкой PhantomJS, он должен использовать асинхронные методы для всего, даже если соответствующая операция PhantomJS является синхронной. При настройке содержимого страницы, которая будет отображаться в PhantomJS, вы можете просто:
page.content = '<h1>Some Markup</h1>';
page.render('page.pdf');
Однако, используя модуль node - phantom внутри node, вы должны использовать метод 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();
});
});
});
Ответ 3
Очень простое решение этой проблемы - модуль node-webshot - вы можете поместить raw html непосредственно в качестве аргумента, и он печатает pdf напрямую.