Wkhtmltopdf не отображает график Chart.JS 2.5.0
Использование:
WKpdftohml версия 0.12.3.2
PHPwkhtmltopdf версия 2.2.0
Chart.JS версия 2.5.0
Я пытаюсь напечатать линейный график с использованием вышеуказанных библиотек. Я могу воспроизвести 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;">
html тегу родительского div холста - добавленной
ctx.canvas.width = 800;ctx.canvas.height = 200;
для javascript инициализации диаграммы.
Ну, ничего не сработало. Я люблю 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
но не мой?!
9 ответов
Вот код, который работает с 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
Нашел ответ. После того, как я создал отдельный файл вне фреймворка, я снова провел несколько тестов. Он отобразил график в браузере, поэтому я попытался использовать командный инструмент WKhtmltopdf, и он не сработал, как это было с другими примерами (см. Обновление № 1). Так что с моей страницей php что-то не так.
Запустил те же тесты, что и в рамках, и получил ответ на мою проблему. Введя размеры ширины родительского тега div в тег canvas, он сделал визуализацию графика на странице.
<div style="width:800px;height:200;">
<canvas id="myChart" style="width:800px;height:200;"></canvas>
</div>
Предложение было найдено на этом сайте: Github, так что спасибо laguiz.
Попробуйте добавить это,
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/7.0.0/polyfill.min.js"></script>
Это сработало для меня.
Источник: https://github.com/wkhtmltopdf/wkhtmltopdf/issues/2952
Решил это путем понижения wkhtmltopdf: 0.12.4 > 0.12.2.1
Версия chart.js, похоже, не имела никакого влияния. Я использовал 2.7.0.
Фиксированная ширина и высота, кажется, также необходимы.
Я имел дело с той же проблемой, используя rotativa для экспорта моей страницы ASP.NET MVC с Chart.JS в PDF, но безуспешно.
Через пару дней я наконец нашел супер-простое решение для достижения своей цели. Я просто использовал метод.toBase64Image() Chart.JS для кодирования диаграммы в строковую переменную base64 в Javascript. Затем я сохранил эту строку в модели, а затем на странице 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' />
Я пытаюсь улучшить ответ 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, как здесь, в первой строке. Обратите внимание, что это может повлиять на разрешение диаграммы.
Я тоже боролся с этим, и ты сам не ответил на мой вопрос. Я использую 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.
Надеюсь, это поможет.
Я реализовал рабочий код для этой проблемы. Вы можете посмотреть рабочий код здесь.
ПРИМЕЧАНИЕ. Для создания PDF необходимо отключить Chart JS
анимация или добавить опцию javascript-delay=>1000
к wkhtmltopdf
параметры.
Да, я решил эту проблему, попробуйте использовать Chartjs 1, а не новую диаграмму js, потому что laravel snappy использует wkhtmltopdf, который не поддерживает анимацию css, а новый chartjs использует анимацию css https://github.com/chartjs/Chart.js/issues/4767 покажите это, и решение, которое я нашел, состоит в том, чтобы использовать диаграмму Google, которая использует SVG, чтобы вы могли получить диаграмму высокого разрешения