8

I'd like to generate a PDF from my React App, the easiest way would probably be to take a screenshot of the current state of my app / ideally a div and save it as PDF...I just don't seem to be able to find the best way how to do it.

Any ideas?

Michaela
  • 268
  • 2
  • 4
  • 14

3 Answers3

3

For anyone reading this pdfkit can also generate pdfs in the browser...nice!

You'll need to check out pdfkit website and specifically I only got it to work using the browser releases for pdfkit and blob-stream

https://github.com/devongovett/pdfkit/releases https://github.com/devongovett/blob-stream/releases

My code looked like

import PDFDocument from 'pdfkit'
import BlobStream from 'blob-stream'
import FileSaver from 'file-saver'

let doc = new PDFDocument()
    let stream = doc.pipe(BlobStream())
    addHeader(doc, 'My Report.....')
    doc.moveDown(0.5).fontSize(8)
   // render you doc
   // then add a stream eventListener to allow download
stream.on('finish', ()=>{
      let blob = stream.toBlob('application/pdf')
      FileSaver.saveAs(blob, 'myPDF.pdf')

    })
    doc.end()
dorriz
  • 1,927
  • 3
  • 12
  • 19
1

How about a combination of:

html2canvas: https://html2canvas.hertzen.com/

and

jsPDF: https://parall.ax/products/jspdf

From the canvas provided by html2canvas, you can convert it to an image with .toDataUrl() and then feed that into jsPDF with the .addImage() method which wants a base64 image.

Sam Foot
  • 126
  • 4
  • that sounds like a good idea...just not sure how to include libraries as such into my reactjs app...bit of a newbie :) – Michaela Apr 13 '17 at 10:54
  • No problem, If you are using webpack both are available on npm: [html2canvas](https://www.npmjs.com/package/html2canvas) [jspdf](https://www.npmjs.com/package/jspdf) If you are just including React on the page both have CDN links on the links above. – Sam Foot Apr 13 '17 at 11:34
  • 2
    I just posted a detailed answer about the same [here](https://stackoverflow.com/a/45017234/1587695). Hope it helps. – Shivek Khurana Jul 10 '17 at 16:30
  • There is a problem with jsPDF wich I bumped into. The addImage method do its stuff in sync manner and the whole app just hangs. And it can't be moved into web worker because it relies on the DOM. It's not very user-friendly. So I used html2canvas on the client and pdfkit on the backend to solve the similar task. It's pretty much pain in the ass in either case though. – Aleksej Shovgenja May 19 '18 at 09:26
0

Using html2canvas and jsPDF created a react components that export the div and its children components as pdf and Image

The react component is defined as following

        import React from 'react'
        import html2canvas from 'html2canvas'
        import { jsPDF } from "jspdf";
    
        class Exporter extends React.Component {
           constructor(props) {
             super(props)
           } 
    
        export =(type, name)=>{
    
        html2canvas(document.querySelector(`#capture`)).then(canvas => {
          let dataURL = canvas.toDataURL('image/png');
    
          if (type === 'pdf') {
            const pdf = new jsPDF({
              orientation: "landscape",
              unit: "in",
              format: [14, 10]
            });
    
            pdf.addImage(dataURL, 'PNG', .6, .6);
            pdf.save(`${name}.pdf`);
    
          } else if (type === 'png') {
            var link = document.createElement('a');
            link.download = `${name}.png`;
            link.href = dataURL;
            link.click();
          }
        });
     }
     render() { 
        return (
          <div>
            <button onClick={()=>this.export("pdf", "my-content")}></button>
            <div id={`capture`} >
              Content to export as pdf/png
              {this.props.children} //any child Component render here will be exported as pdf/png
            </div>
          </div>
        )
      }
    }

export default Exporter
Arvind Pal
  • 498
  • 3
  • 14