PDF.js library is a great open source tool supported by Mozilla. It’s main purpose is to display PDF files over Web (HTML5). You can display files on the canvas or use a sample viewer that converts PDF documents into DOM elements. In this article, I’ll show how to create a simple PDF viewer using canvas and PDF.js.


Introduction to PDF.JS

A general-purpose, web standards-based platform for parsing and rendering PDFs. PDF.js is a Portable Document Format (PDF) viewer that is built with HTML5. PDF.js is community-driven and supported by Mozilla Labs.

Download PDFjs Demonstration GitHub Project

A nice youtube presentation by one of PDF.js contributor Julian Viereck follows:

Click on button below for a cool guide on usage of PDF.js in your webpage.

GitHub Project


Using PDF.JS Library

You can download the library from mozilla website and see an example demo here. The only two files that you need are:

  • pdf.js
  • pdf.worker.js

You have to include them in your main html document in the order as shown above.

  <script src="js/pdf.js"></script>
  <script src="js/pdf.worker.js"></script>

The PDF.js library has a built in file loader, so you don’t have to worry about loading. First, you have to disable the file stream reading, which is the experimental feature introduced by Mozilla.

PDFJS.disableStream = true;

The next thing is opening a PDF document.

PDFJS.getDocument('/files/mydemo.pdf');

The engine loading is done using an asynchronous XMLHttpRequest. Normally we would use a callback to listen for the loaded/completed event, however in the PDF.js library we use Promises.

Promises are a great way to deal with asynchronous code. You can find many great articles about the Promises. So, this is how to respond to the loaded/completed event to fetch the first page

PDFJS.getDocument('/files/mydemo.pdf').then(function(pdf) {
  // Do fetch the first page with the PDF file stored in the `pdf` variable
});

Using Canvas

To display PDF file on the canvas we have to get the desired page from the pdf. This is shown below:

PDFJS.getDocument('/files/mydemo.pdf').then(function(pdfFile) {

    //We use the getPage function from the pdfFile variable, passing page number as a first argument. 
    var pageNumber = 1;
    pdfFile.getPage(pageNumber).then(function(page) 
    {    
        // We need to get the viewport to display.
        var scale = 1;
        var viewport = page.getViewport(scale);
        
        //Now we can display the page on the canvas.
        var canvas = document.getElementById('canvas');
        var context = canvas.getContext('2d');
        
        var renderContext = {
            canvasContext: context,
            viewport: viewport
        };
        
        page.render(renderContext);
    });
});

The Final Code

Final code for page is as shown below

$(document).load(function() {
  //
  // If absolute URL from the remote server is provided, configure the CORS
  // header on that server.
  //
  var url = './mydmo.pdf';

  //
  // Disable workers to avoid yet another cross-origin issue (workers need
  // the URL of the script to be loaded, and dynamically loading a cross-origin
  // script does not work).
  //
  // PDFJS.disableWorker = true;

  //
  // The PDFJS property shall be specified.
  //
  PDFJS.workerSrc = 'pdf.worker.js';
  PDFJS.imageResourcesPath = './images/';
  PDFJS.cMapUrl = './cmaps/';
  
  //
  // Asynchronous download PDF
  //
  PDFJS.getDocument(url).then(function getPdfHelloWorld(pdf) {
    //
    // Fetch the first page
    //
    pdf.getPage(1).then(function getPageHelloWorld(page) {
      var scale = 1.5;
      var viewport = page.getViewport(scale);

      //
      // Prepare canvas using PDF page dimensions
      //
      var canvas = document.getElementById('idPushPDFHere');
      var context = canvas.getContext('2d');
      canvas.height = viewport.height;
      canvas.width = viewport.width;

      //
      // Render PDF page into canvas context
      //
      var renderContext = {
        canvasContext: context,
        viewport: viewport
      };
      page.render(renderContext);
    });
  });
});  

Code In Action

Embed In Action