Generate/export table+graph in highcharts in PDF f

2019-08-20 08:17发布

问题:

One way to do this is use drawing API and then draw table line by line while exporting PDF. Is there any other way like render html (table ) code into PDF or create table row and column wise, so that it would be easier to format or update table.

回答1:

Unfortunately, it is the only solution with pure Highcharts library:

Highcharts docs: https://www.highcharts.com/docs/getting-started/frequently-asked-questions/#add-data-table.

However, more complex pdfs with multiple charts and additional elements like tables, images, titles, etc can be made following this approach:

  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 these approaches: https://stackoverflow.com/a/20285053/10077925)
  3. Add charts images, tables, titles, etc to pdf using the jspdf library and save the result.

Code:

$(function() {

  const toDataURL = url => fetch(url)
    .then(response => response.blob())
    .then(blob => new Promise((resolve, reject) => {
      const reader = new FileReader()
      reader.onloadend = () => resolve(reader.result)
      reader.onerror = reject
      reader.readAsDataURL(blob)
    }))

  var chartOptions = {

    title: {
      text: 'Solar Employment Growth by Sector, 2010-2016'
    },

    subtitle: {
      text: 'Source: thesolarfoundation.com'
    },
    
    exporting: {
    	showTable: true
    },

    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'
          }
        }
      }]
    }

  };
  
  var chart = Highcharts.chart('container', chartOptions),
  	chartRows = chart.getDataRows();

  var specialElementHandlers = {
    '#editor': function(element, renderer) {
      return true;
    }
  };

  $('#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, 'PDF Title');
          doc.addImage(dataUrl, 'PNG', 15, 40);

					doc.autoTable({
          	startY: 180,
            head: [chartRows[0]],
            body: chartRows.filter((elem, i) => {
            	if (i !== 0) {
              	return elem;
              }
            })
          });

          doc.save('sample-file.pdf');
        })
    });
  });

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<script src="https://unpkg.com/jspdf"></script>
<script src="https://unpkg.com/jspdf-autotable"></script>

<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="https://code.highcharts.com/modules/export-data.js"></script>
<div class="chart-outer">
    <div id="container"></div>
    <!-- data table is inserted here -->
</div>
<br><br>
<button id="cmd">generate PDF</button>

Demo:

  • https://jsfiddle.net/BlackLabel/tzcujfyv/