我正尝试从前端的javascript的highcharts SVG输出中,将包含希腊语和拉丁语字符的公式打印到php后端的TCPDF中。
这是SVG文件的相关部分:
β(ϴᶜ)m-¹ sr-¹
当渲染到pdf时,其打印如下:
?(??)m-1 sr-1
我也将这些字符渲染为pdf页面上的文本,并且效果很好。
这是初始化代码:
parent::__construct('P', 'mm','Letter', true, 'UTF-8', false, true);
我正在使用自定义的TTF字体:
$this->documentFont = \TCPDF_FONTS::addTTFfont($ttfFont, 'TrueTypeUnicode',
'', 96);
调用打印单元格的代码,可以正确地将扩展的UTF-8字符集呈现在00FF以上:
$this->WriteHTMLCell($x, $y, $this->text);
这是渲染highcharts SVG的调用,它不能正确渲染00FF以上的字符:
$this->ImageSVG('@'.$image, $x, $y, $width, $height);
要变通,我发现了与UTF-8的00FF子集中所需的字符类似的字符:
ß(Øc)m-¹ sr-¹
这不是完美的,但是作为一种变通方法,它可以起作用,直到我弄清楚为什么SVG渲染不能正确打印00FF以上的Unicode字符。
我尝试在00FF以上的unicode范围内向Highchart轴添加字符。这就是我发现这似乎是SVG渲染器将打印内容的上限的方式。
我还尝试确保在PDF渲染器的前端和后端使用相同的字体。 PDF渲染器中使用的自定义TTF字体与我指定用于前端,CSS和HighCharts配置的字体相同。
正如下面的代码所示,我还尝试使用unescape()从HighCharts包围SVG渲染器。
HighCharts渲染:
/**
* inserts a highchart line chart into the HTML document at specified point
* @param {HTMLElement} chartContainer where this chart is rendered to
* @param {object} chartConfig config object with chart options.
* @param {array} seriesData two dimensional array to plot
* @param {string} seriesName name of series being plotted
* @return {Highcharts} highcharts object to be inserted - allows later referencing
*/
function addChart(chartContainer, chartConfig, seriesData, seriesName)
{
return new Highcharts.Chart({
chart: {
animation: false,
type: 'line',
renderTo: chartContainer,
zoomType: 'y'
},
title: {
text: chartConfig.title
},
xAxis: {
title: {
text: 'DUT DATA - ' + chartConfig.uom
},
gridLineDashStyle: 'solid',
gridLineWidth: 2,
minorTicks: true,
minorGridLineDashStyle: 'longdash',
startOnTick: true,
endOnTick: true,
max: chartConfig.xMax,
min: chartConfig.xMin
},
yAxis: {
title: {
text: 'Residuals'
},
gridLineDashStyle: 'solid',
gridLineWidth: 2,
minorTicks: true,
minorGridLineDashStyle: 'longdash',
tickWidth: 2,
lineWidth: 1,
max: chartConfig.yMax,
min: chartConfig.yMin
},
plotOptions: {
line: {
animation: false
}
},
series: [{
name: seriesName,
point: {
events: {
click: function () {
console.log('Category: ' + this.category + ', value: ' + this.y);
}
}
},
animation: false,
showInLegend: true,
data: seriesData
}],
exporting: {
enabled: true
},
credits: {
enabled: false
}
});
}
SVG创建:
chart[i].svgData = unescape(chart[i].getSVG());
我希望TCPDF SVG渲染器能够打印整个UTF-8范围。看来SVG渲染器无法渲染00FF以上的字符。
答案 0 :(得分:1)
SVG解析器启动时要做的第一件事就是初始化SVG样式。这样,它将font-family
设置为Helvetica。因此,您需要确保在SVG中明确使用自定义字体。
我用Highcharts网站上的折线图进行了测试,并明确在每个font-family
和text
元素上设置了tspan
属性似乎可以解决问题。诚然,这是一个比较直截了当的解决方案,但是您可以使用它来使其更具针对性。我在下面提供了屏幕截图。 (Highcharts有时在style
属性中包含一个不同的字体系列,但是font-family
属性为我们提供了一种无需解析和更新style
属性字符串即可覆盖它的简便方法。)
<?php
$svgdom = new DOMDocument();
//My extract from Highcharts did not include the XML declaration, so I add it.
//TCPDF might assume it's UTF-8, so this may not be needed.
//[Edit: Checked, TCPDF does, but we're working on it before that stage I figure
//it's best to include the xml declaration if it's not already there.]
$svgdom->loadXML('<?xml version="1.0" encoding="utf-8" ?>'.$image);
$xpath = new DOMXPath($svgdom);
$textitems = $xpath->query('//*[local-name() = "text" or local-name() = "tspan"]');
foreach($textitems as $element) {
$element->setAttribute('font-family', $font);
}
$image = $svgdom->saveXML();
(我在下面的示例中使用了Dejavusans,只是将标题替换为测试文本。)