Create PDFs Easily

published on May 18, 2015 in technical

Most of us developers have had to generate PDF files at some point in time. I recently used a very interesting library and I would like to share my experience about it in a few tutorials.

This first tutorial would introduce very basic concepts of the library, but before we go deeper, let’s go over my reasons to picking the jsPDF library.

Options

There are basically two big groups of options out in the wild: server side and client side.

First one is probably well known to many of you. In my case there was a limitation on the server side, namely it had to work with Node.js given that my stack uses Node.js on the backend. Given this limitation, I basically had the possibility of generating PDFs with Phantom.js by. From previous experience this was something I did not want to pick Phantom.js due to its poor output quality and its speed.

The client side version is not that well known given there are much less options which use this sort of implementation. One of them, and the one I opted for in the end is jsPDF.

Why client side?

I had a few reasons to go with this option, one of the strongest ones was the quality of the produced output. Another reason was that in case data needed for the PDF content is avalable on client side, there will be no need to get it from the server. The last one probably has some implications over scalability given client browser can pretty much scale to any extent.

Introduction to basic API

Now I would like to walk you all through a few simple examples on how to use the API specifically, creating a PDF document, specifying document format, adding pages of different types, adding text, colored text, paragraphs of text, adding shapes like rectangles, circles or triangles and finally images.

In the last post of this series I will also publish a GitHub repo with code examples, possibly even structured as one or more Angular directives.

PDF document, pages and page formats

The simplest way to create a PDF document is this

var doc = new jsPDF();

doc will contain a jsPDF instance initialized with default options. In case we want to customize your instance, then we do this

var doc = new jsPDF(orientation, unit, format);

In this case we have three options, orientation, unit and format where orientation is one of ‘portrait’ or ‘landscape’ (or shortcuts ‘p’ (Default), ‘l’), unit may be one of ‘pt’ (points), ‘mm’ (Default), ‘cm’, ‘in’, format is one of ‘a3’, ‘a4’ (Default), ‘a5’, ‘letter’, ‘legal’.
So in case we want a document that starts with an a4 page with point units and portrait format, we do this

var doc = new jsPDF('p', 'pt', 'a4');

When we want to add a page we do it like this

doc.addPage(format, orientation);

Parameter values are the same as in the case of the document creation.

Adding text

After we have created a PDF document, adding text is pretty simple, we do it like this

doc.text(20, 20, 'This is a title');

You might wonder instantly what the 20, 20 are, rightfully. Those are the coordinates that we place the text on. 0, 0 is at the top left of the page, x increasing to the right, y increasing to the bottom.

To provide font size and color, we something like this

doc.setFontSize(22);
doc.setTextColor(0, 255, 0);
doc.text(20, 20, 'This is a title');

where setTextColor sets the color of the text in RGB ranges.

For adding paragraphs, we use a small trick

var doc = new jsPDF();
var paragraph = "Longer paragraph of text wich
 we display over multiple lines";
var lines = doc.setFontType("normal")
    .setFontSize(12)
    .setTextColor(0)
    .splitTextToSize(paragraph, 50);
doc.text(20, 20, lines);

Most of this is probably already familiar, except for the splitTextToSize method, which works like this

splitTextToSize(paragraph, width)

where paragraph is the text you would like to display on multiple lines, width is the width of the block the paragraph should fit in.

Shapes

We can also add shapes like rectangles, triangles and circles. Here is the way of adding rectangles

doc.rect(x, y, width, height, style);

where the first four parameters are coordinates, the first two, then width and height of the desired rectangle. The style is a string which tells if we want to have stroke ‘S’, fill ‘F’ or both ‘FD’ displayed with the rectangle.

In case we want to have rounded corners dispayed, we use this syntax

doc.roundedRect(x, y, width, height, rx, ry, style);

where the first four parameters are the same as in the previous case, so is the style. The two new parameters are rx, which is the radius along x axis and ry which is the radius along y axis.

Triangles work the same way basically as rectangles, their syntax is very similar

doc.triangle(x1, y1, x2, y2, x3, y3, style);

where the first six parameters are the three pairs of corner coordinates and the last one is the same style parameter as in the case of the rectangles.

Images

Adding images is also pretty simple, the only additional step needed is including the addImage plugin, which is also part of the same GitHub repo.

doc.addImage(imageData, format, x, y, width, height);

where imageData is the base64encoded data of the image, format if one of ‘jpeg’, ‘jpg’, ‘png’. There is an easy way of retrieving image base64 string by using the HTML5 canvas element – I will show an example in the final GitHub repo with code samples.

Next tutorial

My next tutorial will show how to use the above knowledge to build a bit more complex content, like charts, centering text, calculating rendered text sizes and so.