I\'ve created this demo:
http://polishwords.com.pl/dev/pdfjs/test.html
It displays one page. I would like to display all pages. One below another, or place s
Here's my take. Renders all pages in correct order and still works asynchronously.
<style>
#pdf-viewer {
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.1);
overflow: auto;
}
.pdf-page-canvas {
display: block;
margin: 5px auto;
border: 1px solid rgba(0, 0, 0, 0.2);
}
</style>
<script>
url = 'https://github.com/mozilla/pdf.js/blob/master/test/pdfs/tracemonkey.pdf';
var thePdf = null;
var scale = 1;
PDFJS.getDocument(url).promise.then(function(pdf) {
thePdf = pdf;
viewer = document.getElementById('pdf-viewer');
for(page = 1; page <= pdf.numPages; page++) {
canvas = document.createElement("canvas");
canvas.className = 'pdf-page-canvas';
viewer.appendChild(canvas);
renderPage(page, canvas);
}
});
function renderPage(pageNumber, canvas) {
thePdf.getPage(pageNumber).then(function(page) {
viewport = page.getViewport(scale);
canvas.height = viewport.height;
canvas.width = viewport.width;
page.render({canvasContext: canvas.getContext('2d'), viewport: viewport});
});
}
</script>
<div id='pdf-viewer'></div>
If you want to render all pages of pdf document in different canvases
<html>
<head>
<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>
</head>
<body>
<h1>PDF.js 'Hello, world!' example</h1>
<div id="canvas_div"></div>
<body>
<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>
The following answer is a partial answer targeting anyone trying to get a PDF.js to display a whole PDF in 2019, as the api has changed significantly. This was of course the OP's primary concern. inspiration sample code
Please take note of the following:
<div class="row">
<div class="col-md-10 col-md-offset-1">
<div id="wrapper">
</div>
</div>
</div>
<style>
body {
background-color: #808080;
/* margin: 0; padding: 0; */
}
</style>
<link href="//cdnjs.cloudflare.com/ajax/libs/pdf.js/2.1.266/pdf_viewer.css" rel="stylesheet"/>
<script src="//cdnjs.cloudflare.com/ajax/libs/pdf.js/2.1.266/pdf.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/pdf.js/2.1.266/pdf_viewer.js"></script>
<script src="//cdn.polyfill.io/v2/polyfill.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>
<script>
$(document).ready(function () {
// startup
});
'use strict';
if (!pdfjsLib.getDocument || !pdfjsViewer.PDFViewer) {
alert("Please build the pdfjs-dist library using\n" +
" `gulp dist-install`");
}
var url = '//www.pdf995.com/samples/pdf.pdf';
pdfjsLib.GlobalWorkerOptions.workerSrc =
'//cdnjs.cloudflare.com/ajax/libs/pdf.js/2.1.266/pdf.worker.js';
var loadingTask = pdfjsLib.getDocument(url);
loadingTask.promise.then(function(pdf) {
// please be aware this uses .range() function from lodash
var pagePromises = _.range(1, pdf.numPages).map(function(number) {
return pdf.getPage(number);
});
return Promise.all(pagePromises);
}).then(function(pages) {
var scale = 1.5;
var canvases = pages.forEach(function(page) {
var viewport = page.getViewport({ scale: scale, }); // Prepare canvas using PDF page dimensions
var canvas = document.createElement('canvas');
canvas.height = viewport.height;
canvas.width = viewport.width; // Render PDF page into canvas context
var canvasContext = canvas.getContext('2d');
var renderContext = {
canvasContext: canvasContext,
viewport: viewport
};
page.render(renderContext).promise.then(function() {
if (false)
return console.log('Page rendered');
});
document.getElementById('wrapper').appendChild(canvas);
});
},
function(error) {
return console.log('Error', error);
});
</script>
If you want to render all pages of pdf document in different canvases, all one by one synchronously this is kind of solution:
index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>PDF Sample</title>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="pdf.js"></script>
<script type="text/javascript" src="main.js">
</script>
<link rel="stylesheet" type="text/css" href="main.css">
</head>
<body id="body">
</body>
</html>
main.css
canvas {
display: block;
}
main.js
$(function() {
var filePath = "document.pdf";
function Num(num) {
var num = num;
return function () {
return num;
}
};
function renderPDF(url, canvasContainer, options) {
var options = options || {
scale: 1.5
},
func,
pdfDoc,
def = $.Deferred(),
promise = $.Deferred().resolve().promise(),
width,
height,
makeRunner = function(func, args) {
return function() {
return func.call(null, args);
};
};
function renderPage(num) {
var def = $.Deferred(),
currPageNum = new Num(num);
pdfDoc.getPage(currPageNum()).then(function(page) {
var viewport = page.getViewport(options.scale);
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
var renderContext = {
canvasContext: ctx,
viewport: viewport
};
if(currPageNum() === 1) {
height = viewport.height;
width = viewport.width;
}
canvas.height = height;
canvas.width = width;
canvasContainer.appendChild(canvas);
page.render(renderContext).then(function() {
def.resolve();
});
})
return def.promise();
}
function renderPages(data) {
pdfDoc = data;
var pagesCount = pdfDoc.numPages;
for (var i = 1; i <= pagesCount; i++) {
func = renderPage;
promise = promise.then(makeRunner(func, i));
}
}
PDFJS.disableWorker = true;
PDFJS.getDocument(url).then(renderPages);
};
var body = document.getElementById("body");
renderPDF(filePath, body);
});
PDFJS has a member variable numPages
, so you'd just iterate through them. BUT it's important to remember that getting a page in pdf.js is asynchronous, so the order wouldn't be guaranteed. So you'd need to chain them. You could do something along these lines:
var currPage = 1; //Pages are 1-based not 0-based
var numPages = 0;
var thePDF = null;
//This is where you start
PDFJS.getDocument(url).then(function(pdf) {
//Set PDFJS global object (so we can easily access in our page functions
thePDF = pdf;
//How many pages it has
numPages = pdf.numPages;
//Start with first page
pdf.getPage( 1 ).then( handlePages );
});
function handlePages(page)
{
//This gives us the page's dimensions at full scale
var viewport = page.getViewport( 1 );
//We'll create a canvas for each page to draw it on
var canvas = document.createElement( "canvas" );
canvas.style.display = "block";
var context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
//Draw it on the canvas
page.render({canvasContext: context, viewport: viewport});
//Add it to the web page
document.body.appendChild( canvas );
//Move to next page
currPage++;
if ( thePDF !== null && currPage <= numPages )
{
thePDF.getPage( currPage ).then( handlePages );
}
}
The pdfjs-dist library contains parts for building PDF viewer. You can use PDFPageView to render all pages. Based on https://github.com/mozilla/pdf.js/blob/master/examples/components/pageviewer.html :
var url = "https://cdn.mozilla.net/pdfjs/tracemonkey.pdf";
var container = document.getElementById('container');
// Load document
PDFJS.getDocument(url).then(function (doc) {
var promise = Promise.resolve();
for (var i = 0; i < doc.numPages; i++) {
// One-by-one load pages
promise = promise.then(function (id) {
return doc.getPage(id + 1).then(function (pdfPage) {
// Add div with page view.
var SCALE = 1.0;
var pdfPageView = new PDFJS.PDFPageView({
container: container,
id: id,
scale: SCALE,
defaultViewport: pdfPage.getViewport(SCALE),
// We can enable text/annotations layers, if needed
textLayerFactory: new PDFJS.DefaultTextLayerFactory(),
annotationLayerFactory: new PDFJS.DefaultAnnotationLayerFactory()
});
// Associates the actual page with the view, and drawing it
pdfPageView.setPdfPage(pdfPage);
return pdfPageView.draw();
});
}.bind(null, i));
}
return promise;
});
#container > *:not(:first-child) {
border-top: solid 1px black;
}
<link href="https://npmcdn.com/pdfjs-dist/web/pdf_viewer.css" rel="stylesheet"/>
<script src="https://npmcdn.com/pdfjs-dist/web/compatibility.js"></script>
<script src="https://npmcdn.com/pdfjs-dist/build/pdf.js"></script>
<script src="https://npmcdn.com/pdfjs-dist/web/pdf_viewer.js"></script>
<div id="container" class="pdfViewer singlePageView"></div>