carreankush
carreankush

Reputation: 651

jspdf is not able to capture the div content properly for highcharts to download as pdf format

I want to download the content of html in the pdf fprmat,but here in my case I am using highcharts but when I download the pdf its not able to capture the content of chart,it can able to capture only text contents.I have used all the extra plugin like addimage,standard font etc even though it not able to print.is there any other plugin I need to use,or do I need to use any highcharts plugin for that,here is the code below

    $(function () {
    
        var specialElementHandlers = {
            '#editor': function (element,renderer) {
                return true;
            }
        };
     $('#cmd').click(function () {
            var doc = new jsPDF();
            doc.fromHTML(
                $('#container').html(), 15, 15, 
                { 'width': 170, 'elementHandlers': specialElementHandlers }, 
                function(){ doc.save('sample-file.pdf'); }
            );
    
        });  
    });
    Highcharts.chart('container', {
    
        title: {
            text: 'Solar Employment Growth by Sector, 2010-2016'
        },
    
        subtitle: {
            text: 'Source: thesolarfoundation.com'
        },
    
        yAxis: {
            title: {
                text: 'Number of Employees'
            }
        },
        legend: {
            layout: 'vertical',
            align: 'right',
            verticalAlign: 'middle'
        },
    
        plotOptions: {
            series: {
                label: {
                    connectorAllowed: false
                },
                pointStart: 2010
            }
        },
    
        series: [{
            name: 'Installation',
            data: [43934, 52503, 57177, 69658, 97031, 119931, 137133, 154175]
        }, {
            name: 'Manufacturing',
            data: [24916, 24064, 29742, 29851, 32490, 30282, 38121, 40434]
        }, {
            name: 'Sales & Distribution',
            data: [11744, 17722, 16005, 19771, 20185, 24377, 32147, 39387]
        }, {
            name: 'Project Development',
            data: [null, null, 7988, 12169, 15112, 22452, 34400, 34227]
        }, {
            name: 'Other',
            data: [12908, 5948, 8105, 11248, 8989, 11816, 18274, 18111]
        }],
    
        responsive: {
            rules: [{
                condition: {
                    maxWidth: 500
                },
                chartOptions: {
                    legend: {
                        layout: 'horizontal',
                        align: 'center',
                        verticalAlign: 'bottom'
                    }
                }
            }]
        }
    
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script type="text/javascript" src="https://code.jquery.com/ui/1.12.0-beta.1/jquery-ui.min.js"></script>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.1.135/jspdf.min.js"></script>
    <script type="text/javascript" src="http://cdn.immex1.com/js/jspdf/plugins/jspdf.plugin.addimage.js"></script>
    <script type="text/javascript" src="http://cdn.immex1.com/js/jspdf/plugins/jspdf.plugin.standard_fonts_metrics.js"></script>
    <script type="text/javascript" src="http://cdn.immex1.com/js/jspdf/plugins/jspdf.plugin.split_text_to_size.js"></script>
    <script type="text/javascript" src="http://cdn.immex1.com/js/jspdf/plugins/jspdf.plugin.from_html.js"></script>
    <script src="https://code.highcharts.com/highcharts.js"></script>
    <script src="https://code.highcharts.com/modules/series-label.js"></script>
    <script src="https://code.highcharts.com/modules/exporting.js"></script>
    <script src="https://code.highcharts.com/modules/export-data.js"></script>
    <div id="container"></div>
     <button id="cmd">generate PDF</button>

Upvotes: 2

Views: 2035

Answers (2)

shikhar
shikhar

Reputation: 140

To get the content of the charts you need to convert the HTML part to canvas, download npm package html2canvas. There is an in built function html2canvas which takes element id as an argument and return the canvas. Returned canvas can be added to document using addImage function.

//you need to import html2canvas
import * as html2canvas from 'html2canvas'
$(function () {

$('#cmd').click(function () {
   var doc = new jsPDF();
   let chartelement = document.getElementById('container');

function tellMeWhenToReturn(){
return new Promise((resolve) => {
  const elementToPrint = document.getElementById(id) //The html element to become a pdf
  html2canvas(elementToPrint).then((canvas) => {
    const contentDataURL = canvas.toDataURL('image/png');
    resolve(contentDataURL );
  });
});
}

tellMeWhenToReturn().then((data)=>{
  doc.addImage(data, 'margin', 'widthimage', 'imageheight');
 });


    });  
});

Upvotes: 0

Wojciech Chmiel
Wojciech Chmiel

Reputation: 7372

To download the chart content you can use Highcharts exporting. To export on custom button click chart.exportChart method can be use:

$('#cmd').click(function() {
  chart.exportChart({
    type: 'application/pdf',
    filename: 'my-pdf'
  });
});

Notice, additionally exporting module has to be loaded after highcharts script.

Docs reference:
https://www.highcharts.com/docs/export-module/export-module-overview

Demo:
https://jsfiddle.net/wchmiel/ue3pav2g/1/


EDIT:

To download multiple charts using jspdf you have to follow this steps:

  1. send AJAX to Highcharts server with options for each of the charts. The return will be an URL to the image on the server.
  2. convert images from Highcharts server into base64 format. (You can use this approaches: https://stackoverflow.com/a/20285053/10077925)
  3. Add charts images, logo, footer to pdf using jspdf library and save the result.

Code:

  $('#cmd').click(function() {
    var obj = {
        options: JSON.stringify(chartOptions),
        type: 'image/png',
        async: true
      },
      exportUrl = 'https://export.highcharts.com/',
      imgContainer = $("#container"),
      doc = new jsPDF(),
      chartsLen = 1,
      imgUrl;

    var calls = [];

    for (var i = 0; i < chartsLen; i++) {
      calls.push({
        type: 'post',
        url: exportUrl,
        data: obj,
      });
    }

    $.when(
      $.ajax(calls[0])
    ).done(function(c1) {

      imgUrl = exportUrl + c1;

      toDataURL(imgUrl)
        .then(dataUrl => {
          doc.setFontSize(30);
          doc.text(35, 25, 'First caption');
          doc.addImage(dataUrl, 'PNG', 15, 40);
          doc.text(35, 175, 'Second caption');
          doc.addImage(dataUrl, 'PNG', 15, 185);
          doc.save('sample-file.pdf');
        })
    });
  });

Demo: https://jsfiddle.net/wchmiel/4a8u16ck/1/

Upvotes: 1

Related Questions