React中使用jsPDF 2.4.0调用addImage输出灰色方块如何解决?
jsPDF生成PDF图片显示灰色方块修复方案
核心问题原因
你遇到的问题是jsPDF输出格式不匹配导致的PDF二进制内容损坏:
- 无参数调用
pdf.output()默认返回二进制字符串,直接传入Blob构造函数会触发编码错误,PDF内的图片资源无法正常解析,最终渲染为随机灰色像素块 - 少量场景是canvas转DataURL流程异常、addImage参数格式不兼容导致的
修复方法
最小改动方案(仅改1行代码)
将生成Blob的代码:
var blobPDF = new Blob([pdf.output()], { type: 'application/pdf' });
修改为:
var blobPDF = new Blob([pdf.output('arraybuffer')], { type: 'application/pdf' });
显式指定jsPDF输出ArrayBuffer格式的二进制内容,避免编码损坏。
可选优化方案
如果修改后仍有问题,可以做如下调整:
- addImage的格式参数改为大写
'PNG',部分版本对小写格式标识兼容不佳:
pdf.addImage(img, 'PNG', 1, 1, 1, 1);
- 移除多余的canvas转DataURL逻辑,jsPDF 2.4.0支持直接传入HTMLImageElement添加图片,简化代码避免转换异常:
const loadImage: (url: string) => Promise<HTMLImageElement> = (url) => { return new Promise((resolve) => { const i = new Image(); i.crossOrigin = 'anonymous'; // 跨域场景添加该配置 i.onload = () => resolve(i); i.src = url; }); };
- 如果是部署后加载跨域图片,需要给图片资源配置正确的CORS响应头。
修复后完整示例代码
import React from 'react'; import { jsPDF } from 'jspdf'; import testImage from './testImage.png'; const loadImage: (url: string) => Promise<string> = (url) => { return new Promise((resolve) => { const c = document.createElement('canvas'); const ctx = c.getContext('2d'); const i = new Image(); i.onload = () => { c.width = i.width; c.height = i.height; if (ctx) { ctx.drawImage(i, 0, 0); } resolve(c.toDataURL('image/png')); }; i.src = url; }); }; function PdfExport() { const [pdfUrl, setPdfUrl] = React.useState<string | undefined>(); React.useEffect(() => { const pdf = new jsPDF({ orientation: 'portrait', format: [8.3, 11.7], unit: 'in', }); loadImage(testImage).then((img) => { pdf.addImage(img, 'PNG', 1, 1, 1, 1); // 仅修改此处output参数为arraybuffer var blobPDF = new Blob([pdf.output('arraybuffer')], { type: 'application/pdf' }); const objectUrl = URL.createObjectURL(blobPDF); setPdfUrl(objectUrl); }); // 组件卸载时释放object URL,避免内存泄漏 return () => { if (pdfUrl) URL.revokeObjectURL(pdfUrl); } }, [pdfUrl]); return ( <iframe src={pdfUrl} /> ); } export default PdfExport;
内容的提问来源于stack exchange,提问作者frozenhelium
相关产品推荐
相关产品推荐

