Генерация PDF отчётов на TypeScript: библиотека pdf-lib

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Генерация PDF отчётов на TypeScript с библиотекой pdf-lib

В современной веб-разработке часто возникает необходимость создавать документы в формате PDF — от простых чеков и квитанций до сложных аналитических отчётов с графиками. TypeScript, как строго типизированное расширение JavaScript, предоставляет отличные возможности для работы с PDF. Среди множества библиотек выделяется pdf-lib — мощный, полностью клиентский инструмент, не требующий серверных зависимостей.

В этой статье мы подробно разберём, как использовать pdf-lib для генерации PDF-отчётов на TypeScript, включая установку, базовые операции и продвинутые приёмы.

Что такое pdf-lib?

pdf-lib — это библиотека с открытым исходным кодом, написанная на TypeScript, которая позволяет создавать и редактировать PDF-документы прямо в браузере или в среде Node.js. Её главные преимущества:

  • Полная поддержка TypeScript (все типы включены)
  • Работа без внешних зависимостей (нет необходимости в Puppeteer или wkhtmltopdf)
  • Возможность работы с существующими PDF (слияние, вставка страниц)
  • Поддержка кириллицы и любых шрифтов
  • Встраивание изображений (PNG, JPG, SVG)
  • Создание форм и аннотаций

Установка и настройка

Установка производится стандартным менеджером пакетов:

npm install pdf-lib
# или
yarn add pdf-lib

Для работы с TypeScript дополнительных действий не требуется — все типы уже включены в пакет.

Базовый пример: создание простого отчёта

Рассмотрим создание минимального PDF-документа с заголовком и текстом:

import { PDFDocument, StandardFonts, rgb } from 'pdf-lib';

async function createSimpleReport() {
  // 1. Создаём новый PDF-документ
  const pdfDoc = await PDFDocument.create();
  
  // 2. Добавляем страницу (формат A4: 595.28 x 841.89 пунктов)
  const page = pdfDoc.addPage([595.28, 841.89]);
  
  // 3. Подключаем стандартный шрифт
  const font = await pdfDoc.embedFont(StandardFonts.Helvetica);
  
  // 4. Рисуем заголовок
  page.drawText('Отчёт о продажах за Q1 2025', {
    x: 50,
    y: 800,
    size: 24,
    font: font,
    color: rgb(0, 0.2, 0.6),
  });
  
  // 5. Рисуем основной текст
  page.drawText('Общая выручка: 1 234 567 руб.', {
    x: 50,
    y: 760,
    size: 14,
    font: font,
    color: rgb(0, 0, 0),
  });
  
  // 6. Сохраняем документ в Uint8Array
  const pdfBytes = await pdfDoc.save();
  return pdfBytes;
}

Работа с таблицами и данными

Для создания табличных отчётов потребуется немного больше логики. Вот пример генерации таблицы с данными:

import { PDFDocument, StandardFonts, rgb } from 'pdf-lib';

interface SaleRecord {
  product: string;
  quantity: number;
  price: number;
}

async function createTableReport(data: SaleRecord[]) {
  const pdfDoc = await PDFDocument.create();
  const page = pdfDoc.addPage([595.28, 841.89]);
  const font = await pdfDoc.embedFont(StandardFonts.Helvetica);
  const boldFont = await pdfDoc.embedFont(StandardFonts.HelveticaBold);
  
  const startX = 50;
  let startY = 800;
  const rowHeight = 25;
  const colWidths = [200, 100, 100, 100]; // Наименование, Кол-во, Цена, Сумма
  
  // Заголовок таблицы
  const headers = ['Наименование', 'Количество', 'Цена', 'Сумма'];
  page.drawText(headers[0], { x: startX, y: startY, size: 12, font: boldFont });
  page.drawText(headers[1], { x: startX + colWidths[0], y: startY, size: 12, font: boldFont });
  page.drawText(headers[2], { x: startX + colWidths[0] + colWidths[1], y: startY, size: 12, font: boldFont });
  page.drawText(headers[3], { x: startX + colWidths[0] + colWidths[1] + colWidths[2], y: startY, size: 12, font: boldFont });
  
  startY -= rowHeight;
  
  // Строки данных
  for (const record of data) {
    const total = record.quantity * record.price;
    page.drawText(record.product, { x: startX, y: startY, size: 11, font });
    page.drawText(String(record.quantity), { x: startX + colWidths[0], y: startY, size: 11, font });
    page.draw                    

Рекомендаций