PDF导出失败主因是DOM未就绪或资源未加载完,应改用window.onload或监听关键元素;中文需嵌入字体;尺寸错乱需重置transform/overflow样式;须透传Promise错误并逐段调试。

导出PDF时空白页或内容缺失,先确认是否在DOM就绪后调用
很多前端PDF导出失败,根本原因不是库本身,而是脚本在document.body还没渲染完就执行了导出逻辑。比如用html2canvas + jsPDF组合时,若直接在DOMContentLoaded里触发,但页面依赖的Vue/React组件、异步图片、字体加载尚未完成,截图必然为空白或截断。
实操建议:
- 改用
window.onload(等所有资源加载完),或更稳妥地监听关键元素:比如用document.querySelector('#report-container')存在且offsetHeight > 0再执行 - 对动态图表(如ECharts)需显式等待:
chartInstance.isDisposed() === false && chartInstance.getWidth() > 0 - 图片务必加
onload钩子或用Promise.all(imgList.map(img => new Promise(r => img.onload = r)))统一等待
中文乱码或字体不显示,检查PDF库是否嵌入了对应字体
jsPDF默认只支持ASCII,直接doc.text('你好', 10, 10)会输出空格或报错Uncaught Error: "undefined" is not a valid font.;而html2canvas截图虽能显示中文,但若CSS中用了未加载的Web Font(如font-family: 'PingFang SC'),截图也会变成方块。
实操建议:
- 用
jsPDF导出纯文本PDF时,必须先doc.addFileToVFS('simhei.ttf', simhei_base64)再doc.addFont('simhei.ttf', 'SimHei', 'normal'),然后doc.setFont('SimHei') - 用
html2canvas截图前,在目标容器上强制指定已加载的本地字体:style="font-family: 'Microsoft YaHei', sans-serif;",并确保该字体已在CSS中通过@font-face声明且font-display: swap设为block或optional - 避免使用系统字体名(如
'-apple-system'),它在无GUI的截图上下文中不可用
导出PDF尺寸错乱、内容被裁剪,重点查CSS中的transform和overflow
html2canvas对CSS transform、position: fixed、overflow: hidden兼容性差,常见现象是按钮位置偏移、弹窗遮罩层消失、表格列被截断。它本质上是将DOM“拍平”成Canvas像素,而非真实打印流。
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
实操建议:
- 导出前临时重置关键样式:
element.style.transform = ''、element.style.position = 'static'、element.style.overflow = 'visible' - 禁用可能干扰布局的CSS类,例如给导出区域加临时class:
export-root { transform: none !important; overflow: visible !important; } - 避免在导出容器内使用
will-change: transform——它会让html2canvas跳过渲染该节点 - 设置
scale: 2参数提升截图精度(html2canvas(element, { scale: 2 })),但注意内存占用翻倍,长页面慎用
调试时看不到错误堆栈?把html2canvas和jsPDF的reject链路打穿
很多项目封装了导出方法,但没透传Promise reject,导致控制台静默失败。例如html2canvas在遇到跨域图片、SVG含引用、或Canvas被污染时,会直接reject,但若外层没.catch(),就只能靠打断点看devtools → Network → XHR/fetch里是否有字体或图片403/404。
实操建议:
- 导出函数必须返回原始Promise链:
return html2canvas(el).then(canvas => { ... }).catch(err => { console.error('html2canvas failed:', err); throw err; }) - 检查浏览器控制台的
SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement'——这是典型跨域图片未加crossOrigin="anonymous" - 启用
jsPDF调试模式:jsPDF.API.events.push(['addPage', () => console.log('page added')]),确认是否卡在分页逻辑
最常被忽略的是:PDF导出不是“一次渲染”,而是“渲染→截图→编码→组装→下载”多阶段流水线,任一环节出问题都不会报明显错误,得逐段加console.time()和console.log()定位卡点。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










