1.
前端预览和打印PDF的两种方式
2.JavaScript是按顺序执行的吗?聊聊JavaScript中的变量提升
最近工作中遇到了一个需求,就是前端选择表格中的某一条数据去请求后端接口,后端返回的是一个PDF文件的下载地址,但是需求不希望用户下载下来再去打印,而是直接预览展示,然后就能打印。
一开始按照网上的方式去操作,但是每一次浏览器直接就下载了下来,后面一看响应头,原来后端的Content-type设置成了如图所示,直接触发了浏览器的下载。
怎么办呢?于是就想到了以下两种方案,两种方案都是再一次去请求返回的地址,只不过前端改成了用二进制Blob(responseType: 'blob'),获取原始二进制数据
方案一如下图所示:
其中的data为要传入的地址,然后将拿到的结果创建一个Blob对象,并重新指定其MIME类型为{ type: 'application/pdf '},这样就不会再触发浏览器的下载功能。接着使用URL.createObjectURL()
生成临时访问地址,通过window.open()的方式在新窗口打开预览,等待加载后自动打印。
但是这种方案要确保后端设置了如下的CORS头,这种方案兼容所有现代浏览器(Chrome/Firefox/Edge/Safari)
1
2
3
|
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET
|
方案二如下图所示:
创建一个隐藏的iframe标签src设置为pdf地址;前端通过获取隐藏的iframe标签的id来实现打印指定内容;
附上具体代码:
async batchPrintReturn(data) { axios.get(data,{responseType: 'blob'}).then(res => { // 以二进制Blob格式接收 console.log('res>', res) const blob = new Blob([res.data], { type: 'application/pdf' }); // 创建Blob对象并指定新的MIME类型 // 方案一 const objectUrl = URL.createObjectURL(blob); // 生成临时URL const previewWindow = window.open(objectUrl, '_blank'); // 打开新窗口预览 previewWindow.onload = function() { // 等待加载后自动打印 previewWindow.print(); }; // 方案二 var date = (new Date()).getTime() var ifr = document.createElement('iframe') ifr.style.frameborder = 'no' ifr.style.display = 'none' ifr.style.pageBreakBefore = 'always' ifr.setAttribute('id', 'printPdf' + date) ifr.setAttribute('name', 'printPdf' + date) ifr.src = window.URL.createObjectURL(blob) document.body.appendChild(ifr) this.doPrint('printPdf' + date) window.URL.revokeObjectURL(ifr.src) // 释放URL 对象 }) }, doPrint(val) { var ordonnance = document.getElementById(val).contentWindow setTimeout(() => { ordonnance.print() }, 100) },
获取原始二进制数据 原创作者: xiuqian 转载于: https://www.cnblogs.com/xiuqian/p/18898640