使用Snappy在Laravel中的PDF上呈现LavaChart

问题描述

我正在尝试将snappy库与wkhtmltopdf结合使用,以在生成的PDF上呈现图表(LavaChart),但是我无法这样做。 PDF可以很好地生成,但图表不显示。如果视图未转换为PDF,则将按预期方式呈现图表。

下面是我的LavaChart和Snappy代码

图表部分

         $chart = Lava::ColumnChart('Performance',$table,[
            'title' => 'Performance Chart','png' => true,'animation' => [
               'startup' => true,'easing' => 'inAndOut'
            ],'titleTextStyle' => [
                'fontName' => 'Arial','fontColor' => 'blue'
            ],'legend' => [
                'position' => 'top'
            ],'vAxis' => [
                'title' => 'Total score'
            ],'hAxis' => [
                'title' => 'Class'
            ],'events' => [
                'ready' => 'getimageCallback'
            ],'colors' => ['#3366CC','#DC2912','#FF9900']
        ]);

快照部分

    $pdf = PDF::loadView('print.charts')->setPaper('portrait');
    $pdf->setoption('enable-javascript',true);
    $pdf->setoption('javascript-delay',10000);
    $pdf->setoption('no-stop-slow-scripts',true);
    $pdf->setoption('page-size','A4');
    $pdf->setoption('margin-left',0);
    $pdf->setoption('margin-right',0);
    $pdf->setoption('margin-top',0);
    $pdf->setoption('margin-bottom',0);
    $pdf->setoption('lowquality',false);
    $pdf->setTimeout(1500);
    $pdf->setoption('disable-smart-shrinking',true);

视图部分

    <script type="text/javascript">
        function getimageCallback (event,chart) {
            console.log(chart.getimageURI());
        }
    </script>

 <div id="chart" style="margin: 10px; height: 200px; width: 50%;"></div>
 {!! Lava::render('ColumnChart','Performance','chart') !!}    

由于在视图未转换为pdf时图表将按预期呈现,因此我有理由相信wkhtmltopdf不会执行pdf版本中期望的javascript。我安装了最新的wkhtmltopdf,但还是没有运气。

库版本:

barryvdh/laravel-snappy: ^0.4.3
khill/lavacharts: 3.0.*

感谢您的任何帮助。

解决方法

我可以用一个简单的示例显示,首先,我在浏览器上显示了图表,该图表示例摘自Lavacharts文档(您可以使用您的文档)。保持注意 events和回调getImageCallback

public function index(){
        $lava = new Lavacharts;
        $data = $lava->DataTable();

        $data->addDateColumn('Day of Month')
            ->addNumberColumn('Projected')
            ->addNumberColumn('Official');

        // Random Data For Example
        for ($a = 1; $a < 20; $a++) {
            $rowData = [
            "2020-10-$a",rand(800,1000),1000)
            ];

            $data->addRow($rowData);
        }

        $lava->LineChart('Stocks',$data,[
            'elementId' => 'stocks-div','title' => 'Stock Market Trends','animation' => [
                'startup' => true,'easing' => 'inAndOut'
            ],'colors' => ['blue','#F4C1D8'],'events' => [
                'ready' => 'getImageCallback'
            ]
        ]);

        return view('charts-view',['lava' => $lava]);
    }

在视图图表视图中,

 <div id="stocks-div">
        <?= $lava->render('LineChart','Stocks','stocks-div'); ?>
    </div>
    <form action="{{ url('export-pdf') }}" method="post">
        @csrf
        <div class="form-group">
            <input type="hidden" name="exportpdf" id="exportPDF">
            <button class="btn btn-info" type="submit">Export as PDF</button>
        </div>
    </form>
    <script type="text/javascript">
        function getImageCallback (event,chart) {
            console.log(chart.getImageURI());
            document.getElementById("exportPDF").value = chart.getImageURI();
        }
    </script>

请注意,脚本中的函数名称必须与控制器中ready中的events键设置的值相同。到目前为止,您也已经完成了。我已经将获得的结果作为隐藏的输入字段传递了并将表单发布到控制器。您可以在图表按钮export as PDF中看到。 enter image description here


URL export-pdf调用控制器函数exportPdf,该函数最终将生成PDF。您需要将图像(以data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAB .....获得)传递给控制器​​,以将其作为图像传递给视图。

exportPdf 中,

      public function exportPdf(Request $request){
        $imageData = $request->get('exportpdf');
        $pdf = SnappyPDF::loadView('export-pdf',['imageData' => $imageData])->setPaper('a4')->setOrientation('portrait');
        $pdf->setOption('lowquality',false);
        $pdf->setTimeout(1500);
        $pdf->setOption('disable-smart-shrinking',true);
        return $pdf->download('stock-market.pdf');                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
    }

export-pdf刀片视图

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Stock Market</title>
</head>
<body>
    <div class="container">
        <div class="col">
            <h2>Stock Market Detail</h2>
        </div>
        <div class="col">
            <h4>Oct 2020</h4>
        </div>    
    </div>
    <img src="{{ $imageData }}" alt="image" width="720" height="230">
</body>
</html>

获得的最终PDF看起来像, enter image description here