All posts
Published in nodejs

How to Create and Modify PDF Files With pdf-lib

Profile image of Atakan Demircioğlu
By Atakan Demircioğlu
Fullstack Developer

In this post, we will cover how to modify an existing PDF using JavaScript with PDF-lib. Specifically, we’ll generate a QR code and insert it into a PDF.

I selected one of the simplest libraries named qrcode. There are multiple types of generation but I preferred the PNG response for adding my PDF easily.

import QRCode from "qrcode";export const generateQR = async text => {
  try {
    const response = await QRCode.toDataURL(text);
    return response;
  } catch (err) {
    console.error(err)
  }
}

How to modify existing PDFs with NodeJS?

When I started to research, I just saw that finding a library to read existing PDFs is hard. Most libraries are designed for creating new PDFs.

For archiving this I used PDF-lib. This package allows you to modify existing PDFs and also create new PDFs.

Let’s read the existing PDF file;

const existingPdfBytes = await fsPromises.readFile('YOUR_FILE.pdf');
const pdfDoc = await PDFDocument.load(existingPdfBytes);

After that let’s add a new page to our PDF and add a generated QR

// adding new page

const page = pdfDoc.addPage();
// generate qr

const qrResponse = await generateQR('https://www.google.com');
// embed qr

const qrImage = await pdfDoc.embedPng(qrResponse);const { height } = page.getSize();page.drawImage(qrImage, {
  x: 50,
  y: height - 300,
  width: 200,
  height: 200,
});
const pdfBytes = await pdfDoc.save();
fs.writeFileSync('qr.pdf', pdfBytes);

In summary, we are creating a QR Code that goes to google.com. After the generation, we draw the QR Code to our existing PDF with the page.drawImage method.

Note: Also If you want to create an empty new PDF you can use it like this;

const pdfDoc = await PDFDocument.create();
pdfDoc.addPage();

 

You can find the full code here;

 

import fs from 'fs';
import fsPromises from 'fs/promises';
import { PDFDocument } from "pdf-lib";
import QRCode from "qrcode";
export const generateQR = async text => {
  try {
    const response = await QRCode.toDataURL(text);
    return response;
  } catch (err) {
    console.error(err)
  }
}
const existingPdfBytes = await fsPromises.readFile('qr.pdf');
const pdfDoc = await PDFDocument.load(existingPdfBytes);
const page = pdfDoc.addPage();
const qrResponse = await generateQR('https://www.google.com');
const qrImage = await pdfDoc.embedPng(qrResponse);
const { height } = page.getSize();
page.drawImage(qrImage, {
  x: 50,
  y: height - 300,
  width: 200,
  height: 200,
});
const pdfBytes = await pdfDoc.save();
fs.writeFileSync('qr.pdf', pdfBytes);