SchattenJager
SchattenJager

Reputation: 333

PDF.js - Printing multiple documents at once

I need to place multiple PDFs on a page determined by an AJAX response, and when all documents and pages have rendered, call window.print.

The pages (canvases) of each document are being added to a div with class 'pdfdoc' to keep the pages in order by document.

I'm new to Promises, and I'm having trouble determining when to call window.print because of the async nature. Sometimes it is being called before all the pages are available even though I'm checking for the last page of the last document in the render promise before calling it. Below is the code:

// Called on each iteration of coredatalist
var getDoc = function(count) {
    PDFJS.getDocument(srcUrl).then(function(pdf) {
        var currentPage = 1;
        $('<div class="pdfdoc" id="doc' + count + '"></div>').appendTo('body');
        getPage(pdf, currentPage, count);
    });
};

// Called for each page in PDF
var getPage = function(pdf, currentPage, count) {
    pdf.getPage(currentPage).then(function(page) {
        var scale = 2,
            viewport = page.getViewport(scale),
            canvas = document.createElement('canvas'),
            context = canvas.getContext('2d'),
            renderContext = {
                canvasContext: context,
                viewport: viewport,
                intent: 'print'
            };

        // Prepare canvas using PDF page dimensions

        canvas.setAttribute('class', 'canvaspdf');
        canvas.id = 'canvas' + currentPage;
        canvas.height = viewport.height;
        canvas.width = viewport.width;

        // Render PDF page into canvas context

        page.render(renderContext).then(function(page) {
            $('#doc' + count).append(canvas);
            if (currentPage < pdf.numPages) {
                currentPage++;
                getPage(pdf, currentPage, count);
            } else {
                if (parseInt(count) === coredatalist.length - 1) {
                    window.print();
                }
            }
        });
    });
};

// Iterate through JSON object from AJAX request
for (var j in coredatalist) {
    if (coredatalist.hasOwnProperty(j)) {
        srcUrl = coredatalist[j].props.downloaduri;
        getDoc(j);
    }
}

Does anyone know how to call window.print after all documents AND pages are rendered?

Upvotes: 4

Views: 4229

Answers (1)

SchattenJager
SchattenJager

Reputation: 333

For anyone interested, I fulfilled my requirements by wrapping PDFJS.getDocument() inside a function with a callback 'next':

loadPdf: function (pdfUrl, pdfindex, next) {
    var self = this;
    PDFJS.getDocument(pdfUrl).then(function (pdf) {

        var currentPage = 1;
        function getPage() {
            pdf.getPage(currentPage).then(function (page) {
                var scale = 2,
                    viewport = page.getViewport(scale),
                    canvas = document.createElement('canvas'),
                    context = canvas.getContext('2d'),
                    renderContext = {
                        canvasContext: context,
                        viewport: viewport,
                        intent: 'print'
                    };

                // Prepare canvas using PDF page dimensions

                canvas.setAttribute('class', 'canvaspdf');
                canvas.id = 'canvas' + currentPage + '-' + pdfindex;
                canvas.height = viewport.height;
                canvas.width = viewport.width;

                // Render PDF page into canvas context

                page.render(renderContext).then(function (page) {
                    document.body.appendChild(canvas);
                    if (currentPage < pdf.numPages) {
                        currentPage++;
                        getPage();
                    } else {
                        next();
                    }
                });
            });
        }

        if (currentPage < pdf.numPages) {
            getPage();
        }
    });
}

And then calling it within the callback:

var pdfUrls = [],

    next = function () {
        if (pdfUrls.length === 0) {
            window.print();
        } else {
            self.loadPdf(pdfUrls.pop(), pdfUrls.length, next);
        }
    };

for (var j in coredatalist) {
    if (coredatalist.hasOwnProperty(j)) {
        pdfUrls.push('url');
    }
}

next();

Upvotes: 5

Related Questions