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

如何用html2canvas导出带正确Poppins字体的D3图表为PNG?

解决Vue3+D3图表导出PNG时Poppins字体不显示的问题

核心原因

html2canvas无法正确加载远程CDN字体,或字体未在渲染完成前加载完毕;html-to-image因频繁请求CDN字体触发429限流。

解决方案

1. 改用本地字体加载(彻底解决字体请求问题)

将Poppins字体文件下载到项目的public/font目录(比如Poppins-Regular.ttf、Poppins-Bold.ttf等),然后在全局CSS中通过@font-face引入:

@font-face {
  font-family: 'Poppins';
  src: url('/font/Poppins-Regular.ttf') format('truetype');
  font-weight: 400;
  font-style: normal;
  font-display: swap; /* 确保字体加载不阻塞渲染,且优先使用本地字体 */
}

@font-face {
  font-family: 'Poppins';
  src: url('/font/Poppins-Bold.ttf') format('truetype');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

2. 优化html2canvas导出逻辑,等待字体加载完成

修改导出代码,利用document.fonts.ready确保所有字体加载完毕后再执行导出,同时开启相关配置允许读取本地字体:

const vm = this
// 等待字体加载完成后再导出
document.fonts.ready.then(() => {
  html2canvas(document.getElementById(this.chartID), {
    scale: vm.exportImageScale,
    scrollY: -window.scrollY,
    backgroundColor: '#121111',
    useCORS: true,
    allowTaint: true, // 允许加载本地资源,避免字体被拦截
    logging: false, // 关闭日志输出,减少干扰
  }).then((canvas) => {
    downloadLink(canvas.toDataURL(), `${this.downloadName}.png`)
  })
})

3. 确保D3图表元素明确指定字体

在D3生成坐标轴标签、图例文本等元素时,显式设置font-family为Poppins,避免继承问题:

// 示例:设置X轴标签字体
svg.append("text")
  .attr("x", width / 2)
  .attr("y", height + 40)
  .attr("text-anchor", "middle")
  .attr("font-family", "Poppins")
  .attr("font-size", 14)
  .text("X轴标题");

// 示例:设置图例文本字体
const legend = svg.append("g")
  .attr("transform", `translate(${width - 150}, 20)`);

legend.selectAll("text")
  .data(legendData)
  .enter()
  .append("text")
  .attr("x", 20)
  .attr("y", (d, i) => i * 25 + 15)
  .attr("font-family", "Poppins")
  .text(d => d.name);

4. 若坚持使用html-to-image的优化方案

同样改用本地字体,然后调整配置避免限流:

import { toPng } from 'html-to-image';

const vm = this
document.fonts.ready.then(() => {
  toPng(document.getElementById(this.chartID), {
    backgroundColor: '#121111',
    scale: vm.exportImageScale,
    cacheBust: false, // 禁用缓存破坏,避免重复请求字体
    fontRendering: 'canvas', // 强制用canvas渲染字体,减少远程请求
  }).then((dataUrl) => {
    downloadLink(dataUrl, `${this.downloadName}.png`)
  }).catch(err => {
    console.error('导出失败:', err);
  })
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 15:52:39