如何通过API获取Blob并在Chrome中用window.print()实现打印?
解决Chrome中Blob内容无法触发window.print()的问题
我之前也踩过Chrome这个坑!窗口弹出来但打印对话框死活不出来,大概率是时机问题或者Blob内容的加载状态没处理到位,下面是经过验证的可行方案:
方案1:处理PDF类型Blob(最常见场景)
如果你的Blob是PDF文件,直接创建Object URL后插入到新窗口的<embed>标签中,必须等PDF完全加载后再触发打印:
async function printPdfBlob(blob) { // 生成Blob的临时访问URL const blobUrl = URL.createObjectURL(blob); // 打开空白打印窗口 const printWindow = window.open('', '_blank'); // 等待打印窗口基础DOM加载完成 await new Promise(resolve => printWindow.onload = resolve); // 向窗口写入PDF嵌入代码 printWindow.document.write(` <html> <head> <meta charset="UTF-8"> <title>打印PDF</title> <style>body { margin: 0; }</style> </head> <body> <embed src="${blobUrl}" type="application/pdf" style="width:100%;height:100vh;" /> </body> </html> `); printWindow.document.close(); // 等待PDF资源加载完成——这是触发打印的关键! const embedElement = printWindow.document.querySelector('embed'); await new Promise(resolve => { embedElement.onload = resolve; // 加5秒超时兜底,避免加载失败导致页面卡住 setTimeout(resolve, 5000); }); // 触发打印对话框 printWindow.print(); // 打印完成后清理资源,避免内存泄漏 setTimeout(() => { URL.revokeObjectURL(blobUrl); printWindow.close(); }, 1000); }
方案2:处理HTML/纯文本类型Blob
如果Blob是HTML或纯文本内容,先把Blob转成文本再写入窗口:
async function printHtmlBlob(blob) { // 将Blob转换为HTML文本 const htmlContent = await blob.text(); const printWindow = window.open('', '_blank'); await new Promise(resolve => printWindow.onload = resolve); printWindow.document.write(htmlContent); printWindow.document.close(); // HTML加载速度快,可直接触发打印 printWindow.print(); setTimeout(() => printWindow.close(), 1000); }
核心注意事项
- 必须在用户交互上下文内调用:比如按钮点击、表单提交等用户主动触发的事件中执行打印逻辑,Chrome会拦截非用户触发的
window.print()调用。 - 等待资源加载完成:PDF、图片这类外部资源需要时间加载,直接调用print会导致打印空白或不触发对话框。
- 清理临时URL:用
URL.revokeObjectURL()释放Blob的临时访问地址,避免浏览器内存泄漏。 - 检查Blob的MIME类型:确保Blob的类型和嵌入标签的
type属性匹配(比如PDF对应application/pdf),否则可能无法正常加载。
我用这套方法解决了Chrome里的打印失效问题,你可以根据自己的Blob类型调整代码,也可以适当修改超时时间适配不同的加载速度。
内容的提问来源于stack exchange,提问作者Onfroy
相关产品推荐
相关产品推荐

