Wkhtmltopdf不呈现Chart.JS 2.5.0图形

rbpvctlc  于 2023-01-26  发布在  Chart.js
关注(0)|答案(9)|浏览(272)

使用

WKpdftohml版本0.12.3.2
PHPwkhtmltopdf版本2.2.0
图表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;">添加到画布html标记的父div
  • 在图表的javascript初始化中添加了ctx.canvas.width = 800;ctx.canvas.height = 200;

我喜欢Chart.JS和WKhtmltopdf,但是如果我不能打印,我将不得不放弃其中的一个。有什么解决办法吗?
这是我的php代码的PHPwkhtmltopdf:

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');

}

#更新1

制作了一个带有页面输出的php文件。在浏览器中运行它,图形就会呈现出来。当我在控制台中做的时候,它会呈现除了图形之外的所有东西!
它怎么可能是wkhtmltopdf呈现这个页面中的图形:http://netdna.webdesignerdepot.com/uploads7/easily-create-stunning-animated-charts-with-chart-js/chartjs-demo.html但不是我自己的?!

g6baxovj

g6baxovj1#

下面是适用于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
t1rydlwq

t1rydlwq2#

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

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

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

mfuanj7w

mfuanj7w3#

尝试添加此内容,如this github source所示

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

b1payxdu4#

通过降级wkhtmltopdf解决了这个问题:0.12.4〉0.12.2.1chart.js版本好像没什么影响,我用的是2.7.0,好像还需要固定宽度和高度。
编辑:由于wkhtmltopdf已经死了,我最近换了《 puppet 戏》。

oknrviil

oknrviil5#

我也在处理同样的问题,使用Rotativa将我的ASP.NET MVC页面与ChartIdeJS导出到PDF,但没有运气。
几天后,我终于找到了一个超级简单的解决方案来实现我的目标。我所做的只是简单地使用Chart.JS的.toBase64Image()方法将图表编码为Javascript中的base64字符串变量。然后我将此字符串保存到一个模型中,然后在PDF html页面上保存一个used标记,在此我将base64encoded字符串放入scr属性中,结果非常好:-)
浏览器:

//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' />
wfsdck30

wfsdck306#

我也在纠结这个问题,你的自我回答对我的情况没有帮助。我正在使用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。
希望能有所帮助。

hvvq6cgz

hvvq6cgz7#

是的,我已经解决了这个问题,尝试使用Chartjs 1而不是新的图表js,因为laravel snappy使用wkhtmltopdf,它不支持css动画,而新的图表js使用css动画https://github.com/chartjs/Chart.js/issues/4767显示,我发现的解决方案是使用谷歌图表,它使用svg,所以你可以得到高分辨率的图表

q9rjltbz

q9rjltbz8#

我已经实现了这个问题的工作代码。你可以查看工作代码here
注:要生成pdf,您必须禁用Chart JS动画或将javascript-delay=>1000选项添加到wkhtmltopdf选项。

dtcbnfnu

dtcbnfnu9#

我正在尝试改进the answer by temuri,它很棒,但有点臃肿。我遇到了OP的问题(甚至是相同的WKpdftohml版本),这对我来说很有效:

<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js"></script>

<div style="width: 400px;"><canvas id="canvas"></canvas></div>

<script type="application/javascript">
    // wkhtmltopdf 0.12.5 crash fix.
    // https://github.com/wkhtmltopdf/wkhtmltopdf/issues/3242#issuecomment-518099192

    Function.prototype.bind = Function.prototype.bind || function (thisp) {
        const fn = this;
        return function () {
            return fn.apply(thisp, arguments);
        };
    };

    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":{}
        }
    );
</script>

我还没有弄清楚如何通过像npm这样的普通工具来获取图表库,而不是像第一行那样通过 AJAX 来获取,注意这会影响你的图表分辨率。

相关问题