Custom PDF viewer using javascript

Posted By :Jayant Singh Parmar |28th February 2019

Hi everyone, in this blog, we will learn how to show a PDF document on a web page. We will not only load a PDF file into a web page but also create pagination if it is a multi-page PDF document and also display an error message if a PDF file not found. In this little project, we will use pdf.js to create our custom pdf view interface and pagination using javascript. We will be using modern syntaxes such as arrow functions and promises. So we will keep it very very simple, we will create our script, our HTML, and a little bit of CSS for the file navigation part and showing error messages. So let's get started and create a project structure as listed below.

PDF_viewer (project root)

  • index.html
  • docs
    • sample.pdf
  • css
    • style.css
  • js
    • main.js

and that should be for our structure.

We will also use font-awesome so you can quickly grab the CDN.

Now head over to your index.html and add the following code.

        <!DOCTYPE html>
        <html lang="en">
        <head>
            <meta charset="UTF-8" />
            <meta name="viewport" content="width=device-width, initial-scale=1.0" />
            <meta http-equiv="X-UA-Compatible" content="ie=edge" />
            <link
            rel="stylesheet"
            href="https://use.fontawesome.com/releases/v5.7.2/css/all.css"
            integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr"
            crossorigin="anonymous"
            />
            <link rel="stylesheet" href="css/style.css" />
            <title>PDF Viewer</title>
        </head>
        <body>
            <div class="top-bar">
            <button class="btn" id="prev-page">
                <i class="fas fa-arrow-circle-left"></i> Prev Page
            </button>
            <button class="btn" id="next-page">
                Next Page <i class="fas fa-arrow-circle-right"></i>
            </button>
            <span class="page-info">
                Page <span id="page-num"></span> of <span id="page-count"></span>
            </span>
            </div>

            <canvas id="pdf-render"></canvas>

            <script src="https://mozilla.github.io/pdf.js/build/pdf.js"></script>
            <script src="js/main.js"></script>
        </body>
        </html>
    

At this point, we have not added any CSS. We will do that last. So let's jump into our main.js and add the following code.

        const url = '../docs/pdf.pdf';

        let pdfDoc = null,
            pageNum = 1,
            ageIsRendering = false,
            pageNumIsPending = null;
            
        const scale = 1.5,
            canvas = document.querySelector('#pdf-render'),
            ctx = canvas.getContext('2d');
            
        // Render the page
        const renderPage = num => {
            pageIsRendering = true;
            
            // Get page
            pdfDoc.getPage(num).then(page => {
                // Set scale
                const viewport = page.getViewport({ scale });
                canvas.height = viewport.height;
                canvas.width = viewport.width;
            
                const renderCtx = {
                  canvasContext: ctx,
                  viewport
                };
            
                page.render(renderCtx).promise.then(() => {
                  pageIsRendering = false;
            
                  if (pageNumIsPending !== null) {
                    renderPage(pageNumIsPending);
                    pageNumIsPending = null;
                  }
                });
            
                // Output current page
                document.querySelector('#page-num').textContent = num;
            });
        };
            
        // Check for pages rendering
        const queueRenderPage = num => {
            if (pageIsRendering) {
                pageNumIsPending = num;
            } else {
                renderPage(num);
            }
        };
            
        // Show Prev Page
        const showPrevPage = () => {
            if (pageNum <= 1) {
                return;
            }
            pageNum--;
            queueRenderPage(pageNum);
        };
            
        // Show Next Page
        const showNextPage = () => {
            if (pageNum >= pdfDoc.numPages) {
                return;
            }
            pageNum++;
            queueRenderPage(pageNum);
        };
            
        // Get Document
        pdfjsLib
            .getDocument(url)
            .promise.then(pdfDoc_ => {
                pdfDoc = pdfDoc_;
            
                document.querySelector('#page-count').textContent = pdfDoc.numPages;
            
                renderPage(pageNum);
            })
            .catch(err => {
                // Display error
                const div = document.createElement('div');
                div.className = 'error';
                div.appendChild(document.createTextNode(err.message));
                document.querySelector('body').insertBefore(div, canvas);
                // Remove top bar
                document.querySelector('.top-bar').style.display = 'none';
            });
            
        // Button Events
        document.querySelector('#prev-page').addEventListener('click', showPrevPage);
        document.querySelector('#next-page').addEventListener('click', showNextPage);            
    

So at this point, everything will be working well. Now we will move on to our styling, so let's head over to your style.css and add the following rules.

            * {
                margin: 0;
                padding: 0;
              }
              
              .top-bar {
                background: #333;
                color: #fff;
                padding: 1rem;
              }
              
              .btn {
                background: coral;
                color: #fff;
                border: none;
                outline: none;
                cursor: pointer;
                padding: 0.7rem 2rem;
              }
              
              .btn:hover {
                opacity: 0.9;
              }
              
              .page-info {
                margin-left: 1rem;
              }
              
              .error {
                background: orangered;
                color: #fff;
                padding: 1rem;
              }    
    

So from now on, if you have to include a pdf on your website or on your application, you can embed it however you want and have a UI of whatever kind you want which comes in really handy. So that's it for now, I hope you find it useful to implement in a real website or application. 

 


About Author

Jayant Singh Parmar

Jayant is self taught UI Developer having some experience in designing UI for web applications. His skillset includes HTML, CSS, Bootstrap, Javascript & jquery.

Request For Proposal

Sending message..

Ready to innovate ? Let's get in touch


Notice: Undefined index: HTTP_REFERER in /var/html/www/AI/wp-content/themes/oxides-child/functions.php on line 272

Notice: Undefined index: HTTP_REFERER in /var/html/www/AI/wp-content/themes/oxides-child/functions.php on line 272

Notice: Undefined index: HTTP_REFERER in /var/html/www/AI/wp-content/themes/oxides-child/functions.php on line 272

Notice: Undefined index: HTTP_REFERER in /var/html/www/AI/wp-content/themes/oxides-child/functions.php on line 272

Chat With Us