Google charts are not showing in Snappy PDF
Asked Answered
D

2

10

I am trying to load a chart then convert it to PDF using Laravel-snappy

Here is the code I am using to generate the pdf:

$pdf = SnappyPDF::loadView('report', []);
$pdf->setOption('enable-javascript', true);
$pdf->setOption('no-stop-slow-scripts', true);
$pdf->setOption('page-size', 'A4');
$pdf->setOption('lowquality', false);
$pdf->setOption('disable-smart-shrinking', true);
$pdf->setOption('images', true);
$pdf->setOption('window-status', 'ready');
$pdf->setOption('run-script', 'window.setTimeout(function(){window.status="ready";},5000);');
return $pdf->inline();

And here is the HTML/CSS report.blade.php:

<head>
    <script src="http://www.gstatic.com/charts/loader.js"></script>
    <script>
      function init() {
        google.charts.load('current', {packages: ['corechart']});
        var interval = setInterval(function () {
          if (google.visualization !== undefined && google.visualization.DataTable !== undefined 
            && google.visualization.PieChart !== undefined) {
            clearInterval(interval);
            window.status = 'ready';
            drawChart();
          }
        }, 100);
      }

      function drawChart() {
        // Define the chart to be drawn.
        var data = new google.visualization.DataTable();
        data.addColumn('string', 'Element');
        data.addColumn('number', 'Percentage');
        data.addRows([
          ['Nitrogen', 0.78],
          ['Oxygen', 0.21],
          ['Other', 0.01]
        ]);

        var chart = new google.visualization.PieChart(document.getElementById('myPieChart'));
        chart.draw(data, {});
      }
    </script>
</head>
<body onload="init()">
<div id="myPieChart" style="width: 500px; height: 500px;"></div>
</body>

The PDF output is always returning a blank page.

Devonian answered 17/6, 2020 at 16:12 Comment(1)
I'm facing the same problem here. Since few weeks (begin of June 2020 ?) my charts doesn't render anymore with wkhtmltopdf using laravel-snappy (Laravel 5.7). It worked before, but now it doesn't. The "funny" fact is that when I render the page on the web (not as a PDF), charts are OK and rendering well. But since I use this package, it doesn't works anymore. Didn't find a solution yet...Yoo
L
4

I had this same issue - getting blank chart or an error message 'Undefined is not a function.'.

After 3 days of trying all possible options, what worked for me is to "revert" back to an old Google Charts version.

<script>google.load("visualization", "44", {packages:["corechart"]});</script>

I was previously using "1" for the version number. And just found out that using version "1" now means you are using the current version! From Google Charts document - "All 'jsapi' requests are now being redirected to the new loader. If you were loading version '1' or '1.0', you will now be loading 'current'."

Have also tried version 45, and it fails in case too. Looks like the newer versions have loading problems with wkhtmlpdf.

Laurentium answered 28/7, 2020 at 10:22 Comment(0)
Y
3

Try this : Thanks to https://github.com/barryvdh/laravel-snappy/issues/255#issuecomment-628815194

<script type="text/javascript" src="http://www.google.com/jsapi"></script>

    <script type="text/javascript">

        spandata = document.getElementsByClassName("spandata")
        spandatadate = document.getElementsByClassName("spandatadate")
        function init() {
          google.charts.load('current', {packages: ['corechart']});
          var interval = setInterval(function() {
            if ( google.visualization !== undefined && google.visualization.DataTable !== undefined && google.visualization.PieChart !== undefined ){ clearInterval(interval);
              window.status = 'ready';
              drawCharts();
            }
          }, 100);
        }



        function drawCharts() { // PROCESSING ... }
</script>

Where drawCharts() is your function that process the drawing, etc.

It finally worked for me, so... I hope it will work for you !

I'm still not able to know what is the problem, but I guess it's because the chart API can't be loaded fast, so wkhtmltopdf is processing the convert BEFORE the chart load. Waiting the DOM to be ready + set an interval seems to fix the problem (for now!)


EDIT 21/06/2020

Forgot to tell : http://www.google.com/jsapi redirect to an HTTPS page for gstatic (https://www.gstatic.com/charts/loader.js) which is the new place for the JS API Google. So, if you want wkhtmltopdf works, you need to install the libssl package

sudo apt-get install libssl1.0-dev

You can try if it works with

wkhtmltopdf https://google.com google.pdf

If not, you will have this kind of output :

Loading pages (1/6)
QSslSocket: cannot resolve CRYPTO_num_locks                  ] 10%
QSslSocket: cannot resolve CRYPTO_set_id_callback
QSslSocket: cannot resolve CRYPTO_set_locking_callback
QSslSocket: cannot resolve sk_free
QSslSocket: cannot resolve sk_num
QSslSocket: cannot resolve sk_pop_free
QSslSocket: cannot resolve sk_value
QSslSocket: cannot resolve SSL_library_init
QSslSocket: cannot resolve SSL_load_error_strings
QSslSocket: cannot resolve SSLv3_client_method
QSslSocket: cannot resolve SSLv23_client_method
QSslSocket: cannot resolve SSLv3_server_method
QSslSocket: cannot resolve SSLv23_server_method
QSslSocket: cannot resolve X509_STORE_CTX_get_chain
QSslSocket: cannot resolve OPENSSL_add_all_algorithms_noconf
QSslSocket: cannot resolve OPENSSL_add_all_algorithms_conf
QSslSocket: cannot resolve SSLeay
QSslSocket: cannot call unresolved function CRYPTO_num_locks
QSslSocket: cannot call unresolved function CRYPTO_set_id_callback
QSslSocket: cannot call unresolved function CRYPTO_set_locking_callback
QSslSocket: cannot call unresolved function SSL_library_init
QSslSocket: cannot call unresolved function SSLv23_client_method
QSslSocket: cannot call unresolved function sk_num
QSslSocket: cannot call unresolved function SSLv23_client_method
QSslSocket: cannot call unresolved function SSL_library_init
Error: Failed loading page https://google.com (sometimes it will work just to ignore this error with --load-error-handling ignore)
Exit with code 1 due to network error: UnknownNetworkError
QSslSocket: cannot call unresolved function CRYPTO_num_locks
QSslSocket: cannot call unresolved function CRYPTO_set_id_callback
QSslSocket: cannot call unresolved function CRYPTO_set_locking_callback

After installing the libssl, the output for the google.pdf test should be

Loading pages (1/6)
Counting pages (2/6)                                               
Resolving links (4/6)                                                       
Loading headers and footers (5/6)                                           
Printing pages (6/6)
Done 

I'm using:

Laravel 5.7
PHP 7.1.3
barryvdh/laravel-dompdf ^0.8.5
barryvdh/laravel-snappy ^0.4.6
wkhtmltopdf 0.12.4 (with patched qt)
Ubuntu 18.04 LTS
Yoo answered 21/6, 2020 at 16:41 Comment(3)
Which wkhtmltopdf version are you using?Devonian
I solved my issue by installing wkhtmltopdf 0.12.6 (with patched qt). As you said in your answer the issue is because of using https.. which is fixed in this version. Thank you!Devonian
@Devonian glad to see it solved your problem, don't hesitate to auto answer your question which the solution and validate it, it could help others. Or you can also validate mine if it helped you ! Have a nice day !Yoo

© 2022 - 2024 — McMap. All rights reserved.