JSPDF搭配html2Canvas在IOS浏览器中无法下载PDF文件问题
问题根因
iOS端浏览器(尤其是Safari内核的所有浏览器)存在两个和该功能相关的兼容性限制:
- iOS Safari对canvas最大可渲染尺寸有严格限制,超过上限后
canvas.toDataURL()会返回空值,导致后续PDF生成逻辑中断 - jsPDF默认的
save()方法在iOS下受浏览器安全策略限制,无法直接触发文件下载行为
修复方案
你可以直接替换原有JS代码为下方兼容版本:
$('#print').click(function (e) { e.preventDefault(); let HTML_Width = $(".report").width(); let HTML_Height = $(".report").height(); let top_left_margin = 1; let PDF_Width = HTML_Width + (top_left_margin * 2); let PDF_Height = (PDF_Width * 1.5) + (top_left_margin * 2); let canvas_image_width = HTML_Width; let canvas_image_height = HTML_Height; // 适配iOS canvas尺寸限制,超过最大尺寸自动缩放 const MAX_IOS_CANVAS_HEIGHT = 16384; let scaleRate = 1; if (HTML_Height > MAX_IOS_CANVAS_HEIGHT) { scaleRate = MAX_IOS_CANVAS_HEIGHT / HTML_Height; canvas_image_width = HTML_Width * scaleRate; canvas_image_height = HTML_Height * scaleRate; } let totalPDFPages = Math.ceil(HTML_Height / PDF_Height) - 1; html2canvas($(".report")[0], { scale: scaleRate, // 传入缩放参数,避免canvas尺寸超限 useCORS: true, // 存在跨域图片时需要保留该配置 logging: false }).then(function (canvas) { let imgData = canvas.toDataURL("image/jpeg", 1.0); let pdf = new jsPDF('p', 'pt', [PDF_Width, PDF_Height]); pdf.addImage(imgData, 'JPG', top_left_margin, top_left_margin, canvas_image_width, canvas_image_height, 'FAST'); for (let i = 1; i <= totalPDFPages; i++) { pdf.addPage(PDF_Width, PDF_Height); pdf.addImage(imgData, 'JPG', top_left_margin, -(PDF_Height * i) + (top_left_margin * 4), canvas_image_width, canvas_image_height); } // 替换默认save方法,手动适配iOS下载 if (/(iPhone|iPad|iPod)/i.test(navigator.userAgent)) { // iOS环境:手动生成blob并触发a标签下载 const pdfBlob = pdf.output('blob'); const blobUrl = URL.createObjectURL(pdfBlob); const a = document.createElement('a'); a.href = blobUrl; a.download = 'Report.pdf'; a.target = '_blank'; document.body.appendChild(a); a.click(); // 延迟释放资源,避免iOS下提前释放导致下载失败 setTimeout(() => { document.body.removeChild(a); URL.revokeObjectURL(blobUrl); }, 1000); } else { // 非iOS环境用原有逻辑 pdf.save("Report.pdf"); } $(".html-content").hide(); }); });
额外注意事项
- 如果报表里包含跨域图片,需要确保图片服务配置了CORS头,否则iOS下图片会渲染空白
- 不要给点击事件加额外的非用户触发的异步封装(比如非交互触发的setTimeout),否则iOS会判定为非用户主动操作,拦截下载行为
内容的提问来源于stack exchange,提问作者Osama Amr
相关产品推荐
相关产品推荐

