Вступление
Формат PDF - один из наиболее распространенных форматов документов для
передачи информации. В динамических веб-приложениях вам может
потребоваться экспортировать данные в документ, и PDF обычно является
популярным вариантом. В этой статье мы обсудим, как создавать PDF-файлы
в NodeJS с помощью пакета NPM pdfkit
.
PDFKit - это библиотека для создания PDF-файлов на JavaScript для Node.js, которая обеспечивает простой способ создания многостраничных PDF-документов для печати.
Начало работы с PDFKit
Создадим каталог проекта, cd
в него и инициализируем проект 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
. Этот экземпляр является читаемым потоком. Мы направим
этот поток в записываемый поток, чтобы сохранить файл.
Если вы не знакомы с тем, как работают потоки, ознакомьтесь с нашим введением в Node.js Streams .
Для этого мы используем pipe()
и сохраняем полученный
SampleDocument.pdf
в нашем корневом каталоге. После создания мы можем
добавить к нему содержимое с помощью text
функции. Конечно, мы захотим
в конце завершить поток end()
Когда мы запускаем код, в корневой папке нашего проекта создается
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();
Запуск этого кода даст нам:
{.ezlazyload}
Перенос текста и выравнивание
Модуль pdfkit
автоматически переносит строки так, чтобы они помещались
между полями или по width
(при написании текста в столбцах). Другими
словами, для параметра lineBreak
по умолчанию установлено значение
true
Вы можете изменить его на false
при вызове функции text()
:
pdfDoc.text("very long text ".repeat(20), { lineBreak : false });
Новые страницы также добавляются автоматически по мере необходимости, т. Е. Как только контент, который вы хотите добавить, не помещается на текущей странице целиком. Однако вы также можете переключиться на следующую страницу перед заполнением предыдущей, просто позвонив:
pdfDoc.addPage();
Что касается выравнивания, pdfkit
предоставляет нам обычные параметры
left
(по умолчанию),right
, поcenter
и поjustify
. Обратите внимание, что установка определенного выравнивания с параметромlineBreak
установленным наfalse
, не будет работать, даже если текст может уместиться в строке.
Как и lineBreak
, 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'})
pdfDoc.end();
Выполнение приведенного выше кода даст нам PDF-файл, который выглядит следующим образом:
{.ezlazyload}
Стилизация текста
Модуль pdfkit
также предоставляет параметры, которые можно
использовать для стилизации текста в ваших PDF-документах. Мы рассмотрим
некоторые из наиболее важных вариантов стилизации, полный список которых
вы можете найти в Руководстве в формате PDF .
Мы можем передать различные параметры в виде пар ключ-значение функции
text()
, а также связать несколько других функций перед вызовом
text()
вообще.
Очень важно отметить, что связанные функции, такие как fillColor()
(а
затем font()
, fontSize()
и т. Д.), Будут влиять на весь текст
после этого вызова:
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-файла со следующим содержанием:
{.ezlazyload}
Изменение стилей в середине абзаца немного сложнее, поскольку
объединение нескольких 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();
Что даст нам желаемый результат:
{.ezlazyload}
Создание списков
Чтобы добавить список элементов в документ 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();
Что дает нам:
{.ezlazyload}
Шрифты
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()
могут быть связаны с другими функциями, как в
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-файл в качестве вывода:
{.ezlazyload}
Добавление изображений
Еще одна распространенная вещь, которую вы можете добавить в свои
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();
Запуск этого кода даст нам:
{.ezlazyload}
Вы также можете масштабировать изображение, задав коэффициент 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();
Это даст нам:
{.ezlazyload}
Заключение
В этой статье мы увидели, как сгенерировать PDF-файлы в Node.js с помощью PDFKit. Мы изучили некоторые варианты форматирования текста и способы добавления изображений в наши файлы. В библиотеке есть обширная документация , в которой гораздо больше говорится о создании файлов PDF в приложениях Node.js.