Creating a pdf.file using react
Tags: react, reactnative, javascript
Published: 2020-03-23 16:30:37


Assuming your a mid level software developer, you know that react components are separated code that is better transmitted across UI and even through many other projects. This blog will discuss how to create a PDF component for your one of your projects.

Step 1 - Install Dependencies
First of all, I need an environment to create our component in. For this example I will be using create-react-app to generate a project. Navigate to an empty directory and run the following command:

npm i create-react-app --save-dev

Step 2 - Create the Project
Use the following commands to generate your React project:

npx create-react-app my-app
cd my-app
This will install React and any other dependencies you need.

Now you can start your local server by running:
npm run start

Navigate to http://localhost:3000/ and you should see the default create react-app welcome screen.

Step 3 - Project Setup
Next I need to set up our project.  Start by clearing the templates that create-react-app provides. Navigate to src/App.js and delete all the code inside the render function, except the outer div. The file should now contain:

import React, { Component } from 'react';
import './App.css';
class App extends Component {
  render() {
    return (
      <div className="App">
      </div>);}}

export default App;


Now I need to create our PDF viewing component. Let’s create the file src/components/PDFViewer/PDFViewer.js and start by writing a basic React component.

import React from 'react';
export default class PDFViewer extends React.Component {

  render() {
    return (
      <div id='viewer' style={{ width: '100%', height: '100%' }}>
        Hello world!
      </div>
    )
  }
}


Now, back in App.js, lets import this component and render it. App.js should now look like this:

import React, { Component } from 'react';
import './App.css';
import PDFViewer from './components/PDFViewer/PDFViewer';

class App extends Component {
  render() {
    return (
      <div className="App">
        <PDFViewer />
      </div>
    );
  }
}

export default App;


If you take a look at http://localhost:3000 , you should see a little “Hello world!” on a white background.

Step 4 - Defining Our Backend
when creating your first backend that renders a PDF using pdf.js. Create the file src/backends/pdfjs.js and export a class that contains an init function.

export default class PDFJs {
  init = () => {
    
  }
}

Let’s make the init function accept both of these things as parameters.

export default class PDFJs {
  init = (source, element) => {
    
  }
}

In App.js, import the pdfjs.js backend and pass it as a prop to our PDFViewer component. We’re also going to need a PDF source, so lets pass that as well. App.js should now look something like this:

import React, { Component } from 'react';
import './App.css';
import PDFViewer from './components/PDFViewer/PDFViewer';
import PDFJSBackend from './backends/pdfjs';

class App extends Component {
  render() {
    return (
      <div className="App">
        <PDFViewer 
          backend={PDFJSBackend}
          src='/myPDF.pdf'
        />
      </div>
    );
  }
}

export default App;


Now in our PDFViewer component, lets implement the backends init function. First we start by creating an instance of the backend and storing it to the component.

import React from 'react';

export default class PDFViewer extends React.Component {
  constructor(props) {
    super(props);
    this.viewerRef = React.createRef();
    this.backend = new props.backend();
  }

  render() {
    return (
      <div ref={this.viewerRef} id='viewer' style={{ width: '100%', height: '100%' }}>

      </div>
    )
  }
}

No pass it a reference to the #viewer div , as well as the PDF source. We can also remove the "Hello world" from the render function while we're at it. PDFViewer.js should now look like this:

import React from 'react';

export default class PDFViewer extends React.Component {
  constructor(props) {
    super(props);
    this.viewerRef = React.createRef();
    this.backend = new props.backend();
  }

  componentDidMount() {
    const { src } = this.props;
    const element = this.viewerRef.current;

    this.backend.init(src, element);
  }
  
  render() {
    return (
      <div ref={this.viewerRef} id='viewer' style={{ width: '100%', height: '100%' }}>

      </div>
    )
  }
}

The final step is making our init function  do something. Lets test it out by making it render some text.

export default class PDFJs {
  init = (source, element) => {
    const textNode = document.createElement('p');
    textNode.innerHTML = `Our PDF source will be: ${source}`;

    element.appendChild(textNode);
  }
}

http://localhost:3000 should now display "Our PDF source will be: /myPDF.pdf".

Step 5 - Implementing pdf.js
We will start by using the open sourced pdf.js library to render a PDF. Download the library from https://mozilla.github.io/pdf.js/getting_started/#download and extract the contents inside the public folder of our project.


src/backends/pdfjs.js should now look like this:

export default class PDFJs {
  init = (source, element) => {
    const iframe = document.createElement('iframe');

    iframe.src = `/pdfjs-1.9.426-dist/web/viewer.html?file=${source}`;
    iframe.width = '100%';
    iframe.height = '100%';

    element.appendChild(iframe);
  }
}

If you check out http://localhost:3000, you should see your PDF displayed inside the pdf.js viewer.