DevGang
Авторизоваться

Создание файлов PDF в Node.js с помощью PDFKit

Формат PDF - один из наиболее распространенных форматов документов для передачи информации. В динамических веб-приложениях вам может потребоваться экспортировать данные в документ, и PDF обычно является популярным вариантом. В этой статье мы обсудим, как сгенерировать файлы PDF в NodeJS с помощью пакета NPM pdfkit.

PDFKit - это библиотека для создания PDF- файлов на JavaScript для Node.js, которая обеспечивает простой способ создания многостраничных PDF-документов для печати.

Начало работы с PDFKit

Создадим каталог проекта и инициализируем проект Node с настройками по умолчанию:

$ mkdir pdfkit-project
$ cd pdfkit-project
$ npm init -y

Затем давайте выполним install pdfkit:

$ npm install pdfkit

Чтобы использовать модуль в проекте, мы импортируем его через require():

const PDFDocument = require('pdfkit');

Создание PDF-документа с помощью PDFKit

Чтобы создать PDF-документ, нам также потребуется импортировать модуль fs (файловой системы). Мы передадим содержимое нашего PDF-файла в записываемый поток fs, чтобы сохранить его. Давайте посмотрим, как это сделать:

const PDFDocument = require('pdfkit');
const fs = require('fs');

let pdfDoc = new PDFDocument;
pdfDoc.pipe(fs.createWriteStream('SampleDocument.pdf'));
pdfDoc.text("My Sample PDF Document");
pdfDoc.end();

Сначала мы импортируем необходимые модули, после чего создаем экземпляр PDFDocument. Этот экземпляр является читаемым потоком. Мы направим этот поток в записываемый поток, чтобы сохранить файл.

Для этого мы используем функцию pipe() и сохраняем результат в нашем корневом каталоге в SampleDocument.pdf. После создания мы можем добавить к нему содержимое с помощью функции text.

Когда мы запускаем код, в корневой папке нашего проекта создается файл PDF с именем SampleDocument.pdf:

$ node index.js

Примечание. Прежде чем пытаться перезаписать существующий файл PDF, он должен быть свободным. Т.е. все окна с этим файлом PDF должны быть закрыты, иначе программа выдаст ошибку.

Форматирование текста в PDF файле

Конечно, pdfkit позволяет нам делать гораздо больше, чем просто добавлять в документ неформатированный текст. Давайте посмотрим на некоторые функции, которые он предлагает.

Размещение текста

По умолчанию модуль pdfkit отслеживает, где текст должен быть добавлен в документ, по сути, печатает каждый вызов функции text() в новой строке.

Вы можете изменить место печати текста на текущей странице, добавив координаты x и y того места, где вы хотите разместить текст, в качестве аргументов функции text().

Например:

pdfDoc.text("Text positioned at (200,200)", 200, 200);

Это полезно, потому что позволяет точно настроить расположение текста, тем более что документы PDF имеют универсальный вид независимо от машины / ОС, на которой они открываются. Это также позволит вам, например, печатать текст поверх другого текста:

const PDFDocument = require('pdfkit');
const fs = require('fs');

var pdfDoc = new PDFDocument;
pdfDoc.pipe(fs.createWriteStream('SampleDocument.pdf'));

pdfDoc.text("From Mon-Sat we will have a 10% discount on selected items!", 150, 150);
pdfDoc
    .fillColor('red')
    .fontSize(17)
    .text("20%", 305, 150);

pdfDoc.end();

Запуск этого кода даст нам:

Перенос текста и выравнивание

Модуль pdfkit автоматически обертывает строки так, чтобы они помещались между полями или в предоставленных width (при написании текста в Столбцах). Другими словами, параметр lineBreak установлен в true по умолчанию. Вы можете изменить его на false при вызове функции text():

pdfDoc.text("very long text ".repeat(20), { lineBreak : false });

Новые страницы также добавляются автоматически по мере необходимости, т.е. как только контент, который вы хотите добавить, не помещается на текущей странице целиком. Однако вы также можете переключиться на следующую страницу перед заполнением предыдущей, просто выполнив:

pdfDoc.addPage();

Что касается выравнивания, в pdfkit нам доступны обычные параметры - left (по умолчанию) right, center и justify. Обратите внимание, что установка определенного выравнивания с lineBreak установленным как false не будет работать, даже если текст может уместиться в строку.

Точно так же параметр align устанавливается путем передачи в функцию text()  объекта, содержащего пары ключ-значение. Давайте посмотрим на несколько примеров выравнивания:

const PDFDocument = require('pdfkit');
const fs = require('fs');

var pdfDoc = new PDFDocument;
pdfDoc.pipe(fs.createWriteStream('text_alignment.pdf'));

pdfDoc.text("This text is left aligned", { align: 'left'})
pdfDoc.text("This text is at the center", { align: 'center'})
pdfDoc.text("This text is right aligned", { align: 'right'})
pdfDoc.text("This text needs to be slightly longer so that we can see that justification actually works as intended", { align: 'justify'})

Выполнение приведенного выше кода даст нам PDF-файл, который выглядит следующим образом:

Стилизация текста

Модуль pdfkit также обеспечивает опции, которые могут быть использованы для стилизации текста в PDF - документах. Мы рассмотрим некоторые из наиболее важных опций стилизации, полный список опций вы можете найти в руководстве.

Мы можем передать функции text() различные параметры в виде пар ключ-значение, а также связать несколько других функций перед вызовом text().

Очень важно отметить, что такие функции как fillColor() (и позже font(), fontSize() и т.д.) будут воздействовать все вызовы text() после этого вызова:

const PDFDocument = require('pdfkit');
const fs = require('fs');

var pdfDoc = new PDFDocument;
pdfDoc.pipe(fs.createWriteStream('text_styling.pdf'));

pdfDoc
    .fillColor('blue')
    .text("This is a link", { link: 'https://pdfkit.org/docs/guide.pdf', underline: true });
pdfDoc
    .fillColor('black')
    .text("This text is underlined", { underline: true });
pdfDoc.text("This text is italicized", { oblique: true });
pdfDoc.text("This text is striked-through", { strike: true });

pdfDoc.end();

При запуске этого кода будет создан файл PDF со следующим содержанием:

Изменение стилей в середине абзаца немного сложнее, поскольку при объединении нескольких функций text() в цепочку по умолчанию добавляется новая строка после каждой. Мы можем избежать этого, установив для параметр lineBreak первого вызова text() в false:

const PDFDocument = require('pdfkit');
const fs = require('fs');

var pdfDoc = new PDFDocument;
pdfDoc.pipe(fs.createWriteStream('text_styling2.pdf'));

pdfDoc
    .fillColor('blue')
    .text("This text is blue and italicized", {oblique : true, lineBreak : false})
    .fillColor('red')
    .text(" This text is red");

pdfDoc.end();

Что даст нам желаемый результат:

Создание списков

Чтобы добавить список элементов в документ PDF, в экземпляре PDFDocument есть функция list(), которая принимает массив строковых элементов (или вложенные массивы строк) и отображает их в виде маркированного списка:

const PDFDocument = require('pdfkit');
const fs = require('fs');

let pdfDoc = new PDFDocument;
pdfDoc.pipe(fs.createWriteStream('lists.pdf'));

let myArrayOfItems = ['Item 1', 'Item 2', 'Item 3', 'Item 4'];

pdfDoc.list(myArrayOfItems);
// Move down a bit to provide space between lists
pdfDoc.moveDown(0.5);

let innerList = ['Nested Item 1', 'Nested Item 2'];
let nestedArrayOfItems = ['Example of a nested list', innerList];

pdfDoc.list(nestedArrayOfItems);

pdfDoc.end();

Что дает нам:

Шрифты

PDFKit поставляется с 14 стандартными шрифтами, которые можно использовать в документах PDF. Любой из этих шрифтов можно передать функции font() класса PDFDocument и связать с text():

pdfDoc.font('Times-Roman').text('A text in Times Roman')

Вы также можете добавить дополнительные шрифты, передав путь к файлу шрифта в качестве аргумента функции font(), а также имя конкретного шрифта, который вы хотите, если в файле есть набор шрифтов. В качестве альтернативы вы можете дать новому шрифту имя, чтобы к нему можно было получить доступ по этому имени, а не по пути к файлу:

pdfDoc.registerFont('Name of the font', '/file_path', 'specific_font_name_in_case_of_a_collection')

Вызовы font() могут быть связаны с другими функциями, как в примере c fillColor().

Вы также можете установить размер шрифта с помощью функции fontSize(). Давайте посмотрим на несколько примеров:

const PDFDocument = require('pdfkit');
const fs = require('fs');

let pdfDoc = new PDFDocument;
pdfDoc.pipe(fs.createWriteStream('fonts.pdf'));

pdfDoc.font('ZapfDingbats').text('This is a symbolic font.');
pdfDoc.font('Times-Roman').fontSize(25).fillColor('blue').text('You can set a color for any font');
pdfDoc.font('Courier').fontSize(5).fillColor('black').text('Some text to demonstrate.');

pdfDoc.end();

Запуск этого даст нам следующий PDF-файл в качестве вывода:

Добавление изображений

Еще одна распространенная вещь, которую вы можете добавить в свои PDF-файлы, - это изображения. Вы можете вызвать функцию image() в экземпляре документа и передать путь или URI изображения, которое вы хотите включить.

Вы также можете установить такие параметры, как ширина, высота, горизонтальное и вертикальное выравнивание изображения, передав объект, содержащий пары ключ-значение, в качестве аргумента функции image(). По умолчанию изображения загружаются в исходном размере.

Если вы установите width и height- изображение будет растянуто, чтобы соответствовать указанным параметрам. Если один из них не указан, изображение масштабируется пропорционально указанному параметру:

const PDFDocument = require('pdfkit');
const fs = require('fs');

let pdfDoc = new PDFDocument;
pdfDoc.pipe(fs.createWriteStream('images.pdf'));

pdfDoc.text('By default, the image is loaded in its full size:')
pdfDoc.image('raspberries.jpg');

pdfDoc.moveDown(0.5)
pdfDoc.text('Scaled to fit width and height')
pdfDoc.image('raspberries.jpg', {width: 150, height: 150});

pdfDoc.moveDown(0.5)
pdfDoc.text('Scaled to fit width')
pdfDoc.image('raspberries.jpg', {width: 150});

pdfDoc.end();

Запуск этого кода даст нам:

Вы также можете масштабировать изображение, задав коэффициент scale. Кроме того, вы можете указать массив fit или cover, в котором изображение будет масштабировано, чтобы соответствовать предоставленному прямоугольнику или покрывать его, соответственно. Если вы предоставляете массив fit или cover, вы также можете установить горизонтальное выравнивание (align) и вертикальное выравнивание (valign):

const PDFDocument = require('pdfkit');
const fs = require('fs');

let pdfDoc = new PDFDocument;
pdfDoc.pipe(fs.createWriteStream('images.pdf'));

pdfDoc.text('Scaled by a factor, keeps the original proportions:')
pdfDoc.image('raspberries.jpg', {scale: 0.75});

pdfDoc.moveDown(0.5)
pdfDoc.text('Fit with horizontal alignment:')
pdfDoc.image('raspberries.jpg', {fit: [400, 150], align: 'center'});

pdfDoc.end();

Это даст нам:

Вывод

В этой статье мы увидели, как создавать PDF-файлы в Node.js с помощью PDFKit. Мы изучили некоторые варианты форматирования текста и способы добавления изображений в наши файлы. В библиотеке есть обширная документация, которая намного больше охватывает создание файлов PDF в приложениях Node.js.

Источник:

#JavaScript #NodeJS
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

Поделитесь своим опытом, расскажите о новом инструменте, библиотеке или фреймворке. Для этого не обязательно становится постоянным автором.

Попробовать

Оплатив хостинг 25$ в подарок вы получите 100$ на счет

Получить