KnpLabs/snappy 捆绑包 (wkhtmltopdf) 未呈现 Chart.js 图表
KnpLabs/snappy bundle (wkhtmltopdf) not render Chart.js charts
我试图用 Chart.js
库生成的图表生成 PDF
但是 javascript 根本不渲染。
你看到我遗漏了什么吗?
# config/packages/knp_snappy.yaml
knp_snappy:
pdf:
enabled: true
binary: '%env(WKHTMLTOPDF_PATH)%'
options:
debug-javascript: true
enable-javascript: true
javascript-delay: 200
no-stop-slow-scripts: true
image:
enabled: true
binary: '%env(WKHTMLTOIMAGE_PATH)%'
options: []
PHP Symfony 部分
/**
* Download pdf.
*
* @param string $slug
* @param string $language
*
* @return Response
*
* @throws \Psr\Cache\CacheException
* @throws \Psr\Cache\InvalidArgumentException
*/
public function __invoke(string $slug, string $language): Response
{
$this->pdfFilesService->setPdfLanguage($language);
$base64Images = $this->pdfFilesService->getBase64Images($slug);
$profile = $this->profileData->execute($slug, $language);
$filename = $profile['name'].'-report.pdf';
$path = $this->parameterBag->get('app.private_pdf_storage').'/'.$filename;
$html = $this->templating->render('download_pdf.twig', \array_merge($base64Images, [
'profile' => $profile,
'language' => $language,
]));
$this->pdf->generateFromHtml([$html], $path, [], true);
return new Response(
$path,
200,
[
'Content-Type' => 'application/pdf',
'Content-Disposition' => 'inline; filename="'.$path.'"',
]
);
}
树枝
<section>
<div id="barMulti"></div>
</section>
<script type="text/javascript" src="{{ chartJs }}"></script>
<script type="text/javascript">
function getDataMulti(type) {
return {
// The type of chart we want to create
type,
// The data for our dataset
data: {
labels: [ ... ],
datasets: [
{
backgroundColor: "#F4F7F9",
data: [3,7,4,5,5,2,6,8,9,7]
},
{
backgroundColor: "#66C4E0",
data: [3,7,4,5,5,2,6,8,9,7]
},
{
backgroundColor: "#009DCD",
data: [3,7,4,5,5,2,6,8,9,7]
},
]
},
// Configuration options go here
options: {
legend: {
display: false,
},
animation: {
duration: 0
},
scales: {
yAxes: [{
gridLines: {
color: "#454D57",
},
ticks: {
padding: 20,
fontStyle: 'bold',
fontColor: '#F4F7F9',
min: 0,
max: 100,
}
}],
xAxes: [
{
gridLines: {
color: "#454D57"
},
ticks: {
fontStyle: 'bold',
fontColor: '#F4F7F9',
padding: 20,
callback: function(label) {
if (/\s/.test(label)) {
return label.split(" ");
}
return label;
}
}
}
]
}
}
}
}
// var barMulti = document.getElementById('barMulti');
var barMulti = document.getElementById('barMulti');
new Chart(barMulti, getDataMulti('bar'));
</script>
wkhtmltopdf
is not a perfect library but it is opensource and free
to use, so we need to be grateful and try to help its usage or
improve by contributing.
作为第一步,您需要测试 HTML/TWIG 模板是否正常工作 Javascript。
<script>
document.body.innerHTML = "Testing JavaScript PDF Rendering"
</script>
如果这不起作用,请检查您的 wkhtmltopdf
配置
# config/packages/knp_snappy.yaml
knp_snappy:
pdf:
enabled: true
binary: '%env(WKHTMLTOPDF_PATH)%'
options:
debug-javascript: true
enable-javascript: true
javascript-delay: 1500
no-stop-slow-scripts: true
在您确定 Javascript 在 wkhtmltopdf
中工作后
最重要的事情。 你需要用 styled
div
包裹你的 canvas
元素
<div class="reportGraph">
<canvas id="barMulti"></canvas>
</div>
并在 head
或 css
中放置样式 class
.reportGraph {
width:850px
}
或者通过内联 css
样式 canvas 容器
然后在包含chart.js
库
之后添加这个脚本文件
<script>
// 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);
};
};
</script>
然后添加另一个 script
标签,您将在其中呈现图表。
<script>
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>
我试图用 Chart.js
库生成的图表生成 PDF
但是 javascript 根本不渲染。
你看到我遗漏了什么吗?
# config/packages/knp_snappy.yaml
knp_snappy:
pdf:
enabled: true
binary: '%env(WKHTMLTOPDF_PATH)%'
options:
debug-javascript: true
enable-javascript: true
javascript-delay: 200
no-stop-slow-scripts: true
image:
enabled: true
binary: '%env(WKHTMLTOIMAGE_PATH)%'
options: []
PHP Symfony 部分
/**
* Download pdf.
*
* @param string $slug
* @param string $language
*
* @return Response
*
* @throws \Psr\Cache\CacheException
* @throws \Psr\Cache\InvalidArgumentException
*/
public function __invoke(string $slug, string $language): Response
{
$this->pdfFilesService->setPdfLanguage($language);
$base64Images = $this->pdfFilesService->getBase64Images($slug);
$profile = $this->profileData->execute($slug, $language);
$filename = $profile['name'].'-report.pdf';
$path = $this->parameterBag->get('app.private_pdf_storage').'/'.$filename;
$html = $this->templating->render('download_pdf.twig', \array_merge($base64Images, [
'profile' => $profile,
'language' => $language,
]));
$this->pdf->generateFromHtml([$html], $path, [], true);
return new Response(
$path,
200,
[
'Content-Type' => 'application/pdf',
'Content-Disposition' => 'inline; filename="'.$path.'"',
]
);
}
树枝
<section>
<div id="barMulti"></div>
</section>
<script type="text/javascript" src="{{ chartJs }}"></script>
<script type="text/javascript">
function getDataMulti(type) {
return {
// The type of chart we want to create
type,
// The data for our dataset
data: {
labels: [ ... ],
datasets: [
{
backgroundColor: "#F4F7F9",
data: [3,7,4,5,5,2,6,8,9,7]
},
{
backgroundColor: "#66C4E0",
data: [3,7,4,5,5,2,6,8,9,7]
},
{
backgroundColor: "#009DCD",
data: [3,7,4,5,5,2,6,8,9,7]
},
]
},
// Configuration options go here
options: {
legend: {
display: false,
},
animation: {
duration: 0
},
scales: {
yAxes: [{
gridLines: {
color: "#454D57",
},
ticks: {
padding: 20,
fontStyle: 'bold',
fontColor: '#F4F7F9',
min: 0,
max: 100,
}
}],
xAxes: [
{
gridLines: {
color: "#454D57"
},
ticks: {
fontStyle: 'bold',
fontColor: '#F4F7F9',
padding: 20,
callback: function(label) {
if (/\s/.test(label)) {
return label.split(" ");
}
return label;
}
}
}
]
}
}
}
}
// var barMulti = document.getElementById('barMulti');
var barMulti = document.getElementById('barMulti');
new Chart(barMulti, getDataMulti('bar'));
</script>
wkhtmltopdf
is not a perfect library but it is opensource and free to use, so we need to be grateful and try to help its usage or improve by contributing.
作为第一步,您需要测试 HTML/TWIG 模板是否正常工作 Javascript。
<script>
document.body.innerHTML = "Testing JavaScript PDF Rendering"
</script>
如果这不起作用,请检查您的 wkhtmltopdf
配置
# config/packages/knp_snappy.yaml
knp_snappy:
pdf:
enabled: true
binary: '%env(WKHTMLTOPDF_PATH)%'
options:
debug-javascript: true
enable-javascript: true
javascript-delay: 1500
no-stop-slow-scripts: true
在您确定 Javascript 在 wkhtmltopdf
最重要的事情。 你需要用 styled
div
canvas
元素
<div class="reportGraph">
<canvas id="barMulti"></canvas>
</div>
并在 head
或 css
中放置样式 class
.reportGraph {
width:850px
}
或者通过内联 css
样式 canvas 容器然后在包含chart.js
库
<script>
// 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);
};
};
</script>
然后添加另一个 script
标签,您将在其中呈现图表。
<script>
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>