Генерация PDF отчётов на JavaScript (Node.js): Puppeteer, PDFKit, jsPDF
Создание PDF-документов — одна из самых частых задач в веб-разработке. Отчёты, счета, сертификаты, документация — всё это требует надёжного инструмента для генерации файлов на серверной стороне. В экосистеме Node.js существует несколько мощных библиотек, каждая из которых решает задачу по-своему. В этой статье мы разберём три основных подхода: эмуляцию браузера через Puppeteer, низкоуровневую работу с PDF через PDFKit и клиент-серверное решение jsPDF.
1. Puppeteer — генерация PDF из HTML/CSS
Puppeteer — это библиотека для управления безголовым браузером Chromium. Она позволяет загрузить любую HTML-страницу, применить стили и «сфотографировать» её в PDF. Это идеальный выбор, если у вас уже есть вёрстка отчётов на HTML/CSS, и вы хотите получить точный перенос в PDF.
Основные возможности:
- Поддержка всех CSS-свойств (Flexbox, Grid, шрифты, тени).
- Работа с JavaScript на странице (графики Chart.js, таблицы с динамикой).
- Настройка формата, полей, колонтитулов, фонов.
- Поддержка пользовательских шрифтов (TTF, OTF).
Пример генерации отчёта:
const puppeteer = require('puppeteer');
async function generateReport() {
const browser = await puppeteer.launch();
const page = await browser.newPage();
// Загружаем HTML напрямую (или по URL)
await page.setContent(`
<html>
<head>
<style>
body { font-family: Arial; padding: 40px; }
h1 { color: #2c3e50; }
.data { background: #ecf0f1; padding: 20px; }
</style>
</head>
<body>
<h1>Отчёт о продажах</h1>
<div class="data">
<p>Выручка: 1 200 000 руб.</p>
<p>Количество заказов: 345</p>
</div>
</body>
</html>
`, { waitUntil: 'networkidle0' });
await page.pdf({
path: 'report.pdf',
format: 'A4',
printBackground: true,
margin: { top: '20mm', bottom: '20mm' }
});
await browser.close();
console.log('PDF создан!');
}
generateReport();
Плюсы: точность вёрстки, поддержка сложных макетов, работа с графиками.
Минусы: высокое потребление памяти (Chromium весит ~200 МБ), медленный запуск.
2. PDFKit — низкоуровневое создание PDF
PDFKit — это библиотека для прямого манипулирования PDF-структурой. Вы не используете HTML, а строите документ программно: рисуете линии, добавляете текст, вставляете изображения. Это даёт полный контроль над каждым пикселем документа.
Основные возможности:
- Векторная графика (линии, прямоугольники, кривые).
- Поддержка Unicode и встраивание шрифтов.
- Создание таблиц, нумерация страниц.
- Работа с аннотациями и ссылками.
Пример создания простого счёта:
const PDFDocument = require('pdfkit');
const fs = require('fs');
const doc = new PDFDocument({ size: 'A4', margin: 50 });
doc.pipe(fs.createWriteStream('invoice.pdf'));
// Заголовок
doc.fontSize(24).text('Счёт № 12345', { align: 'center' });
doc.moveDown();
// Таблица (вручную)
doc.fontSize(12).text('Наименование', 50, 150);
doc.text('Кол-во', 350, 150);
doc.text('Цена', 450, 150);
doc.moveTo(50, 170).lineTo(550, 170).stroke();
doc.text('Услуги разработки', 50, 180);
doc.text('1', 350, 180);
doc.text('150 000 руб.', 450, 180);
doc.moveDown(2);
doc.fontSize(16).text('Итого: 150 000 руб.', { align: 'right' });
doc.end();
Плюсы: лёгкий вес, высокая производительность, минимальные зависимости.
Минусы: сложность создания сложных макетов, ручная работа с позиционированием.