jsPDF - Documentation

What is jsPDF?

jsPDF is a JavaScript library that allows you to generate PDF documents client-side in a web browser without requiring any server-side processing. It provides a comprehensive API for creating PDFs with text, images, lines, and more, offering a powerful and flexible solution for generating documents directly within your web applications. This eliminates the need to send data to a server for PDF generation, improving performance and user experience.

Why use jsPDF?

There are several compelling reasons to utilize jsPDF:

Setting up jsPDF

Integrating jsPDF into your project is straightforward. The most common method is via a CDN (Content Delivery Network) or by including the library directly from a downloaded package via npm or yarn.

CDN (Content Delivery Network): Include the jsPDF script tag in your HTML file’s <head> section:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>

npm/yarn: If you use npm or yarn for package management, install jsPDF using the following command:

npm install jspdf
// or
yarn add jspdf

Then, import it into your JavaScript code:

import jsPDF from 'jspdf';

Remember to consult the latest jsPDF documentation for the most up-to-date installation instructions and compatible versions.

Basic Usage Example

This example demonstrates creating a simple PDF with text:

import jsPDF from 'jspdf';

// Initialize jsPDF document
const doc = new jsPDF();

// Add text to the PDF
doc.text('Hello, world!', 10, 10);

// Save the PDF
doc.save('hello.pdf');

This code snippet initializes a new jsPDF document, adds the text “Hello, world!” at coordinates (10, 10) (in points), and then saves the document as “hello.pdf”. This provides a foundation upon which you can build more complex PDFs using the various features offered by the jsPDF library. Refer to the subsequent sections for details on adding images, drawing shapes, and customizing document properties.

Core Concepts

Document Object

The core of jsPDF is the jsPDF document object. This object represents the PDF document being created and provides the primary interface for manipulating its contents. It’s instantiated using the new jsPDF() constructor (or variations thereof, depending on options selected). All operations—adding text, images, drawing shapes, setting properties—are performed via methods called on this object. The document object manages page creation, content placement, and ultimately, the generation of the final PDF file. Key methods include those for adding content (e.g., text, addImage, line), setting document properties (e.g., setFontSize, setFont), and saving the document (e.g., save). Understanding the document object is crucial for effectively using jsPDF.

Pages and Page Sizes

A jsPDF document can consist of multiple pages. By default, a new document starts with a single page. You can add new pages using the addPage() method. jsPDF supports various standard page sizes (e.g., ‘a4’, ‘letter’, ‘legal’) which can be specified during document creation or when adding a new page. Custom page sizes can also be defined. Page dimensions are crucial for accurate content placement; understanding the coordinate system (discussed in the next section) is vital for positioning elements correctly on each page. Automatic page breaks are handled internally by jsPDF, ensuring content is appropriately distributed across pages.

Units and Coordinates

jsPDF uses points as its default unit of measurement. One point is approximately 1/72nd of an inch. Coordinates within the document are specified using a two-dimensional Cartesian system, with (0, 0) representing the top-left corner of the page. X-coordinates increase to the right, and Y-coordinates increase downwards. Therefore, (10, 10) represents a point 10 points from the left and 10 points from the top. While points are the default, you can change the unit of measurement using options during document initialization. Accurate positioning of elements requires a clear understanding of this coordinate system and the chosen unit of measurement.

Fonts and Text

jsPDF provides mechanisms for adding text to the PDF document. The text() method is the primary function for this purpose, taking text content and x, y coordinates as arguments. You can control text properties such as font size, font family, and style (bold, italic) using methods like setFontSize(), setFont(), and setFontStyle(). jsPDF includes a selection of built-in fonts; however, you can also add custom fonts for more precise control over typography. Managing text flow, including line breaks and text alignment, can be accomplished through various methods and careful consideration of coordinate placement.

Images and Graphics

jsPDF supports the inclusion of images within the generated PDF. The addImage() method is used to incorporate images from various sources (e.g., URLs, data URLs, or local files). You need to provide the image data, along with x, y coordinates for placement, and optionally specify image width and height. Supported image formats typically include JPEG, PNG, and GIF. Beyond images, jsPDF offers capabilities for drawing basic shapes (lines, rectangles, ellipses) and more complex graphical elements using methods like line(), rect(), ellipse(), and circle(). These functions allow for the creation of diagrams, charts, and other visual elements within the PDF document. Precise control over the appearance of graphics requires understanding the coordinate system and relevant properties.

Adding Text

Adding Simple Text

The most basic way to add text to a jsPDF document is using the text() method. This method takes the text string and x, y coordinates as its primary arguments. The coordinates specify the position of the baseline of the first character of the text.

const doc = new jsPDF();
doc.text('Hello, world!', 10, 10); // Text starts at x=10, y=10
doc.save('simple_text.pdf');

This code adds the text “Hello, world!” to the PDF, starting 10 points from the left edge and 10 points from the top edge of the page. Remember that the coordinate system uses points as the unit.

Text Alignment and Formatting

While the basic text() method places text at a specific point, jsPDF allows for alignment control. You can use the setFontSize() method to adjust the size of your text. For alignment, you typically need to use the getTextWidth() method along with manual coordinate adjustments to center or right-align text. There isn’t built-in left, center, right alignment in the simple text() function, so you will have to calculate the position yourself.

const doc = new jsPDF();
const text = "This text is centered";
const textWidth = doc.getTextWidth(text);
const x = (doc.internal.pageSize.getWidth() - textWidth) / 2; // Center calculation
doc.text(text, x, 20);
doc.setFontSize(20); // Increase font size
doc.text("Larger text", 10, 40);
doc.save('aligned_text.pdf');

This example centers the text horizontally. For right alignment, you would adjust the x calculation accordingly.

Line Breaks and Paragraphs

To create line breaks and paragraphs, you have several approaches. You can manually calculate positions for each line:

const doc = new jsPDF();
doc.setFontSize(12);
doc.text("This is line one.", 10, 20);
doc.text("This is line two.", 10, 30);
doc.save('line_breaks.pdf');

Or, you can use the setFontSize and text functions in a loop to create paragraphs with a set line height. Note that this requires managing line breaks yourself. There is no automated paragraph formatting.

Fonts and Styles

jsPDF supports various font styles and families. You can change the font using setFont() and modify the style (bold, italic) with setFontStyle(). The available fonts depend on the fonts embedded in the user’s browser and system, as well as any custom fonts you might add.

const doc = new jsPDF();
doc.setFont('helvetica', 'bold');
doc.setFontSize(16);
doc.text('Bold Helvetica Text', 10, 10);
doc.setFont('times', 'italic');
doc.text('Italic Times Text', 10, 30);
doc.save('fonts.pdf');

Adding Text with Specific Coordinates

Precise control over text placement is achieved by specifying the exact x and y coordinates when using the text() method. The coordinates refer to the bottom-left point of the first character. If you need more precise positioning, you can use the getTextWidth() method to determine the width of the text for horizontal alignment calculations. Likewise, you will need to manually account for line height when placing multiple lines of text vertically.

Working with Images

Adding Images from URLs

jsPDF allows you to add images directly from a URL. The addImage() method is the key function for this. You’ll need to provide the image URL, along with x and y coordinates for positioning, and optionally specify the image width and height.

const doc = new jsPDF();
doc.addImage('https://example.com/image.png', 'PNG', 10, 10, 50, 50); // x, y, width, height
doc.save('image_from_url.pdf');

This code snippet adds an image from https://example.com/image.png to the PDF. The image type (‘PNG’) must be specified. The parameters 10, 10 define the top-left corner coordinates, and 50, 50 set the width and height of the image in points. Note that if you don’t specify width and height, jsPDF will try to determine the dimensions from the image data, which may cause delays. It is generally good practice to specify these dimensions to avoid unexpected behavior.

Adding Images from Local Files

Adding images from local files is slightly more complex and generally requires data URLs. You cannot directly reference a file path from the client-side for security reasons. First, you need to read the image file using the browser’s FileReader API. Then convert it to a Data URL, and finally use that Data URL with addImage().

const doc = new jsPDF();
const fileInput = document.getElementById('imageInput'); // Assumes an input element with id 'imageInput'
fileInput.addEventListener('change', (e) => {
  const file = e.target.files[0];
  const reader = new FileReader();
  reader.onload = (readerEvent) => {
    const imgData = readerEvent.target.result;
    doc.addImage(imgData, 'PNG', 10, 10, 50, 50);
    doc.save('image_from_file.pdf');
  };
  reader.readAsDataURL(file);
});

This example uses a file input element to select an image. The FileReader reads the image file, and the onload event handler processes the data URL, adding the image to the PDF. Remember to add an appropriate <input type="file"> element to your HTML.

Image Scaling and Positioning

The addImage() method’s width and height parameters control the image’s size within the PDF. Omitting these parameters will result in the image being rendered at its original size. Accurate positioning requires carefully selecting the x and y coordinates. Experimentation or pre-calculation may be needed to achieve precise placement, especially when combining multiple images or text. Consider using the getImageProperties() method to get the image dimensions before adding the image, allowing for more precise scaling and positioning calculations.

Image Alignment

Similar to text alignment, jsPDF does not have built-in image alignment functions. To achieve centering or other alignment, you’ll need to manually calculate the x and y coordinates based on the image dimensions and the page size. This typically involves determining the center point of the page (or a specific area) and calculating the x and y offsets needed to place the image correctly. This requires using getImageProperties() to get the image dimensions and internal.pageSize.getWidth() and internal.pageSize.getHeight() for page dimensions.

Drawing and Shapes

Lines and Rectangles

jsPDF provides methods for drawing basic shapes like lines and rectangles. The line() method draws a line segment between two points, specified by their x and y coordinates. The rect() method draws a rectangle, requiring coordinates for the top-left corner, width, and height.

const doc = new jsPDF();
// Draw a line from (10, 10) to (100, 10)
doc.line(10, 10, 100, 10);
// Draw a rectangle at (20, 20) with width 50 and height 30
doc.rect(20, 20, 50, 30);
doc.save('lines_rects.pdf');

Remember that coordinates are specified in points. rect() draws the rectangle’s outline; to fill it, you’ll need to use the setFillColor() method before calling rect().

Circles and Ellipses

jsPDF doesn’t have dedicated circle() and ellipse() methods, but you can achieve similar results using the ellipse() method. This method requires the x and y coordinates of the center, the horizontal and vertical radii, and start and end angles (in radians). A circle is simply an ellipse with equal horizontal and vertical radii.

const doc = new jsPDF();
// Draw a circle with center at (50, 50) and radius 20
doc.ellipse(50, 50, 20, 20, 0, 2 * Math.PI);
//Draw an ellipse
doc.ellipse(120, 50, 30, 15, 0, 2 * Math.PI);
doc.save('circles_ellipses.pdf');

Again, setFillColor() can be used to fill the shape.

Polygons and Paths

For more complex shapes like polygons, you need to use a series of line segments. There’s no single polygon function. You would define the vertices and connect them using multiple calls to line(), or construct a path. For paths you can use lines() method to create a series of connected lines to form the polygon. You would have to close the path manually by drawing the line from the last point to the first point.

Styling Shapes

You can style shapes using methods like setLineWidth(), setDrawColor(), setFillColor(), and setDashPattern(). These methods control the line width, line color, fill color, and line style (e.g., dashed lines).

const doc = new jsPDF();
doc.setLineWidth(2); // Set line width to 2 points
doc.setDrawColor(255, 0, 0); // Set draw color to red
doc.rect(10, 10, 40, 40);
doc.setFillColor(0, 255, 0); // Set fill color to green
doc.rect(60, 10, 40, 40, 'F'); // Filled rectangle, 'F' for fill
doc.save('styled_shapes.pdf');

The ‘F’ in rect(..., 'F') indicates that the rectangle should be filled.

Using Custom Paths

For intricate shapes, jsPDF’s path drawing capabilities become vital. While not as feature-rich as dedicated vector graphics libraries, you can create complex shapes by manually specifying a series of points and commands (moveTo, lineTo, quadraticCurveTo, bezierCurveTo, arc, closePath) using the lines() method or related methods. This requires a more advanced understanding of vector graphics concepts. Each point and drawing operation needs to be defined explicitly. This level of control offers maximum flexibility, but requires a deeper dive into the lower-level drawing capabilities.

Advanced Features

Working with Tables

jsPDF doesn’t have a built-in table object, but you can create tables by manually positioning text and lines using the text() and line() methods, along with careful calculation of cell positions and sizes. Libraries like jsPDF-AutoTable are commonly used to simplify this process. They provide a higher-level abstraction for creating and managing tables, handling aspects like cell alignment, borders, and automatic page breaks. These libraries handle much of the complex coordinate calculations and layout management. If you choose not to use a third-party library, you must manually manage row and column positioning, including calculating widths and heights, applying borders, and handling page breaks when the table exceeds a single page.

jsPDF allows you to add links and annotations to your PDF documents. The link() method is used to create internal or external links. Annotations (like comments, highlights, etc.) typically require more advanced techniques and might necessitate the use of external libraries that extend jsPDF’s capabilities or direct manipulation of the PDF’s underlying structure (which is considerably more complex). Using a library tailored to this purpose would be more efficient and less error-prone. Basic internal links can be created by using the link() method with specific page and coordinate targets. External links would require you to specify a URL.

Document Metadata

Document metadata, such as the title, author, subject, and keywords, can be added using the setProperties() method. This information is stored within the PDF and can be accessed by PDF viewers. This metadata improves PDF searchability and organization.

const doc = new jsPDF();
doc.setProperties({
  title: 'My PDF Document',
  subject: 'A sample document',
  author: 'Your Name',
  keywords: 'jspdf, pdf, document'
});
// ... add content to the document ...
doc.save('metadata_example.pdf');

Page Headers and Footers

Adding headers and footers requires manual positioning of content on each page. You’ll need to use event listeners or callbacks that are triggered before each page is rendered. This allows you to add the header and footer content to each page individually using text() and related methods. Because jsPDF doesn’t handle page breaks automatically for headers and footers, you must track page numbers and adjust coordinates accordingly. The process involves using event listeners or custom functions that are executed before each page rendering, making sure to add header and footer content at the correct positions for every page.

Watermarks and Backgrounds

Adding watermarks or backgrounds involves adding an image or text behind the main content. This typically involves adding an image or text element using addImage() or text() with a lower opacity (alpha channel). The exact implementation depends on whether you are using an image watermark or text. For an image watermark you’ll need to adjust its opacity during the addImage function. For a text watermark you would likely need to adjust the opacity as well, and may need to repeat the text on multiple pages to ensure full coverage of the page. Positioning is crucial to overlay the watermark appropriately over the main content. Consider using a library that simplifies this if you are working with a complex watermark design.

PDF Manipulation

Merging PDFs

jsPDF itself does not directly support merging multiple PDF files. Merging PDFs typically requires a server-side solution or the use of external libraries that extend jsPDF’s capabilities or utilize other PDF manipulation libraries. Client-side merging of PDFs is significantly more complex due to the intricacies of the PDF file format. A common approach involves using a server-side language (like Node.js with a suitable library) to handle the merging process. The client-side would send the individual PDFs to the server, which would then perform the merge and return the combined PDF. Alternatively, third-party JavaScript libraries may offer client-side PDF merging functionality, but their capabilities and performance should be carefully evaluated.

Splitting PDFs

Similar to merging, splitting PDFs is not a built-in feature of jsPDF. The most straightforward approach is typically a server-side solution using a dedicated PDF library. Client-side splitting would involve parsing the PDF’s structure to identify page boundaries and extract individual pages as separate PDF files. This requires a deep understanding of the PDF format and is quite involved. If you require client-side splitting, consider using a library that provides this functionality; however, be aware that parsing a PDF client-side can be resource-intensive and may impact performance.

Adding Bookmarks

Adding bookmarks (outlines) to a PDF is not directly supported by the core jsPDF library. You will likely need to use a library that extends jsPDF or manipulate the PDF’s structure directly which is substantially complex. The complexity arises because you would need to understand and modify the PDF’s outline structure which is very intricate. Use of an appropriate third-party library is usually the recommended approach for adding bookmarks effectively. These libraries often provide higher-level functions to add bookmarks with associated destinations and titles.

Compressing PDFs

jsPDF doesn’t offer direct compression capabilities beyond what’s inherent in the PDF generation process. The resulting PDF’s size depends on various factors, including the amount and type of content (text, images, etc.) and the encoding used. Optimizing the size of images before inclusion in the PDF is crucial for reducing its overall file size. Using optimized image formats (like WebP) and reducing image resolution where possible can significantly decrease the file size. However, jsPDF doesn’t perform additional compression steps after the PDF is generated. Post-processing with a separate compression tool might be necessary for further size reduction if needed.

Protecting PDFs with Passwords

Password protection for PDFs is not a built-in feature of jsPDF. Implementing password protection requires modifying the PDF’s encryption settings, a task beyond the scope of the jsPDF library. This requires a server-side solution or a third-party library capable of handling PDF encryption. Client-side encryption of PDFs is a security risk and generally not recommended due to the ease with which client-side JavaScript code can be accessed and modified. A server-side approach offers better security. Therefore, use a server-side solution or a trusted third-party library that handles this securely.

Troubleshooting and Common Issues

Debugging jsPDF Code

Debugging jsPDF code involves standard JavaScript debugging techniques. Use your browser’s developer tools (usually accessed by pressing F12) to set breakpoints in your JavaScript code, step through the execution, inspect variables, and examine the console for errors. Pay close attention to error messages, as they often pinpoint the source of the problem. Console logging (console.log()) is invaluable for tracking variable values and the flow of execution. If using a module bundler (like Webpack or Parcel), ensure your configuration is correct and that jsPDF is properly included and imported into your code. For complex issues, consider using a debugger extension in your browser’s developer tools.

Common Errors and Solutions

Font Rendering Issues

Font rendering problems might be due to several factors:

Image Loading Problems

Issues with loading images usually stem from:

Performance Optimization

For performance optimization, consider the following:

Best Practices

Code Organization and Structure

Organize your jsPDF code into modular, reusable components. Avoid putting all your code into a single, large function. Break down complex tasks into smaller, more manageable functions. This improves readability, maintainability, and testability. Use meaningful variable and function names to enhance understanding. Consider using a module bundler (Webpack, Parcel, Rollup) to manage dependencies and structure your code effectively. This helps to separate concerns and organize your code in a more structured way. A well-structured project makes collaboration easier and reduces the risk of errors.

Error Handling

Implement robust error handling to gracefully handle potential issues during PDF generation. Use try...catch blocks to wrap potentially problematic code sections and handle exceptions appropriately. Log errors to the console (using console.error()) to aid debugging. Provide informative error messages to the user if necessary. Avoid crashing the application due to unexpected inputs or conditions. Thorough error handling makes your application more resilient and improves the user experience. Consider checking the validity of inputs and handling edge cases.

Performance Optimization Techniques

Performance is crucial, especially when generating large or complex PDFs. Here are some optimization techniques:

Accessibility Considerations

Accessibility is crucial for ensuring your PDFs are usable by everyone. Here are some important points:

Examples and Use Cases

Generating Invoices

jsPDF is well-suited for generating invoices. You can create a template with placeholders for invoice number, date, client information, items, and totals. Use text(), setFontSize(), setFontStyle(), and potentially line() to create the layout. Calculate totals and dynamically populate the placeholders with data from your application. Consider using a table library (like jsPDF-AutoTable) to streamline the creation of item tables. Ensure proper alignment and formatting for a professional-looking invoice. You might also include company logos using addImage().

Creating Certificates

Certificates often require a more visually appealing layout. Use addImage() to add a background image or logo. Employ text() to add the recipient’s name, certificate title, and date. Consider using different font sizes and styles (setFontSize(), setFontStyle()) to emphasize specific elements. You can add a signature image using addImage() and possibly create decorative borders or lines using line(), rect(), or more complex path drawing. For more complex designs, consider leveraging a templating engine or a library that enhances jsPDF’s graphical capabilities.

Building Reports

Reports frequently involve tabular data. A library like jsPDF-AutoTable is invaluable here. Populate the table with data from your application. Include headers and summaries. You might add charts or graphs (if your application provides them) using addImage(). Consider adding page numbers and a report title using text() with appropriate positioning. Ensure clear data representation and a logical structure for easy readability. You may need to handle page breaks gracefully when dealing with large datasets.

Exporting Data to PDF

Many applications benefit from exporting data to PDF. This commonly involves converting tabular data (e.g., from a database or spreadsheet) into a PDF document. A table library (jsPDF-AutoTable) simplifies this significantly. Fetch the data from your application’s data source. Format the data appropriately, handling any special formatting requirements. Use text() to add headers and any accompanying text. You could add filters or sorting mechanisms to allow users to customize the exported data. Consider including the date and time of export for provenance.

Custom PDF Templating

For complex and repetitive PDF generation, consider a templating approach. Create a template file (e.g., HTML or a custom format) that defines the PDF’s structure and placeholders for dynamic data. Your application would then populate these placeholders with data and use a templating engine or custom parser to generate the final PDF using jsPDF. This approach promotes code reusability and maintainability for generating PDFs with consistent layouts. Such an approach requires additional development effort but enhances consistency and efficiency. Consider using a client-side templating engine, but you may need to write some custom code to handle PDF-specific aspects like positioning.

API Reference

This section provides a concise overview of key jsPDF API methods. Refer to the complete jsPDF documentation for a comprehensive list and detailed explanations of all methods and their parameters. Note that the specific methods and their parameters might vary slightly depending on the jsPDF version.

Document Class Methods

Font and Style Methods

Image Methods

Shape Methods

Utility Methods

Note: This is not an exhaustive list. Consult the official jsPDF documentation for the complete API reference and detailed explanations of each method and its parameters. The specific methods and their availability may also depend on the version of jsPDF that you are using. Always refer to the documentation for the version you are actively working with.