You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用PDFMake导出SVG时箭头符号无法正常显示问题求助

问题:Highcharts SVG导出PDF时特殊箭头符号显示异常

在使用Highcharts生成图表SVG后,通过PDFMake导出为PDF时遇到符号显示问题:绿色向上箭头▲(Unicode U+25B2)在PDF中显示为绿色方框,但使用↑(Unicode U+2191)时则显示正常。


Highcharts箭头相关代码

series: [           
        {
            type: 'waterfall',
            upColor: Highcharts.getOptions().colors[2],
            color: Highcharts.getOptions().colors[3],
            dataLabels: {
                enabled: true,
                inside: false,
                style: {
                    textOutline:'none'
                },
                formatter() {
                    const { value=null } = getValue(this.key);
                    const isZeroVal = !this.y;
                    const zeroValCss = isZeroVal ? 'margin-top: -8px;': '';                       
                    let greenArrow = '<span style="color: green;">&#x25B2;</span>';
                    let redArrow = '<span style="color: red;">&#x25BC;</span>';                       
                    return `
                        <div style='text-align:center;color:black;${zeroValCss}'>
                            ${isZeroVal ? (!fullBars.includes(this.point.code) ? 'No Change' : value): value}
                            ${value?.includes('+') ? greenArrow : value?.includes('-') ? redArrow : ''}
                        </div>
                    `;
                }
            },
            data: scoreData?.filter(pb => !nonWaterfall.includes(pb.code)) || [],
            pointPadding: 0
        }
    ]
  };

PDFMake导出代码

import util from '../utilities/credit-report-util.js';
import pdfUtil from '../utilities/pdfmake-util';

const scoreBreakDown = () => [pdfUtil.table({
widths: ['100%'],
body: [
    [{ text: 'Score Breakdown', style: 'rgPlusBlack', border: [true, true, true, false], margin: [0, 2, 0, 0] }],
    [{ svg: util.getSVGToEmbedPDF($('.rgPlus-ScoreBreakdownChart .highcharts-container svg')), border: [true, false, true, true], alignment: 'center', margin: [0, 4, 0, 0], width: 400, height: 85 }]
   ]
}, { defaultBorder: false, borderWidth: 1, borderColor: borderColor(true) })];

const getSVGToEmbedPDF = (svgelm, viewBoxHeight, viewBoxWidth, width = '100%', height = '100%', trimSvg = false, useStrokeForBold = false, preserveAspectRatio = false) => {
if (svgelm.length) {
    const isBMChartSvg = svgelm.closest('.ca-m-bench-chart')?.length > 0;
    let cloneSvgElm = svgelm.clone(true);
    const actualWidth = cloneSvgElm.attr('width');
    const actualHeight = cloneSvgElm.attr('height');
    cloneSvgElm[0].setAttribute('viewBox', `0 0 ${viewBoxWidth || actualWidth} ${viewBoxHeight || actualHeight}`);
    cloneSvgElm.attr('width', width);
    cloneSvgElm.attr('height', height);
    if (preserveAspectRatio)
        cloneSvgElm[0].setAttribute('preserveAspectRatio', `none`);
    replaceImageTagToSVG(cloneSvgElm, isBMChartSvg);
    if (useStrokeForBold)
        addStrokeForBold(cloneSvgElm);
    if (trimSvg)
        cloneSvgElm[0].setAttribute('preserveAspectRatio', 'xMinYMin slice');
    return new XMLSerializer().serializeToString(cloneSvgElm[0]);
 }
 return emptySvg; //Fallback in case svg is not created
};

异常SVG示例(▲显示为方框)

<svg>
 <g class="highcharts-label highcharts-data-label highcharts-data-label-color-undefined" data-z-index="1" transform="translate(508,48)"><text x="5" data-z-index="1" y="16" style="color:#000000;font-size:11px;font-weight:bold;fill:#000000;"><tspan style="text-align:center;fill:black;">
+9
<tspan style="fill: green;">▲</tspan>
 </tspan></text></g>
</svg>

正常SVG示例(↑显示正常)

<svg>
  <g class="highcharts-label highcharts-data-label highcharts-data-label-color-undefined" data-z-index="1" transform="translate(508,48)">
<text x="5" data-z-index="1" y="16" style="color:#000000;font-size:11px;font-weight:bold;fill:#000000;">
<tspan style="text-align:center;fill:black;">
  +9
  <tspan style="fill: green;">↑</tspan>
 </tspan>
 </text>
 </g>
</svg>

解决方法

原因分析

▲(U+25B2)属于方块元素类符号,PDFMake依赖的底层渲染引擎默认使用的字体可能不包含该符号的字形,导致无法渲染显示为方框;而↑(U+2191)属于常用箭头符号,多数基础字体都包含其字形。

方案1:替换为兼容符号

直接将代码中的&#x25B2;(▲)替换为&#x2191;(↑),或使用其他PDF渲染引擎支持的箭头符号,如&#x21D7;(↗)等。修改Highcharts formatter中的箭头定义:

let greenArrow = '<span style="color: green;">&#x2191;</span>';
let redArrow = '<span style="color: red;">&#x2193;</span>';

方案2:嵌入包含目标符号的字体

如果必须使用▲符号,需在PDFMake中嵌入支持该符号的字体(如Arial Unicode MS、Noto Sans等):

  1. 将字体文件(如.ttf)放入项目目录
  2. 在PDFMake配置中注册字体:
pdfMake.fonts = {
  NotoSans: {
    normal: 'NotoSans-Regular.ttf',
    bold: 'NotoSans-Bold.ttf',
    italics: 'NotoSans-Italic.ttf',
    bolditalics: 'NotoSans-BoldItalic.ttf'
  }
};
  1. 修改Highcharts dataLabels的style,添加字体设置:
style: {
  textOutline:'none',
  fontFamily: 'NotoSans'
}

方案3:将符号转为SVG图形

不使用文本符号,直接生成SVG箭头图形避免字体依赖:

// 替换箭头文本为SVG图形
let greenArrow = '<svg width="10" height="8"><polygon points="5,0 0,8 10,8" fill="green"/></svg>';
let redArrow = '<svg width="10" height="8"><polygon points="5,8 0,0 10,0" fill="red"/></svg>';

内容的提问来源于stack exchange,提问作者user13677598

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 06:55:56