使用jsPDF的addSvgAsImage方法无法修改SVG元素背景色
问题根因
jsPDF 2.3.1版本的addSvgAsImage()方法不支持解析SVG根节点的background-color样式属性,该属性会被直接忽略,SVG默认渲染为透明背景,在插入PDF的过程中透明通道处理异常就会显示为黑色。
解决方案
提供两种可直接落地的方案,优先选第一种兼容性最好:
- 方案1:给SVG添加底层矩形作为背景
不要把背景色写在SVG根节点的style里,而是在所有SVG元素最前面加一个和SVG宽高一致的矩形,填充你需要的背景色,修改后的代码如下:
exportPdf() { const doc = new jsPDF('p', 'pt', 'a3'); // 新增rect作为背景层,同时避免SVG属性随意换行导致解析异常 const svgStr = `<svg width="200" height="200"> <rect width="200" height="200" fill="red" /> <polygon points="100,10 40,198 190,78 10,78 160,198" style="fill:lime;stroke:purple;stroke-width:5;fill-rule:evenodd;"/> </svg>` doc.addSvgAsImage(svgStr, 10, 50, 200 ,200); doc.html(document.getElementById("exportPage"), { callback: function (doc) { doc.save('test.pdf'); }, x: 10, y: 250 }); }
- 方案2:先将SVG转成带背景的Canvas再插入PDF
如果不能修改SVG结构,可以先把SVG加载到Canvas上绘制背景,再调用addImage()插入PDF:
exportPdf() { const doc = new jsPDF('p', 'pt', 'a3'); const svgStr = '<svg width="200" height="200" style="background-color: red"><polygon points="100,10 40,198 190,78 10,78 160,198" style="fill:lime;stroke:purple;stroke-width:5;fill-rule:evenodd;"/></svg>'; const img = new Image(); const svgBlob = new Blob([svgStr], {type: 'image/svg+xml'}); const url = URL.createObjectURL(svgBlob); img.onload = () => { const canvas = document.createElement('canvas'); canvas.width = 200; canvas.height = 200; const ctx = canvas.getContext('2d'); // 先绘制红色背景 ctx.fillStyle = 'red'; ctx.fillRect(0,0,200,200); // 再绘制SVG ctx.drawImage(img, 0, 0); // 插入PDF doc.addImage(canvas.toDataURL('image/png'), 'PNG', 10, 50, 200, 200); doc.html(document.getElementById("exportPage"), { callback: function (doc) { doc.save('test.pdf'); URL.revokeObjectURL(url); }, x: 10, y: 250 }); } img.src = url; }
额外注意事项
你贴的代码里SVG字符串存在随意拆分属性换行的问题,比如polygon标签的属性拆成了多行,这会导致部分版本的jsPDF解析SVG失败,建议把SVG字符串的属性都合并到同一行,或者用模板字符串保持标签结构完整不要拆分单个属性。
内容的提问来源于stack exchange,提问作者suresh kb
相关产品推荐
相关产品推荐

