简体   繁体   中英

how to open a local PDF in PDFJS using file input?

我想知道是否有办法使用input type="file"选择 pdf 文件并使用PDFJS打开它

You should be able to use a FileReader to get the contents of a file object as a typed array, which pdfjs accepts ( https://mozilla.github.io/pdf.js/examples/ )

//Step 1: Get the file from the input element                
inputElement.onchange = function(event) {

    var file = event.target.files[0];

    //Step 2: Read the file using file reader
    var fileReader = new FileReader();  

    fileReader.onload = function() {

        //Step 4:turn array buffer into typed array
        var typedarray = new Uint8Array(this.result);

        //Step 5:pdfjs should be able to read this
        const loadingTask = pdfjsLib.getDocument(typedarray);
        loadingTask.promise.then(pdf => {
            // The document is loaded here...
        });
                    

    };
    //Step 3:Read the file as ArrayBuffer
    fileReader.readAsArrayBuffer(file);
 
 }

Edit: The pdfjs API changed at some point since I wrote this first answer in 2015. Updating to reflect the new API as of 2021(thanks to @Chiel) for the updated answer

If getDocument().then is not a function:

I reckon I have managed to solve the new problem with the new API. As mentioned in this GitHub issue , the getDocument function now has an promise added to itself. In short, this:

PDFJS.getDocument(typedarray).then(function(pdf) {
    // The document is loaded here...
});

became this:

const loadingTask = pdfjsLib.getDocument(typedarray);
loadingTask.promise.then(pdf => {
    // The document is loaded here...
});

Adapting the older answer to the new api to comply to the bounty gives the following result:

//Step 1: Get the file from the input element                
inputElement.onchange = function(event) {

    //It is important that you use the file and not the filepath (The file path won't work because of security issues)
    var file = event.target.files[0];

    var fileReader = new FileReader();  

    fileReader.onload = function() {

        var typedarray = new Uint8Array(this.result);

        //replaced the old function with the new api
        const loadingTask = pdfjsLib.getDocument(typedarray);
            loadingTask.promise.then(pdf => {
                // The document is loaded here...
            });

    };
    //Step 3:Read the file as ArrayBuffer
    fileReader.readAsArrayBuffer(file);

 }

I have created an example below with the official releases of the source code below to show that it is working.

 /*Offical release of the pdfjs worker*/ pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.5.207/pdf.worker.js'; document.getElementById('file').onchange = function(event) { var file = event.target.files[0]; var fileReader = new FileReader(); fileReader.onload = function() { var typedarray = new Uint8Array(this.result); console.log(typedarray); const loadingTask = pdfjsLib.getDocument(typedarray); loadingTask.promise.then(pdf => { // The document is loaded here... //This below is just for demonstration purposes showing that it works with the moderen api pdf.getPage(1).then(function(page) { console.log('Page loaded'); var scale = 1.5; var viewport = page.getViewport({ scale: scale }); var canvas = document.getElementById('pdfCanvas'); 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 }; var renderTask = page.render(renderContext); renderTask.promise.then(function() { console.log('Page rendered'); }); }); //end of example code }); } fileReader.readAsArrayBuffer(file); }
 <html> <head> <!-- The offical release--> <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.5.207/pdf.js"> </script> </head> <body> <input type="file" id="file"> <h2>Rendered pdf:</h2> <canvas id="pdfCanvas" width="300" height="300"></canvas> </body> </html>

Hope this helps! If not, please comment.

Note:

This might not work in jsFiddle.

I adopted your code and it worked! Then I was browsing for more tips here and there, then I learned there is an even more convenient method.

You can get the URL of client-loaded file with

URL.createObjectURL()

It reduces nesting by one level and you don't need to read the file, convert it to array, etc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM