Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google charts are not showing in Snappy PDF

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.

like image 690
moh96 Avatar asked Jun 17 '20 16:06

moh96


People also ask

How do I save a Google graph as a PDF?

Use google method chart. getImageURI() to get image url then store into the variable after using jquery to submit form. Get HTML data to get images url and store into the images folder, and then retrieve images and content. print into pdf using mpdf.

Is Google Charts deprecated?

While the dynamic and interactive Google Charts are actively maintained, we officially deprecated the static Google Image Charts way back in 2012. This gives us the right to turn it off without notice, which may happen soon.


2 Answers

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.

like image 106
phpd Avatar answered Oct 20 '22 20:10

phpd


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
like image 3
Florian Doyen Avatar answered Oct 20 '22 20:10

Florian Doyen