How to Generate PDF in Node.js Using PDFKit
PDF (Portable Document Format) files remain a standard for sharing documents across different platforms and devices. For Node.js developers, PDFKit is a powerful library that allows you to generate PDFs programmatically with impressive flexibility and control. This comprehensive guide will walk you through everything you need to know about generating PDFs in Node.js using PDFKit.
What is PDFKit?
PDFKit is a JavaScript PDF generation library for Node.js and the browser that makes creating complex, multi-page, printable documents simple and accessible. It provides an intuitive API for creating documents with rich features.
Key features of PDFKit include:
- Vector graphics with HTML5 canvas-like API, SVG path parsing, and gradient support.
- Text handling with line wrapping, alignments, bulleted lists, and formatting options.
- Font embedding (including custom fonts).
- Image embedding supporting JPEG and PNG files.
- Annotations including links, notes, highlights, underlines, and more.
- AcroForms for interactive form creation.
- Document outlines for navigation.
- PDF security with encryption and access privilege controls.
- Accessibility support (marked content, logical structure, and Tagged PDF/UA).
PDFKit creates PDFs programmatically from scratch using JavaScript code – it is not an HTML to PDF converter. If you need to convert existing HTML pages to PDF, consider tools like Puppeteer or wkhtmltopdf instead.
Setting Up Your Environment
Let's start by setting up a Node.js project with PDFKit. Make sure you have Node.js installed on your system, then follow these steps:
1. Create a new directory for your project and navigate to it:
mkdir pdf-generator
cd pdf-generator
2. Initialize a new Node.js project:
npm init -y
3. Install PDFKit:
npm install pdfkit
For some features like image processing, you might need additional dependencies:
npm install pdfkit fs
4. Create a new JavaScript file (e.g., index.js
) for your PDF generation code.
Basic PDF Generation
Let's start with a simple example to create a basic PDF document:
// Import dependencies
const PDFDocument = require('pdfkit');
const fs = require('fs');
// Create a document
const doc = new PDFDocument();
// Pipe its output somewhere, like to a file
doc.pipe(fs.createWriteStream('output.pdf'));
// Add some content to the first page
doc.fontSize(25).text('Hello there!', 100, 100);
// Add some space between text blocks
doc.moveDown();
doc.text('Scroll down...')
// Add another page
doc.addPage()
.fontSize(25)
.text('Here is another page!', 100, 100);
// Finalize the PDF and end the stream
// This is important - without doc.end(), the PDF won't be properly created
doc.end();
When you run this script using node index.js
, it will generate a PDF file named output.pdf
in your project directory. The PDF will contain two pages with simple text content.
Working with Text
PDFKit provides extensive options for working with text, allowing you to control font size, style, alignment, and more.
Text Styling
// Set font size and font family
doc.font('Courier')
.fontSize(18)
.text('This is some styled text.');
// Add space between text blocks
doc.moveDown();
// Text styling: bold, italics, etc. (requires appropriate font)
doc.font('Courier-Bold').text('Bold text');
doc.font('Courier-Oblique').text('Italic text');
doc.moveDown();
// Text color can be changed using fillColor with color names or hex codes
doc.font('Courier') // Reset to regular font
.fillColor('blue').text('Blue text');
doc.fillColor('#FF0000').text('Red text');
doc.fillColor('green').text('Green text');
Here is the output:
Standard and Custom Fonts
PDFKit supports all 14 standard PDF fonts (Helvetica, Times, Courier, Symbol, and ZapfDingbats with their variations) without requiring embedding.
To use these standard fonts, simply call the font
method with the font name:
doc.fontSize(18);
// Standard fonts
doc.font('Helvetica')
.text('This text is in Helvetica font')
.moveDown(1);
doc.font('Times-Bold')
.text('This text is in Times-Bold font')
.moveDown(1);
doc.font('Courier-Oblique')
.text('This text is in Courier-Oblique font');
Here is the output:
For custom designs, PDFKit supports embedding TrueType (.ttf), OpenType (.otf), WOFF, WOFF2, TrueType Collection (.ttc), and Datafork TrueType (.dfont) fonts.
Below is an example with custom fonts:
// Load and use custom fonts from file
doc.font('fonts/Lato-Bold.ttf')
.text('This text is in Lato Bold font')
.moveDown(2);
doc.font('fonts/Nosifer-Regular.ttf')
.text('This text is in Nosifer Regular font')
.moveDown(1);
// Register a font with a name for easier reference later
doc.registerFont('MyFont', 'fonts/GloriaHallelujah-Regular.ttf');
// Use the registered font
doc.font('MyFont')
.text('This is in Gloria Hallelujah font registered as MyFont');
Here is the output:
You can easily integrate Google Fonts into your PDFs by following these steps:
- Visit Google Fonts - select and download your desired font (.ttf files).
- Create a fonts directory in your project for the font files.
- Place the downloaded fonts in your fonts directory.
- Register the fonts - use
registerFont()
to make them available to PDFKit. - Use in your document - reference them with the
font()
method.
Remember that embedding fonts increases file size, so use standard fonts for basic documents when possible.
Text Alignment and Positioning
doc.fontSize(18);
// Left aligned text (default)
doc.text('Left aligned text');
doc.moveDown();
// Center aligned text
doc.text('Center aligned text', {
align: 'center'
});
doc.moveDown();
// Right aligned text
doc.text('Right aligned text', {
align: 'right'
});
doc.moveDown();
// Justified text
doc.text('This text is justified. This text is justified. This text is justified. This text is justified. This text is justified. This text is justified.', {
align: 'justify'
});
doc.moveDown();
// Text at specific coordinates (x, y) from the top-left corner
doc.text('Positioned text', 100, 300);
Here is the output:
Lists
doc.fontSize(18);
// Create a simple bulleted list
doc.list(['Item 1', 'Item 2', 'Item 3'], 100, 100);
doc.moveDown();
// Create a list with custom options
doc.list(['First item', 'Second item', 'Third item'], {
bulletRadius: 2, // Radius of the bullet points
textIndent: 20, // Indentation of text from bullet
bulletIndent: 10 // Indentation of bullet from left margin
});
doc.moveDown();
// Create a multilevel list using nested arrays
doc.list([
'Main item 1',
[
'Sub item 1.1',
'Sub item 1.2',
[
'Sub-sub item 1.2.1',
'Sub-sub item 1.2.2'
]
],
'Main item 2',
[
'Sub item 2.1',
'Sub item 2.2'
]
]);
Here is the output:
Working with Colors and Gradients
Colors and gradients can add visual appeal to your PDFs. Here's how to use them:
// Add labels for each rectangle
doc.fontSize(14);
doc.text('Solid Color', 100, 80);
doc.text('Linear Gradient', 250, 80);
doc.text('Radial Gradient', 400, 80);
// Create a solid color-filled rectangle
// Parameters: x, y, width, height
doc.rect(100, 100, 100, 100).fill('blue');
// Create a rectangle with linear gradient fill
doc.rect(250, 100, 100, 100).fill(
doc.linearGradient(250, 100, 350, 200)
.stop(0, 'red')
.stop(1, 'yellow')
);
// Create a rectangle with radial gradient fill
doc.rect(400, 100, 100, 100).fill(
doc.radialGradient(450, 150, 0, 450, 150, 50)
.stop(0, 'yellow') // Inner color
.stop(1, 'green') // Outer color
);
Here is the output:
- The
doc.rect(x, y, width, height)
method creates a rectangle at position (x, y) with the specified width and height. - It returns the document object for chaining with other methods like
fill()
orstroke()
. - For more information, see the PDFKit Documentation.