Wkhtmltopdf不呈现Chart.JS 2.5.0图

时间:2017-03-02 16:40:54

标签: chart.js phpwkhtmltopdf


WKpdftohml版本0.12.3.2
PHPwkhtmltopdf 2.2.0版 Chart.JS版本2.5.0

我正在尝试使用上述库打印折线图。我可以使用shell命令重现pdf:wkhtmltopdf --javascript-delay 5000 " http://netdna.webdesignerdepot.com/uploads7/easily-create-stunning-animated-charts-with-chart-js/chartjs-demo.html" test2.pdf
所以WKhtmltopdf没有问题。

问题是当我在我的应用程序中使用PHPwkhtmltopdf库时。我得到一个空白页面 根据我的研究,这些是我尝试的事情:

  • 向Chart.JS选项添加了'javascript-delay' => 500;
  • 向Chart.JS选项添加了animation:{onComplete: function () {window.JSREPORT_READY_TO_START =true};
  • <div style="width:800px;height:200;font-size:10px;">添加到canvas html标记的父div
  • 为图表的javascript初始化添加了ctx.canvas.width = 800;ctx.canvas.height = 200;

没有任何效果。我喜欢Chart.JS和WKhtmltopdf,但如果我不能打印,我将不得不放弃其中一个。有没有解决方案?

这是PHPwkhtmltopdf的PHP代码:

public function imprimir ($request, $response)
{
    // include_once 'config/constants.php';
    // include_once 'resources/auxiliar/helpers.php';

    $folha = $_POST['printit'];
    $variaveis = explode(',', $folha);

    $nomeFicheiro = $variaveis[0];

    $printName = substr($nomeFicheiro, 5);

    if (isset($variaveis[2])) {

        $_SESSION['mesNumero'] = $variaveis[2];
        $_SESSION['mes'] = $variaveis[1];

    } else {

        $mesNumero = 0;
        $mes = '';

    }

    ob_start();
    if ($nomeFicheiro == 'printPpiam') {
        require ('C:/xampp/htdocs/.../'.$nomeFicheiro.'.php');
    } else {
        require ('C:/xampp/htdocs/.../'.$nomeFicheiro.'.php');
    }
    $content = ob_get_clean();

    // You can pass a filename, a HTML string, an URL or an options array to the constructor
    $pdf = new Pdf($content);

    // On some systems you may have to set the path to the wkhtmltopdf executable
    $pdf->binary = 'C:/Program Files/wkhtmltopdf/bin/wkhtmltopdf';

    $pdf -> setOptions(['orientation' => 'Landscape',
                        'javascript-delay' => 500,
                        // 'enable-javascript' => true,
                        // 'no-stop-slow-scripts' => true]
                    ]);

    if (!$pdf->send($printName.'.pdf')) {
        throw new Exception('Could not create PDF: '.$pdf->getError());
    }

    $pdf->send($printName.'.pdf');

}  

#Update 1
用页面输出制作一个php文件。在浏览器中运行它并渲染图形。当我在控制台中执行此操作时,它会呈现除图形之外的所有内容! 怎么能wkhtmltopdf在这个页面中呈现图形:http://netdna.webdesignerdepot.com/uploads7/easily-create-stunning-animated-charts-with-chart-js/chartjs-demo.html但不是我自己的?!

8 个答案:

答案 0 :(得分:8)

找到答案。在框架之外创建了一个单独的文件后,我再次进行了一些测试。它在浏览器中呈现图形,所以我尝试使用命令工具WKhtmltopdf,并且当它与其他示例一起使用时它没有用(参见更新#1)。所以我的php页面有问题。
和我在框架中做的测试一样,得到了我的问题的答案。通过在canvas标记中引入父div标签宽度尺寸,它使图形在页面中呈现。

<div style="width:800px;height:200;">
    <canvas id="myChart" style="width:800px;height:200;"></canvas>
</div>

这个命题在这个网站上找到:Github,所以谢谢laguiz。

答案 1 :(得分:7)

以下是适用于wkhtmltopdf版本0.12.5的代码:

chart.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js"></script>
<style>
    .reportGraph {width:900px}
</style>
</head>
<body>

<div class="reportGraph"><canvas id="canvas"></canvas></div>

<script type="text/javascript">
// wkhtmltopdf 0.12.5 crash fix.
// https://github.com/wkhtmltopdf/wkhtmltopdf/issues/3242#issuecomment-518099192
'use strict';
(function(setLineDash) {
    CanvasRenderingContext2D.prototype.setLineDash = function() {
        if(!arguments[0].length){
            arguments[0] = [1,0];
        }
        // Now, call the original method
        return setLineDash.apply(this, arguments);
    };
})(CanvasRenderingContext2D.prototype.setLineDash);
Function.prototype.bind = Function.prototype.bind || function (thisp) {
    var fn = this;
    return function () {
        return fn.apply(thisp, arguments);
    };
};

function drawGraphs() {
    new Chart(
        document.getElementById("canvas"), {
            "responsive": false,
            "type":"line",
            "data":{"labels":["January","February","March","April","May","June","July"],"datasets":[{"label":"My First Dataset","data":[65,59,80,81,56,55,40],"fill":false,"borderColor":"rgb(75, 192, 192)","lineTension":0.1}]},
            "options":{}
        }
    );
}
window.onload = function() {
    drawGraphs();
};
</script>
</body>
</html>

运行:

$ wkhtmltopdf chart.html chart.pdf

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

答案 2 :(得分:1)

通过降级wkhtmltopdf来解决它:0.12.4&gt; 0.12.2.1 chart.js版似乎没有影响力。我使用2.7.0。 似乎也需要固定的宽度和高度。

编辑:由于wkhtmltopdf已经死了,我最近切换到Puppeteer。

答案 3 :(得分:1)

尝试添加此内容,

<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/7.0.0/polyfill.min.js"></script>

对我有用。

来源:https://github.com/wkhtmltopdf/wkhtmltopdf/issues/2952

答案 4 :(得分:1)

我当时正在使用rotativa处理同样的问题,将带有Chart.JS的ASP.NET MVC页面导出到PDF时没有运气。

几天后,我终于找到了实现目标的超简单解决方案。我所做的只是使用Chart.JS的.toBase64Image()方法将图表编码为Javascript中的base64字符串变量。然后,我将此字符串保存到模型中,然后在PDF html页面上使用了一个标签,在其中将base64encoded字符串放入scr属性中,结果很不错:-)

javascript:

//save Chart as Image
var url_base64 = document.getElementById('myChart').toDataURL('image/png');

//set the string as a value of a hidden element
document.getElementById('base64graph').value = url_base64;

PDF视图:

<img style='display:block; width:900px;height:400px;position:relative;margin:auto;text-align:center;' id='base64image'
         src='@Model.base64graph' />

答案 5 :(得分:0)

我也对此感到不安,你的自我答案对我的情况没有帮助。我使用symfony 3.3和Chart.js 2,无论我做了什么,都没有正常工作。所以我以不同的方式解决了它(也许不是一个干净的方式),我想在这里发布它以吸引他人。

我需要导出一个页面,我在浏览器中向用户呈现。在浏览器中,我使用Javascript通过

从渲染图中获取图片
animation: {
                onComplete: function(animation) {
                    console.log('done');
                    var url=document.getElementById("barChartByCountryWeight{{ part }}{{ subsetKey }}").toDataURL();
                    $.ajax({
                        url: 'saveChartImages',
                        type: 'POST',
                        data: { 'barChartByCountryWeight{{ part }}{{ subsetKey }}': url },
                        success: function(result) {
                            console.log(result);
                            console.log('the request was successfully sent to the server');
                        },
                        error: function (request, error) {
                            console.log(arguments[0]['responseText']);
                            console.log(" Can't do because: " + error);
                        }
                    });

                }
            }

在服务器端,我把它放在会话和控制器中进行PDF导出,我从会话中获取了图像并将图像放在HTML中,然后转换为PDF。

希望有所帮助。

答案 6 :(得分:0)

是的,我解决了这个问题 尝试使用 Chartjs 1 而非新图表js 因为laravel snappy使用不支持css动画的wkhtmltopdf 新的chartjs使用css动画 https://github.com/chartjs/Chart.js/issues/4767表明了这一点 我找到的解决方案是使用使用svg的谷歌图表,这样你就可以获得高分辨率图表

答案 7 :(得分:0)

我已经实现了此问题的工作代码。您可以签出工作代码here

注意:要生成pdf,必须禁用Chart JS动画或将选项javascript-delay=>1000添加到wkhtmltopdf选项中。