Search code examples
javascripthtml2canvaspdfmake

How to send pdf generated from screen shot in JavaScript


Objective - Take a screenshot of the page, then make pdf of that and send that pdf to the spring boot backend.

I have implemented the functionality to take the screenshot and convert it into pdf using html2canvas and pdfmake JavaScript libraries.

Issue - I don't know how to send the generated pdf to the backend. I got to know about base64 encode but I am still confused.

Code -

function takeSS() {
    html2canvas(document.body, {
        onrendered: function(canvas) {
            var data = canvas.toDataURL();
            var docDefinition = {
                content: [{
                    image: data,
                    width: 900,
                }]
            };
            pdfMake.createPdf(docDefinition).download("test.pdf"); // to download
        }
    });
}

The above code is taking the screenshot of the page converting it to pdf and downloading it. Instead of downloading it, how can I send this pdf to backend? Do I need to base64 encode canvas.toDataURL()?

Edit Changed my code - jsFiddle


Solution

  • According to the docs of pdfmake you're able to get the generated PDF as a Blob with the getBlob method. The Blob will be a binary representation of your PDF which you can send to your server.

    Blobs need to be wrapped inside a FormData object before they can be sent.

    Edit: Switch to the latest version (1.4.1) of html2canvas. The older version didn't work properly. The latest versions uses Promises which allows us to use async functions and, in my opinion, makes your code more readable.

    The beta version of pdfmake uses Promises instead of a callback function, but the latest stable version (0.2.5) does not. But we can solve this by wrapping the callback with a Promise to still be able to use the async / await syntax.

    async function takeSS() {
      const canvas = await html2canvas(document.body);
      const data = canvas.toDataURL();
      const docDefinition = {
        content: [{
          image: data,
          width: 900,
        }]
      };
      
      const pdfDocGenerator = pdfMake.createPdf(docDefinition);
      const blob = await new Promise(resolve => {
        pdfDocGenerator.getBlob(resolve);
      });
      
      const formData = new FormData();
      formData.append('pdf', blob, 'test.pdf');
      
      try {
        const response = await fetch('myapi-url', {
          method: 'POST',
          body: formData
        });
        
        if (!response.ok) {
          throw new Error('POST request failed');
        }
    
        const message = await response.text();
        console.log(message);
      } catch (error) {
        console.error(error);
      }
    }