Wkhtmltopdf + Node.JS

Створення pdf документів є досить поширеною завданням. З нею успішно справляється ціле сімейство бібліотек, що дозволяють буквально «зібрати» pdf по частинах або ж заповнити його на основі заздалегідь приготованого шаблону. Даний підхід надійний, т. до. ми можлива розраховувати на те, що, змінивши текст одного напису, не зникне пагинация на деяких сторінках. З іншого боку додавання нових сторінок pdf займає певний час у розробника і, чим більше різних візуальних елементів, тим більше часу на це йде.

Однак, є й інший шлях створення pdf документів: конвертування з деякого мови розмітки за допомогою відповідного інструменту. Даний спосіб буде ефективним і займе менше часу на внесення змін в pdf, коли вибраний інструмент працює досить передбачувано. Існує кілька подібних рішень, але на нашому проекті ми зупинили свій вибір на Wkhtmltopdf, яке генерує pdf документ з HTML. Через рік використання даного інструменту можу сказати, що вибір був зроблений правильний, оскільки всі потреби були покриті з головою.

У даній статті я хочу поділитися бібліотеками, що дозволяють спростити роботу з wkhtmltopdf в Node.JS.

На даний момент існує кілька пакетів в npm, що дозволяють інтегрувати wkhtmltopdf. Проте вони мають свої мінуси:
  1. Всі опції до wkhtmltopdf передаються у вигляді об'єкта. Опцій у wkhtmltopdf дійсно багато і потрібно постійно курсувати між документацією та кодом, щоб сформувати правильний об'єкт, тому хотілося б мати підказки від IDE при заколнении опцій.
  2. Не весь функціонал wkhtmltopdf покритий большинстом бібліотек. Наприклад, не скрізь є можливість формування pdf документів з декількох джерел HTML або немає можливості конфігурувати гененируемое змісту (table of contents)


В результаті були розроблені бібліотеки wkhtmltopdf-nodejs-options-wrapper, яка є обгорткою для wkhtmltopdf параметрів, і wkhtmltopdf-nodejs-pdfapi, призначена для створення pdf документів.

Розглянемо приклад їх використання:

var wkhtmlToPdfOptions = require('wkhtmltopdf-nodejs-options-wrapper'),
PdfApi = require('wkhtmltopdf-nodejs-pdfapi');

var pdfApi = new PdfApi(),
request = new wkhtmlToPdfOptions.CreateRequest();

//Додамо головну сторінку гугла
var googlePage = new wkhtmlToPdfOptions.Page();
googlePage.setInput('http://google.com');

//Додамо головну сторінку хабра
var habrPage = new wkhtmlToPdfOptions.Page();
habrPage.setInput('http://habrahabr.ru');
habrPage.getOptions().setZoom(0.5); //зменшуємо масштаб до 50%

request.addPage(googlePage);
request.addPage(habrPage);
request.getGlobalOptions().setImageDpi(300); //встановимо дозвіл завантажуваних зображень в 300dpi
request.getHeadersAndFooterOptions().setFooterCenter('Footer text'); //у футері буде виводиться даний текст

//метод createPdf запустить команду створення pdf і поверне promise 
pdfApi.createPdf(request, 'result.pdf')
.then(function(data, debug) {
console.log('Pdf документ готовий');
}, function(data, debug) {
console.log('помилка:' + data);
});


Як видно з прикладу — для створення pdf документа необхідно створити об'єкт CreateRequest, заповнити її потрібними даними та передати у pdfApi.

IDE (WebStorm в моєму випадку) підказує які методи можна використовувати: image



Цього функціонала вже достатньо для використання на сервері, але було б ще корисніше мати можливість запуску створення pdf з клієнта. Для цього нам необхідно мати веб-сервіс, який би брав запити і віддавав готові pdf файли.

В якості такого сервісу можна скористатися WebSocket сервером wkhtmltopdf-nodejs-ws-server, який легко запускається наступним чином:

var WsServer = require('wkhtmltopdf-nodejs-ws-server');
var server = new WsServer(3000); // <- сервер "слухати" запити за адресою *:3000
server.start();

Клієнтський код може виглядати наступним чином:

//необхідно скористатися webpack або browserify, щоб підключити бібліотеки з допомогою <b>require</b>
var wkhtmlToPdf = require('wkhtmltopdf-nodejs-options-wrapper'),
io = require('socket.io-client');

var socket = io('http://ip_адрес_сервера:3000');

var page = new wkhtmlToPdf.Page(),
request = new wkhtmlToPdf.CreateRequest();

page.setInput('http://google.com'); //знову згенеруємо pdf з головної сторінки гугла

request.addPage(page);
request.getGlobalOptions().setPageSize('Letter');

socket.on('pdf:create:success', function(response) {
console.log('Pdf created: http://ip_адрес_сервера:3000/result_' + response.handle + '.pdf');
});

socket.on('pdf:create:fail', function(response) {
console.log('Pdf creation failed!');
console.log(response);
});

socket.emit('create', request.toObject());


Всі. Цього вже достатньо для створення pdf документів.

Сподіваюся, npm пакети і приклади, наведені в статті, будуть корисні.

Дякую за увагу.

P. S. Документація: wkhtmltopdf-nodejs-options-wrapper wkhtmltopdf-nodejs-pdfapi, wkhtmltopdf-nodejs-ws-server

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.