How To Create PDF Files In Javascript (Using Various Libraries)

Welcome to a tutorial on how to create PDF files in Javascript. Yes, creating PDF files is not limited to the server-side. Thanks to advancements in Javascript technologies, it is possible to create PDF files using Javascript – Let us walk through a few PDF libraries in this guide, read on!

ⓘ I have included a zip file with all the example source code at the start of this tutorial, so you don’t have to copy-paste everything… Or if you just want to dive straight in.

 

 

TABLE OF CONTENTS

Download & Notes PDF Libraries Useful Bits & Links
The End

 

DOWNLOAD & NOTES

Firstly, here is the download link to the example code as promised.

 

EXAMPLE CODE DOWNLOAD

Click here to download the source code, I have released it under the MIT license, so feel free to build on top of it or use it in your own project.

 

QUICK NOTES

  • The Javascript PDF libraries are not included in the zip file. Please visit the respective websites to get the latest versions.

If you spot a bug, please feel free to comment below. I try to answer questions too, but it is one person versus the entire world… If you need answers urgently, please check out my list of websites to get help with programming.

 

 

JAVASCRIPT PDF LIBRARIES

All right, let us now get into some examples and the various libraries to generate PDF files (not in any particular order).

 

1) PDF-LIB

WHERE TO GET IT

 

EXAMPLE USAGE – NODEJS

1a-pdf-lib.js
// (A) LOAD LIBRARIES
// FULL DOCUMENTATION: https://pdf-lib.js.org/
// npm i esm
// npm i pdf-lib
// node -r esm 1b-pdf-lib.js
import { PDFDocument, StandardFonts, rgb } from 'pdf-lib';
const fs = require("fs");

async function goPDF() {
  // (B) INIT PDF FILE
  let pdf = await PDFDocument.create(),
      page = pdf.addPage();

  // (C) DRAW TEXT
  let font = await pdf.embedFont(StandardFonts.TimesRoman),
      fontSize = 28,
      { width, height } = page.getSize();

  page.drawText('Hello World!', {
    x: 50,
    y: height - 4 * fontSize,
    size: fontSize,
    font: font,
    color: rgb(0, 0.53, 0.71),
  });

  // (D) WRITE TO FILE
  let saved = await pdf.save();
  fs.appendFile("hello-world.pdf", Buffer.from(saved), function (err) {
    if (err) {
      console.log(err);
    } else {
      console.log("ok");
    }
  });
}
goPDF();

 

EXAMPLE USAGE – WEB BROWSER

1b-pdf-lib.html
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf-lib/1.9.0/pdf-lib.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/downloadjs/1.4.8/download.min.js"></script>
<script>
// FULL DOCUMENTATION: https://pdf-lib.js.org/
const {PDFDocument, StandardFonts, rgb} = PDFLib;
async function goPDF() {
  // (A) INIT PDF FILE
  let pdf = await PDFDocument.create(),
      page = pdf.addPage();
 
  // (B) DRAW TEXT
  let font = await pdf.embedFont(StandardFonts.TimesRoman),
      fontSize = 28,
      { width, height } = page.getSize();
 
  page.drawText('Hello World!', {
    x: 50,
    y: height - 4 * fontSize,
    size: fontSize,
    font: font,
    color: rgb(0, 0.53, 0.71),
  });
 
  // (C) WRITE + FORCE DOWNLOAD
  let saved = await pdf.save();
  download(saved, "hello-world.pdf", "application/pdf");
}
</script>
<button onclick="goPDF()">Create PDF</button>

 

SOME NOTES & THOUGHTS

Yikes. The demo code on the official website does not work out-of-the-box, and NodeJS is still experimental in supporting ES Modules (at the time of writing). Took me quite a while to even get the basic “Hello World” to work properly. But that said, this library works just fine.

One thing turns me down though – I personally don’t like the way of how “Mathematical” it is. Even drawing a simple block of text with PDF-Lib is a pain in the… behind.

 

 

2) PDF KIT

WHERE TO GET IT

 

EXAMPLE USAGE – NODEJS

2a-pdf-kit.js
// (A) LOAD LIBRARIES
// FULL DOCUMENTATION: http://pdfkit.org/
// npm i pdfkit
const PDFDocument = require("pdfkit"),
      fs = require("fs");

// (B) CREATE NEW PDF
const doc = new PDFDocument();
doc.pipe(fs.createWriteStream("hello-world.pdf"));

// (C) WRITE TEXT
doc
  // .font('PATH/FONTS/FONT.TTF')
  .fontSize(25)
  .text('Hello World', 100, 100);

// (D) SAVE
doc.end();

 

EXAMPLE USAGE – WEB BROWSER

2b-pdf-kit.html
<!-- https://github.com/foliojs/pdfkit/releases -->
<script src="pdfkit.standalone.js"></script>
<!-- https://github.com/devongovett/blob-stream/releases -->
<script src="blob-stream.js"></script>
<script>
function goPDF () {
  // (A) CREATE NEW PDF
  let pdf = new PDFDocument(),
      stream = pdf.pipe(blobStream());

  // (B) WRITE SOMETHING
  pdf
    .fontSize(25)
    .text('Hello World', 100, 80);

  // (C) OUTPUT
  pdf.end();
  stream.on('finish', function() {
    document.getElementById("output").src = stream.toBlobURL('application/pdf');
  });
}
</script>

<iframe id="output" style="display:block; width:100%; height:300px"></iframe>
<button onclick="goPDF()">Create PDF</button>

 

SOME NOTES & THOUGHTS

The NodeJS version of this one is a total breeze. But the browser version took a while to figure out, with their “independent browser version”. Still, I will prefer this over PDF Lib above. This is just a lot more “human” and easier to work with.

 

 

3) PDF MAKE

WHERE TO GET IT

 

EXAMPLE USAGE – NODEJS

3a-pdf-make.js
// (A) INIT PDFMAKE
// FULL DOCUMENTATION: http://pdfmake.org/
// npm i pdfmake
const PdfPrinter = require('pdfmake'),
      fs = require('fs');

var printer = new PdfPrinter({
  Courier: {
    normal: 'Courier',
    bold: 'Courier-Bold',
    italics: 'Courier-Oblique',
    bolditalics: 'Courier-BoldOblique'
  }
});

// (B) CREATE PDF
var pdf = printer.createPdfKitDocument({
  content: [
    'Foo Bar',
    'Hello World',
  ],
  defaultStyle: {
    font: 'Courier'
  }
});

// (C) OUTPUT
pdf.pipe(fs.createWriteStream('hello-world.pdf'));
pdf.end();

 

EXAMPLE USAGE – WEB BROWSER

3b-pdf-make.html
<!-- https://cdnjs.com/libraries/pdfmake -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.68/pdfmake.min.js"></script>
<script>
function goPDF () {
  // (A) SET FONTS
  pdfMake.fonts = {
    Roboto: {
     normal: 'https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.66/fonts/Roboto/Roboto-Regular.ttf',
     bold: 'https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.66/fonts/Roboto/Roboto-Medium.ttf',
     italics: 'https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.66/fonts/Roboto/Roboto-Italic.ttf',
     bolditalics: 'https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.66/fonts/Roboto/Roboto-MediumItalic.ttf'
   }
  };

  // (B) CREATE + DOWNLOAD
  pdfMake
  .createPdf({
    content: [
      'Foo Bar',
      'Hello World',
    ],
    defaultStyle: {
      font: 'Roboto'
    }
  })
  .download('hello-world.pdf');
}
</script>

<button onclick="goPDF()">Create PDF</button>

 

SOME NOTES & THOUGHTS

Yikes, this is another one that did not quite work out of the box. Not too bad though, a little bit of digging, and I was able to get it to run as intended. Although it does seem to be rather naggy about the fonts at first, it really isn’t too bad nor confusing to use.

 

 

4) HTML2PDF

WHERE TO GET IT

 

EXAMPLE USAGE – WEB BROWSER

4-html2pdf.html
<!-- https://cdnjs.com/libraries/html2pdf.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.9.2/html2pdf.bundle.min.js"></script>
<script>
function goPDF () {
  html2pdf()
  .from(document.getElementById("topdf"))
  .save();
}
</script>

<div id="topdf">
  <strong>Foo Bar!</strong>
</div>
<button onclick="goPDF()">Create PDF</button>

 

SOME NOTES & THOUGHTS

While this one is a client-side library, but WOOHOO! We finally have a winner that is totally easy to use – Zero fuss. Just load the library and add a few lines of code.

 

 

USEFUL BITS & LINKS

That’s all for this guide, and here is a small section on some extras and links that may be useful to you.

 

WHICH IS THE BEST?

Personally, I am leaning towards HTML2PDF for the fastest deployment without suffering any brain damage. But if a server-side solution is required, I must say that I have not extensively tested any of the packages… So this is purely my personal preference – PDF kit.

 

LINKS & REFERENCES

 

THE END

Thank you for reading, and we have come to the end of this guide. I hope that it has helped you with your project, and if you want to share anything with this guide, please feel free to comment below. Good luck and happy coding!

Leave a Comment

Your email address will not be published. Required fields are marked *