6

使用
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 库执行此操作时。我得到一个空白页。
根据我的研究,这些是我尝试过的事情:

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

好吧,没有任何效果。我喜欢 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');

}  

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

4

8 回答 8

20

这是适用于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
于 2019-08-11T23:42:32.413 回答
15

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

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

这个提议是在这个网站上找到的: Github,所以感谢 laguiz。

于 2017-03-03T09:14:55.230 回答
5

尝试添加这个,

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

它对我有用。

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

于 2018-11-01T12:42:50.203 回答
2

降级解决了 wkhtmltopdf: 0.12.4 > 0.12.2.1 chart.js 版本好像没有影响。我用的是 2.7.0。似乎也需要固定的宽度和高度。

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

于 2018-03-13T12:34:22.300 回答
2

我正在处理同样的问题,使用 rotativa 将带有 Chart.JS 的 ASP.NET MVC 页面导出为 PDF,但没有成功。

几天后,我终于找到了一个超级简单的解决方案来实现我的目标。我所做的只是使用 Chart.JS 的 .toBase64Image() 方法将图表编码为 Javascript 中的 base64 字符串变量。然后我将此字符串保存到模型中,然后在 PDF html 页面上使用了一个标签,在其中我将 base64 编码的字符串放入 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' />
于 2020-08-25T16:29:04.250 回答
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。

希望有帮助。

于 2017-12-14T21:45:35.673 回答
0

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

于 2018-01-03T15:28:55.947 回答
0

我已经为这个问题实现了工作代码。您可以在此处查看工作代码。

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

于 2020-02-12T12:42:24.023 回答