Skip to content

Instantly share code, notes, and snippets.

@fcingolani
Created August 9, 2012 02:16
Show Gist options
  • Star 80 You must be signed in to star a gist
  • Fork 22 You must be signed in to fork a gist
  • Save fcingolani/3300351 to your computer and use it in GitHub Desktop.
Save fcingolani/3300351 to your computer and use it in GitHub Desktop.
How to render a full PDF using Mozilla's pdf.js
<html>
<body>
<!-- really dirty! this is just a test drive ;) -->
<script type="text/javascript" src="https://raw.github.com/mozilla/pdf.js/gh-pages/build/pdf.js"></script>
<script type="text/javascript">
function renderPDF(url, canvasContainer, options) {
var options = options || { scale: 1 };
function renderPage(page) {
var viewport = page.getViewport(options.scale);
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
var renderContext = {
canvasContext: ctx,
viewport: viewport
};
canvas.height = viewport.height;
canvas.width = viewport.width;
canvasContainer.appendChild(canvas);
page.render(renderContext);
}
function renderPages(pdfDoc) {
for(var num = 1; num <= pdfDoc.numPages; num++)
pdfDoc.getPage(num).then(renderPage);
}
PDFJS.disableWorker = true;
PDFJS.getDocument(url).then(renderPages);
}
</script>
<div id="holder"></div>
<script type="text/javascript">
renderPDF('sample.pdf', document.getElementById('holder'));
</script>
</body>
</html>
@nikhilreddy93
Copy link

How can i get the page number of the page which is clicked? here is my code
$("div").click(function() { PDFJS.getDocument(url) .then(function(pdf) { pdf.getPage(2).then(function(page) { console.log('pagenum1 = '+page.pageIndex); }); });

@santasachin
Copy link

How to get HTML5 code from the pdf file?

@gregdorian
Copy link

Hmm ....and how Make this with jQuery and Modal Boostrap?

@SupFrig
Copy link

SupFrig commented Aug 3, 2017

Using this snippet the pages of my PDF are not rendering in chronogical order, the first page that is ready is rendering first so the pdf order is kinda random. Any trick to avoid this behaviour ?

@SupFrig
Copy link

SupFrig commented Aug 3, 2017

my terrible fix for my issue with pdf pages rendering in wrong order. The use of interval make it longer to render, if someone has a better fix i'll take it

function renderPages(pdfDoc) {

            var maxIterations = pdfDoc.numPages + 1;
            var intervalIterator = 1;

            var i = window.setInterval(function(){
                pdfDoc.getPage(intervalIterator).then(renderPage);
                intervalIterator += 1;

                if(maxIterations == intervalIterator){
                    window.clearInterval(i);
                }
            },50);
            
        }

@ChristianFlack
Copy link

my terrible fix for my issue with pdf pages rendering in wrong order. The use of interval make it longer to render, if someone has a better fix i'll take it

@SupFrig
The issue is that all pages are rendered simultaneously. To render them in order, you could use ES6 Promises or a promise library like kriskowal's Q.

An example implementation would be:

// [...] renderPage implementation stays the same

var renderPageFactory = function (pdfDoc, num) {
    return function () {
        return pdfDoc.getPage(num).then(renderPage);
    };
};

var renderPages = function (pdfDoc) {
    var renderedPage = $q.resolve();
    for (var num = 1; num <= pdfDoc.numPages; num++) {
    	// Wait for the last page t render, then render the next
        renderedPage = renderedPage.then(renderPageFactory(pdfDoc, num));
    }
};

@dardinier
Copy link

my terrible fix for my issue with pdf pages rendering in wrong order. The use of interval make it longer to render, if someone has a better fix i'll take it

@SupFrig & @ChristianFlack

I found another solution.

First, I create my canvas and then I render the page passing the canvas as argument. That way, you get all canvas ordered and you load the page in the right canvas !

Here's the code :

function renderPDF (url) {
  PDFJS.getDocument(url).then((pdf) => {
    for (let i = 1; i <= pdf.numPages; i += 1) {
      const canvas = document.createElement('canvas');
      /* This indentify the canvas as the location of the page */
      canvas.id = i;
      document.getElementById('pdf-viewer').appendChild(canvas);
      pdf.getPage(i).then((page) => {
        renderPage(page, canvas);
      }
    }
  });
}

renderPage(page, canvas) {
  const viewport = page.getViewport(1);
  const canvasContext = canvas.getContext('2d');
  const renderContext = {
    canvasContext,
    viewport
  };
  canvas.height = viewport.height;
  canvas.width = viewport.width;
  page.render(renderContext);
}

@DevKamran
Copy link

asdasdasd

@mandy6720
Copy link

mandy6720 commented Feb 8, 2018

Couldn't you also use Promise.all()?

renderPages() {
  const pagePromises = [];
  PDFJS.getDocument(url).then((pdf) => {
    for (let i = 1; i <= pdf.numPages; i += 1) {
      // Push the promises into promise array
      pagePromises.push(pdf.getPage(i));
    }
    // When loop finishes, call Promise.all() to 
    // wait until all promises resolve and returns 
    // results array
    Promise.all(pagePromises).then((resultsArr) => {
      // render pdf pages
    })
  });
}

Since the promises are pushed into the promise array in the correct order, they would render in the correct order :)

@Sreekanthp74
Copy link

How can I get an editable PDF in the canvas using pdfjs?

@WilsonYesidRiveraCasas
Copy link

Hi, I have a problem.
index.html:34 Uncaught ReferenceError: PDFJS is not defined at renderPDF (index.html:34) at index.html:43 renderPDF @ index.html:34 (anonymous) @ index.html:43

Line 34:

PDFJS.disableWorker = true;

Here's the code :

<html>
<body>

<!-- really dirty! this is just a test drive ;) -->

<script type="text/javascript" src="pdf.js"></script>
<script type="text/javascript">
function renderPDF(url, canvasContainer, options) {

    var options = options || { scale: 1 };
        
    function renderPage(page) {
        var viewport = page.getViewport(options.scale);
        var canvas = document.createElement('canvas');
        var ctx = canvas.getContext('2d');
        var renderContext = {
          canvasContext: ctx,
          viewport: viewport
        };
        
        canvas.height = viewport.height;
        canvas.width = viewport.width;

        canvasContainer.appendChild(canvas);
        
        page.render(renderContext);
    }
    
    function renderPages(pdfDoc) {
        for(var num = 1; num <= pdfDoc.numPages; num++)
            pdfDoc.getPage(num).then(renderPage);
    }

    PDFJS.disableWorker = true;
    PDFJS.getDocument(url).then(renderPages);

}   
</script> 

<div id="holder"></div>

<script type="text/javascript">
renderPDF('file.pdf', document.getElementById('holder'));
</script>  

</body>
</html>

@The-Don-Himself
Copy link

@WilsonYesidRiveraCasas don't use the unreleased/unstable version 2, please stick to version 1.x

@DevTheUIDeveloper
Copy link

how to add zoom functionality in above mention code so that after zoom it stay on the same page?

@kishandonepudi
Copy link

@amazingalain
Copy link

is it possible to JUST render specific range or page o a pdf ? like... page 3 to page 6 ?

@parmodkumarr
Copy link

`

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="pdf.js"></script> <script src="jquery.js"></script>

PDF.js 'Hello, world!' example

<script> // If absolute URL from the remote server is provided, configure the CORS // header on that server. var url = 'pdff.pdf';
        // Loaded via <script> tag, create shortcut to access PDF.js exports.
        var pdfjsLib = window['pdfjs-dist/build/pdf'];
        
        // The workerSrc property shall be specified.
        pdfjsLib.GlobalWorkerOptions.workerSrc = 'worker.js';
        var loadingTask = pdfjsLib.getDocument(url);
            loadingTask.promise.then(function(pdf) {
        			 var __TOTAL_PAGES = pdf.numPages; 
        			  // Fetch the first page
        			  var pageNumber = 1;			  
        			for( let i=1; i<=__TOTAL_PAGES; i+=1){
        	var id ='the-canvas'+i;
        	$('#canvas_div').append("<div style='background-color:gray;text-align: center;padding:20px;' ><canvas calss='the-canvas' id='"+id+"'></canvas></div>");				
        				  var canvas = document.getElementById(id);
        				  //var pageNumber = 1;
        				  renderPage(canvas, pdf, pageNumber++, function pageRenderingComplete() {
        					if (pageNumber > pdf.numPages) {
        					  return; 
        					}
        					// Continue rendering of the next page
        					renderPage(canvas, pdf, pageNumber++, pageRenderingComplete);
        				  });				
        			}
        	  
            });
        
            function renderPage(canvas, pdf, pageNumber, callback) {
              pdf.getPage(pageNumber).then(function(page) {
                var scale = 1.5;
                var viewport = page.getViewport({scale: scale});
        
                var pageDisplayWidth = viewport.width;
                var pageDisplayHeight = viewport.height;
        		//var pageDivHolder = document.createElement();
                // Prepare canvas using PDF page dimensions
                //var canvas = document.createElement(id);
                var context = canvas.getContext('2d');
                canvas.width = pageDisplayWidth;
                canvas.height = pageDisplayHeight;
               // pageDivHolder.appendChild(canvas);
        
                // Render PDF page into canvas context
                var renderContext = {
                  canvasContext: context,
                  viewport: viewport
                };
                page.render(renderContext).promise.then(callback);
              });
            }           
     </script>
     <html>

`

@JMIdeaMaker
Copy link

doesn't work with the newest version, 2.6.347

@levenokk
Copy link

levenokk commented Mar 18, 2021

It`s working now

<div id="my_canvas"></div>
<script src="https://cdn.jsdelivr.net/npm/pdfjs-dist@2.6.347/build/pdf.min.js" /> 
<script>
function renderPDF(url, canvasContainer) {

	function renderPage(page) {

    let viewport = page.getViewport({scale: .5})
    const DPI = 72;
    const PRINT_OUTPUT_SCALE = DPI/72; 
    const scale = canvasContainer.clientWidth / viewport.width;
		const canvas = document.createElement('canvas')
    
    const ctx = canvas.getContext('2d')
    viewport = page.getViewport({scale})

    canvas.width = Math.floor(viewport.width * PRINT_OUTPUT_SCALE);
    canvas.height = Math.floor(viewport.height * PRINT_OUTPUT_SCALE);
    canvas.style.width = '100%';

    canvas.style.transform = 'scale(1,1)';
    canvas.style.transformOrigin = '0% 0%';
  
    const canvasWrapper = document.createElement('div');

    canvasWrapper.style.width = '100%';
    canvasWrapper.style.height = '100%';
  
    canvasWrapper.appendChild(canvas);

		const renderContext = {
			canvasContext: ctx,
			viewport,
		}

		canvasContainer.appendChild(canvasWrapper)

		page.render(renderContext)
	}

	function renderPages(pdfDoc) {
		for (let num = 1; num <= pdfDoc.numPages; num += 1)
			pdfDoc.getPage(num).then(renderPage)
	}

	pdfjsLib.disableWorker = true
	pdfjsLib.getDocument(url).promise.then(renderPages)
}

renderPDF('../files/test.pdf', document.getElementById('my_canvas')) //div element

</script>

@beingshaif
Copy link

thanks @levenokk

@Ajitpatil92002
Copy link

Thank you @levenokk

@huunamtn
Copy link

huunamtn commented Jul 22, 2022

how to add zoom functionality in above mention code so that after zoom it stay on the same page?

add html zoom
<div id="zoom_controls">
<button id="zoom_in">+</button>
<button id="zoom_out">-</button>
</div>

<script> document.getElementById('zoom_in').addEventListener('click', (e) => { if(options.scale < 4) { options.scale += 0.5; document.querySelector("#holder").style.zoom = options.scale; } }); document.getElementById('zoom_out').addEventListener('click', (e) => { if(options.scale > 1) { options.scale -= 0.5; document.querySelector("#holder").style.zoom = options.scale; } }); </script>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment