0

I am trying to create an app with electron and react in which I am trying to render a pdf using pdfjs from the local filesystem. I will get the pdf data from electron which will then be passed to react app.

After going through the code for viewer.js file I can see that I can send the file parameter value as Uint8Array and in turn, it will call the PDFJS's getDocument with data, so I tried a little example but somehow I am not able to get it working.

Pasting the code below

base64ToUint8Array = () => {
// taken from pdfjs github example
let raw = atob(
  'JVBERi0xLjcKCjEgMCBvYmogICUgZW50cnkgcG9pbnQKPDwKICAvVHlwZSAvQ2F0YWxvZwog' +
  'IC9QYWdlcyAyIDAgUgo+PgplbmRvYmoKCjIgMCBvYmoKPDwKICAvVHlwZSAvUGFnZXMKICAv' +
  'TWVkaWFCb3ggWyAwIDAgMjAwIDIwMCBdCiAgL0NvdW50IDEKICAvS2lkcyBbIDMgMCBSIF0K' +
  'Pj4KZW5kb2JqCgozIDAgb2JqCjw8CiAgL1R5cGUgL1BhZ2UKICAvUGFyZW50IDIgMCBSCiAg' +
  'L1Jlc291cmNlcyA8PAogICAgL0ZvbnQgPDwKICAgICAgL0YxIDQgMCBSIAogICAgPj4KICA+' +
  'PgogIC9Db250ZW50cyA1IDAgUgo+PgplbmRvYmoKCjQgMCBvYmoKPDwKICAvVHlwZSAvRm9u' +
  'dAogIC9TdWJ0eXBlIC9UeXBlMQogIC9CYXNlRm9udCAvVGltZXMtUm9tYW4KPj4KZW5kb2Jq' +
  'Cgo1IDAgb2JqICAlIHBhZ2UgY29udGVudAo8PAogIC9MZW5ndGggNDQKPj4Kc3RyZWFtCkJU' +
  'CjcwIDUwIFRECi9GMSAxMiBUZgooSGVsbG8sIHdvcmxkISkgVGoKRVQKZW5kc3RyZWFtCmVu' +
  'ZG9iagoKeHJlZgowIDYKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDEwIDAwMDAwIG4g' +
  'CjAwMDAwMDAwNzkgMDAwMDAgbiAKMDAwMDAwMDE3MyAwMDAwMCBuIAowMDAwMDAwMzAxIDAw' +
  'MDAwIG4gCjAwMDAwMDAzODAgMDAwMDAgbiAKdHJhaWxlcgo8PAogIC9TaXplIDYKICAvUm9v' +
  'dCAxIDAgUgo+PgpzdGFydHhyZWYKNDkyCiUlRU9G');
let uint8Array = new Uint8Array(new ArrayBuffer(raw.length));
for (var i = 0; i < raw.length; i++) {
  uint8Array[i] = raw.charCodeAt(i);
}
return uint8Array;


render(){ 
let pdfUint8Array = this.base64ToUint8Array(); 

return(
  <iframe

    src={`/web/viewer.html?file=${pdfUint8Array}`}
    title="frame"
    width="100%"
    height="700px" 
  />
);

}

From the error on the browser console I can see that the file param value is still taken as url hence pdf not getting rendered.

Error
fetch_stream.js:101 GET http://localhost:3001/web/37,80,68,70,45,49,46,55,10,10,49,32,48,32,111,98,106,32,32,37,32,101,110,116,114,121,32,112,111,105,110,116,10,60,60,10,32,32,47,84,121,112,101,32,47,67,97,116,97,108,111,103,10,32,32,47,80,97,103,101,115,32,50,32,48,32,82,10,62,62,10,101,110,100,111,98,106,10,10,50,32,48,32,111,98,106,10,60,60,10,32,32,47,84,121,112,101,32,47,80,97,103,101,115,10,32,32,47,77,101,100,105,97,66,111,120,32,91,32,48,32,48,32,50,48,48,32,50,48,48,32,93,10,32,32,47,67,111,117,110,116,32,49,10,32,32,47,75,105,100,115,32,91,32,51,32,48,32,82,32,93,10,62,62,10,101,110,100,111,98,106,10,10,51,32,48,32,111,98,106,10,60,60,10,32,32,47,84,121,112,101,32,47,80,97,103,101,10,32,32,47,80,97,114,101,110,116,32,50,32,48,32,82,10,32,32,47,82,101,115,111,117,114,99,101,115,32,60,60,10,32,32,32,32,47,70,111,110,116,32,60,60,10,32,32,32,32,32,32,47,70,49,32,52,32,48,32,82,32,10,32,32,32,32,62,62,10,32,32,62,62,10,32,32,47,67,111,110,116,101,110,116,115,32,53,32,48,32,82,10,62,62,10,101,110,100,111,98,106,10,10,52,32,48,32,111,98,106,10,60,60,10,32,32,47,84,121,112,101,32,47,70,111,110,116,10,32,32,47,83,117,98,116,121,112,101,32,47,84,121,112,101,49,10,32,32,47,66,97,115,101,70,111,110,116,32,47,84,105,109,101,115,45,82,111,109,97,110,10,62,62,10,101,110,100,111,98,106,10,10,53,32,48,32,111,98,106,32,32,37,32,112,97,103,101,32,99,111,110,116,101,110,116,10,60,60,10,32,32,47,76,101,110,103,116,104,32,52,52,10,62,62,10,115,116,114,101,97,109,10,66,84,10,55,48,32,53,48,32,84,68,10,47,70,49,32,49,50,32,84,102,10,40,72,101,108,108,111,44,32,119,111,114,108,100,33,41,32,84,106,10,69,84,10,101,110,100,115,116,114,101,97,109,10,101,110,100,111,98,106,10,10,120,114,101,102,10,48,32,54,10,48,48,48,48,48,48,48,48,48,48,32,54,53,53,51,53,32,102,32,10,48,48,48,48,48,48,48,48,49,48,32,48,48,48,48,48,32,110,32,10,48,48,48,48,48,48,48,48,55,57,32,48,48,48,48,48,32,110,32,10,48,48,48,48,48,48,48,49,55,51,32,48,48,48,48,48,32,110,32,10,48,48,48,48,48,48,48,51,48,49,32,48,48,48,48,48,32,110,32,10,48,48,48,48,48,48,48,51,56,48,32,48,48,48,48,48,32,110,32,10,116,114,97,105,108,101,114,10,60,60,10,32,32,47,83,105,122,101,32,54,10,32,32,47,82,111,111,116,32,49,32,48,32,82,10,62,62,10,115,116,97,114,116,120,114,101,102,10,52,57,50,10,37,37,69,79,70 404 (Not Found)

I can also see while console logging the file param as file [object ArrayBuffer] if I pass pdfUint8Array.buffer in the file param but the pdf is still isn't rendered as it is taken as a string as pdfjs try to display it with url.

Hiten Rastogi
  • 152
  • 4
  • 15

2 Answers2

1

CodeSAndbox Demo (open the result of the codesandbox in a new tab for it to work)

Hey Hiten,

Apparently in mozilla official documents for PDF.js, They say that no need to convert to Byte array (uint8Array), you can parse the base64 code into pdf directly....

Just render the iframe with data:application/pdf;base64 before the raw base64 data like this and it will appear :)

<iframe 
  title="frame"
  width="300px"
  height="700px"
  src={`data:application/pdf;base64,${this.base64PDF()}`} />

A good reference in another Stackoverflow Thread discussing rendering a pdf file using a base64 instead of url

I hope I have helped you ✌

Dabees
  • 494
  • 4
  • 14
  • Thanks, Ahm for your reply but I think you are getting confused here between the default display of browser and pdfjs specific display. The above code has nothing to do with pdfjs and you can check that by opening the sandbox link in chrome which displays nothing but it works in Mozilla as Mozilla's default display is by pdfjs. Plus I want the pdf display to come with pdfjs default viewer rather than creating my own if the intent of the answer is that. – Hiten Rastogi Feb 13 '19 at 10:55
  • i don't understand what do you mean by pdf.js default viewer ?? can you offer a link or a resource ?? ....yes the pdf got rendered using the default browser viewer...are you sure you accused this link [link](https://v8vj2z0000.codesandbox.io) .. – Dabees Feb 13 '19 at 12:35
  • Ahm - Your solution works for web apps but I am creating an electron application where the above doesn't work hence I have to use pdfjs lib and use the default viewer located under web directory named viewer.html to display pdf. I have posted the answer below how I achieved it. – Hiten Rastogi Mar 22 '19 at 12:16
0

My main aim here was to render the pdf from my local filesystem in the electron app that I am creating.

My earlier approach was to pass on the raw base64 data of the pdf in an iframe with src as web/viewer.html of the pdfjs but due to some limitation in electron, this wasn't working.

So, I figured out an easy solution that while starting electron I ran a node server on the directory from where I wanted to serve the pdf files and used the URL in the form http://localhost/{port_number}/{path_to_my_pdf_files} to access the pdf in pdfjs

<iframe

    src={`/web/viewer.html?file=http://localhost:${process.env.REACT_APP_PDF_SERVER_PORT}/${path}`}
    title="iframe"
    width="100%"
    height="700px" 
  />
Hiten Rastogi
  • 152
  • 4
  • 15