Я использую PhantomJS для печати веб-страницы, включая несколько элементов, таких как текст и диаграммы (в ChartJS). Тексты выглядят нормально, но диаграммы и изображения выглядят зашумленными и пиксельными. Видеть:
Обратите внимание, как пикселируются границы диаграммы. Это должна быть проблема растеризации PhantomJS, но не найдено никаких настроек для повышения качества сгенерированного PDF-файла или процесса растеризации.
Я пытался:
page.dpi = 200;. Похоже, не имеет никакого эффекта.page.property('dpi', 200);. То же, никакого эффекта.page.property('viewportSize', { width: 1920, height: 1080 });. Увеличивает размер экрана, но качество остается прежним.Это мой текущий сценарий:
const phantom = require('phantom');
let url = "http://localhost:3000/";
phantom.create().then(function(ph) {
ph.createPage().then(function(page) {
page.property('viewportSize', { width: 1920, height: 1080 });
page.property('dpi', 200); //No effect?
page.dpi = 200; //No effect?
page.property('paperSize', { format: 'Letter', orientation: 'portrait' });
//page.property('zoomFactor', 3.5); //Works erratically
page.open(url).then(function(status) {
setTimeout(function () {
page.render("output-" + Date.now() + ".pdf", { format: "pdf" }).then(function() {
console.info('Page Rendered');
ph.exit();
});
}, 3000); //Change timeout as required to allow sufficient time
});
});
});





Я не знаком с PhantomJS.
У меня была аналогичная проблема, и я решил ее, установив ширину и высоту контейнера, содержащего диаграмму.
<div id = "container" style = "width: 1920px; height: 1080px;">
<canvas id = "canvas"></canvas>
</div>
я также добавил невидимый тег изображения без источника
<img src = "" alt = "Chart" id = "chartImg" style = "display: none;"/>
и зарегистрировал плагин
Chart.plugins.register({
id: 'charttoimg',
beforeRender: function(chart, options) {
document.getElementById('container').style.width='1920px';
document.getElementById('container').style.height='1080px';
},
afterRender: function(chart, options) {
document.getElementById('chartImg').src=chart.chart.canvas.toDataURL('image/png');
document.getElementById('container').style.width='75%';
document.getElementById('container').style.height='';
}
});
с помощью следующего метода я захватил событие печати, чтобы переключить изображение и контейнер до и после печати
(function() {
var beforePrint = function() {
document.getElementById('container').style.display='none';
document.getElementById('chartImg').style.display='inline';
};
var afterPrint = function() {
document.getElementById('chartImg').style.display='none';
document.getElementById('container').style.display='block';
};
if (window.matchMedia) {
var mediaQueryList = window.matchMedia('print');
mediaQueryList.addListener(function(mql) {
if (mql.matches) {
beforePrint();
} else {
afterPrint();
}
});
}
window.onbeforeprint = beforePrint;
window.onafterprint = afterPrint;
}());
Теперь в 2021 году в Chart.js появился параметр devicePixelRatio для повышения качества. В моем случае я установил значение 1,5, чтобы получить высокое разрешение, которое также подходит для печати в формате PDF.
options:{
devicePixelRatio: 1.5
}
Документация: https://www.chartjs.org/docs/3.0.2/configuration/device-pixel-ratio.html