1

I need to generate pdf report including chartjs charts. I use https://v6.charts.erik.cat/ realisation for creating charts and https://github.com/mikehaertl/phpwkhtmltopdf for pdf generating.

$pdf = new Pdf($fileHtml);
$pdf->setOptions([
    'javascript-delay' => 10000,
]);
$pdf->saveAs(public_path($filePdf));

But chart looks like preloader into pdf file

html view

generated pdf

Roman Kutenko
  • 27
  • 1
  • 8
  • 1
    I'm not sure any PDF generator will handle the JS. I used to do the same thing with google map. I tricked by taking a [screenshot of the div with JS](https://stackoverflow.com/a/6887206/8068675), sent the image to the server with ajax, generate the PDF with that image and then sent the PDF in the response. – Clément Baconnier Oct 04 '20 at 21:45
  • 1
    Creating some kind of screen-shot service is indeed the most likely to succeed. Rest assured this question is a duplicate, because it's based on a common misconception. – Martin Zeitler Oct 04 '20 at 21:54

1 Answers1

4

Your best bet is probably to render the chart as an image with a Javascript-enabled renderer, and then add that image to your PDF.

Option 1: If you want to stick with headless rendering, you may need to add a --no-stop-slow-scripts option in addition to the Javascript delay (could also check out Puppeteer, an alternative renderer).

Option 2: Use a service that renders charts to image or PDF. QuickChart is an open-source web service that does this (I am one of its maintainers).

For example, take your Chart.js config:

$chartConfig = '{
  "type": "bar",
  "data": {
    "labels": [2012, 2013, 2014, 2015, 2016],
    "datasets": [{
      "label": "Users",
      "data": [120, 60, 50, 180, 120]
    }]
  }
}';

Pack it into a URL with the /chart endpoint:

$chartUrl = 'https://quickchart.io/chart?w=500&h=300&c=' . urlencode($chartConfig);

And then include the resulting URL as an image in your wkhtmltopdf page:

<img src="https://quickchart.io/chart?w=500&h=300&c=%7B%0A++%22type%22%3A+%22bar%22%2C%0A++%22data%22%3A+%7B%0A++++%22labels%22%3A+%5B2012%2C+2013%2C+2014%2C+2015%2C+2016%5D%2C%0A++++%22datasets%22%3A+%5B%7B%0A++++++%22label%22%3A+%22Users%22%2C%0A++++++%22data%22%3A+%5B120%2C+60%2C+50%2C+180%2C+120%5D%0A++++%7D%5D%0A++%7D%0A%7D" />

This will render your chart without any Javascript.

If you want an even simpler way and you're ok with a PDF that shows only the chart, add &format=pdf to the URL and the service will directly generate a PDF of your chart: example PDF

Note that you can self-host the chart render web service if necessary.

ty.
  • 10,924
  • 9
  • 52
  • 71