Я пытаюсь использовать библиотеку snappy с wkhtmltopdf для визуализации диаграммы (LavaChart) в сгенерированном PDF-файле, но мне это не удалось. 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 не выполняет javascript, ожидаемый в версии pdf. У меня установлена ​​последняя версия wkhtmltopdf, но мне все равно не повезло.

Версия библиотеки:

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

Любая помощь будет оценена, спасибо.

0
BlackPearl 25 Окт 2020 в 06:10

1 ответ

Лучший ответ

Я могу показать на простом примере. Сначала я показал диаграмму в браузере. Пример диаграммы взят из документации 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), rand(800,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]);
    }

В представлении charts-view ,

 <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. введите описание изображения здесь


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-файл выглядит так: введите описание изображения здесь

2
bhucho 26 Окт 2020 в 16:18