前端预览和打印PDF的两种方式

最近工作中遇到了一个需求,就是前端选择表格中的某一条数据去请求后端接口,后端返回的是一个PDF文件的下载地址,但是需求不希望用户下载下来再去打印,而是直接预览展示,然后就能打印。

一开始按照网上的方式去操作,但是每一次浏览器直接就下载了下来,后面一看响应头,原来后端的Content-type设置成了如图所示,直接触发了浏览器的下载。

怎么办呢?于是就想到了以下两种方案,两种方案都是再一次去请求返回的地址,只不过前端改成了用二进制Blob(responseType: 'blob'),获取原始二进制数据

方案一如下图所示:

其中的data为要传入的地址,然后将拿到的结果创建一个Blob对象,并重新指定其MIME类型为{ type: 'application/pdf '},这样就不会再触发浏览器的下载功能。接着使用URL.createObjectURL()生成临时访问地址,通过window.open()的方式在新窗口打开预览,等待加载后自动打印。

但是这种方案要确保后端设置了如下的CORS头,这种方案兼容所有现代浏览器(Chrome/Firefox/Edge/Safari)

复制代码
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)
    },

获取原始二进制数据

相关推荐
jktantan19 分钟前
每个节点 41 字节:把一棵百万节点树拆进 14 个 typed array
前端·javascript·vue.js·算法·typescript
我命由我123451 小时前
访客系统形式(有用户概念、无用户概念)
java·开发语言·前端·javascript·python·产品运营·产品经理
程序员大阳2 小时前
副队长JavaScript教程(65)-详解JSON:轻量级数据交换格式
javascript·json·序列化·反序列化·stringify·parse
paopaokaka_luck3 小时前
基于springboot+vue的益暖微光公益服务平台(DeepSeek公益助手、善款信息追溯、志愿服务积分闭环、ECharts运营分析、活动状态自动流转)
java·前端·javascript·spring boot·mysql·架构·echarts
栀椩3 小时前
Electron 内嵌页面跨域问题(CORS/PNA)解决全记录
前端·javascript·electron
SEO_juper4 小时前
Chrome 扩展一键查看当前页面 SEO 信息:不用切页面,点一下全出来
前端·javascript·chrome
Highcharts.js4 小时前
CSUN 2026|Highcharts无障碍数据与AI分享
javascript·人工智能·数据分析·highcharts·图表开发
系统集成-鹰翔4 小时前
ERP推单数据库怎么备份:SQLite WAL模式下只复制db文件为什么可能漏任务
javascript·数据库·经验分享·后端
小大宇5 小时前
Vue知识点-ElementPlus-05 输入框
前端·javascript·vue.js
外贸GEO优化5 小时前
外贸独立站的可抓取性:JS 渲染、懒加载与无限滚动到底影响什么
开发语言·javascript·ecmascript