'html to pdf using jsPdf is not working with react app

I am using react as a frontend application, I want to export a portion of react component as pdf file using jsPdf.

const handleDownload = () => {
  const content = document.getElementById('download-content');
  const doc = new jsPDF();
  doc.html(content);
  doc.save("a4.pdf");
}

React return component is:

return (
<body>
  <header id='download-content'>
    <div>l kldfjlkasjfld asjflkajf ljfasd'flksdasjf lsdasjfsadf</div>
    <div>l kldfjlkasjfld asjflkajf ljfasd'flksdasjf lsdasjfsadf</div>
    <div>l kldfjlkasjfld asjflkajf ljfasd'flksdasjf lsdasjfsadf</div>
    <div>l kldfjlkasjfld asjflkajf ljfasd'flksdasjf lsdasjfsadf</div>
    <div>l kldfjlkasjfld asjflkajf ljfasd'flksdasjf lsdasjfsadf</div>
    <div>l kldfjlkasjfld asjflkajf ljfasd'flksdasjf lsdasjfsadf</div>
  </header>
  <footer>
    <button onClick={handleDownload}>Download</button>
  </footer>
</body>
)

After click on Download button I want a pdf file which consists header tag data with style. But here I got blank pdf with this function handleDownload.

I don't want to use canvas to generate image and then make pdf.. If I use canvas then, when page size minimize the pdf will change.

How can I get exact html generated page as pdf?



Solution 1:[1]

2 Things:

  1. When getting access to a DOM Element in react you should always use useRef

  2. It appears that .html method is async and requires a callback

A working example would be something like this:

import { useRef } from 'react';
import { jsPDF } from 'jspdf';

export default function PDF() {
    const pdfRef = useRef(null);

    const handleDownload = () => {
        const content = pdfRef.current;

        const doc = new jsPDF();
        doc.html(content, {
            callback: function (doc) {
                doc.save('sample.pdf');
            }
        });
    };

    return (
        <div>
            <header ref={pdfRef}>
                <div>l kldfjlkasjfld asjflkajf ljfasd'flksdasjf lsdasjfsadf</div>
                <div>l kldfjlkasjfld asjflkajf ljfasd'flksdasjf lsdasjfsadf</div>
                <div>l kldfjlkasjfld asjflkajf ljfasd'flksdasjf lsdasjfsadf</div>
                <div>l kldfjlkasjfld asjflkajf ljfasd'flksdasjf lsdasjfsadf</div>
                <div>l kldfjlkasjfld asjflkajf ljfasd'flksdasjf lsdasjfsadf</div>
                <div>l kldfjlkasjfld asjflkajf ljfasd'flksdasjf lsdasjfsadf</div>
            </header>
            <footer>
                <button onClick={handleDownload}>Download</button>
            </footer>
        </div>
    );
}

Update

If you need to control the size you can add additional properties as per documentation cited above:

Option 1 - use the html2canvas option and control the scale:

const handleDownload = () => {
    const content = pdfRef.current;

    const doc = new jsPDF();
    doc.html(content, {
        callback: function (doc) {
            doc.save('sample.pdf');
        },
        html2canvas: { scale: 0.5 } // change the scale to whatever number you need
    });
};

Option 2 - use width and windowWidth:

const handleDownload = () => {
    const content = pdfRef.current;

    const doc = new jsPDF();
    doc.html(content, {
        callback: function (doc) {
            doc.save('sample.pdf');
        },
        width: 200, // <- here
        windowWidth: 200 // <- here
    });
};

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1