FileSaver.js在iOS 10+设备无法下载PDF/Excel文件求助
我之前帮同事踩过iOS 10+ Safari下载Blob的坑,跟你遇到的情况一模一样——FileSaver.js在其他设备都正常,唯独iOS上死活下不了,还不想开新标签。给你几个实测有效的解决方案:
方案1:用File对象替代Blob传入saveAs
iOS 10+的Safari对File对象的兼容性比直接的Blob好太多,只需要微调你的代码:
const wbout: string = XLSX.write(wb, { bookType: 'xlsx', type: 'array' }); // 把原来的Blob换成File对象 const excelFile = new File([wbout], "My List.xlsx", { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }); saveAs(excelFile, "My List.xlsx");
这个改动极小,大概率能直接解决问题,因为FileSaver.js对File对象的处理在iOS上没有Blob的限制。
方案2:原生a标签+URL.createObjectURL(推荐大文件)
如果方案1还是不行,就绕开FileSaver的Blob限制,用原生DOM操作实现下载,完全不会打开新标签:
const wbout: string = XLSX.write(wb, { bookType: 'xlsx', type: 'array' }); const blob = new Blob([wbout], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }); // 生成本地Blob URL const downloadUrl = URL.createObjectURL(blob); // 创建临时a标签 const link = document.createElement('a'); link.href = downloadUrl; link.download = "My List.xlsx"; // iOS必须把标签添加到DOM里才能触发点击 document.body.appendChild(link); link.click(); // 清理临时资源,避免内存泄漏 document.body.removeChild(link); URL.revokeObjectURL(downloadUrl);
这个方法利用Safari支持的download属性,通过本地URL触发下载,既不会跳转页面,又适合大文件(不会像base64那样膨胀体积、占用内存)。
方案3:转base64生成Data URI(适合小文件)
如果你的Excel文件体积不大,可以把数组转换成base64的Data URI,再用a标签完成下载:
const wbout: string = XLSX.write(wb, { bookType: 'xlsx', type: 'array' }); // 将数组转换成Uint8Array再转base64 const uint8Array = new Uint8Array(wbout); const base64Str = btoa(String.fromCharCode(...uint8Array)); const dataUri = `data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,${base64Str}`; const link = document.createElement('a'); link.href = dataUri; link.download = "My List.xlsx"; document.body.appendChild(link); link.click(); document.body.removeChild(link);
注意:这个方法不建议用于大文件,base64会让文件体积增加约30%,还可能导致内存溢出问题。
内容的提问来源于stack exchange,提问作者Am Novice
相关产品推荐
相关产品推荐

