在查阅PDF报告,可以使用 iframe标签去绑定URL地址。但是浏览器会有跨域限制,一些文件无法直接访问。

思路就是使用文件流查看,如果后端返回的是文件流就不需要将在线地址转文件流。

以下为当后端传给的是一个PDF地址时的解决方案

1.将文件下载转换成blob

 const response = await axios.get('http://xxx.xxx.com/aaa.pdf', { responseType: 'blob' });
      const blob = new Blob([response.data], { type: 'application/pdf' });

这段代码使用axios发起GET请求获取指定URL的内容,并设置响应类型为blob。收到响应后,将响应数据封装到一个新的Blob对象中,指定MIME类型为PDF文档 (application/pdf)。简而言之,它从服务器下载一个PDF文件。

2.通过 blob 创建了对象 URL,用于显示 PDF 文件;

this.pdfUrl = window.URL.createObjectURL(blob);

3.使用iframe渲染PDF

<iframe id="xlsx_incoming" :src="pdfUrl" frameborder="0" style="width: 100%; height: 600px" type="application/x-google-chrome-pdf"></iframe>

具体实现代码

 handleExportOnlineCoa(row, query){
      exportCoaAPI({
          type: query.type,
          fileType:query.fileType,
          id: row.id,
      }).then(res=>{
        if(res.code==200){
           const response = await axios.get(res.url, { responseType: 'blob' });
      		const blob = new Blob([response.data], { type: 'application/pdf' });
        	 
        	this.pdfUrl = window.URL.createObjectURL(blob);
       		this.visiblePdf = true
        
        }else{
          this.$message.warning(res.msg || res.message)
        }
      })
    },

封装一个预览组件

<DialogPdf :visible.sync="visiblePdf" :pdfUrl='pdfUrl' />

预览弹出框组件

<template>
    <div style="width:100%">
        <el-dialog :visible.sync="visible" title="预览报告" width="90vw" top="" class="knowledge-dialog" :close-on-click-modal="false" :before-close="close" @close="onClose">
            <iframe id="xlsx_incoming" :src="pdfUrl" frameborder="0" style="width: 100%; height: 600px" type="application/x-google-chrome-pdf"></iframe>
            <div slot="footer">
                <el-button size="mini" type="default" icon="el-icon-close" @click="handleClose">{{ $t("btn.close") }}</el-button>
                <el-button size="mini" type="primary" icon="el-icon-download" @click="handleConfirm">下载报告</el-button>
            </div>
        </el-dialog>
    </div>
</template>

<script>

export default {
    
    props: {
        visible: {
            type: Boolean,
            default: false,
        },
        pdfUrl: {
            type: String
        },
        
    },
    data() {
        return {
            title: '',
        }
    },
    methods: {
        // 窗口关闭
        onClose() {},
        generateTimestamp() {
            const now = new Date();
            const year = now.getFullYear().toString();
            const month = ('0' + (now.getMonth() + 1)).slice(-2); // 月份是从0开始的,所以加1
            const day = ('0' + now.getDate()).slice(-2);
            const hours = ('0' + now.getHours()).slice(-2);
            const minutes = ('0' + now.getMinutes()).slice(-2);
            const seconds = ('0' + now.getSeconds()).slice(-2);

            return `六粮液报告_${year}${month}${day}${hours}${minutes}${seconds}`;
        },
        handleConfirm(){
            const link = document.createElement('a');
            link.href = this.pdfUrl; // 创建一个Blob URL
            const timestamp = this.generateTimestamp();
            link.download = `${timestamp}.pdf`; // 设置自定义的下载文件名
            link.click(); // 触发下载
            setTimeout(() => URL.revokeObjectURL(link.href), 0);
        },
        handleClose() {
            this.$emit('update:visible',false)
        },
        // 窗口关闭前执行
        close() {
            this.$emit('update:visible',false)
        }
    },
}
</script>

<style scoped lang="scss">
::v-deep .el-dialog__footer {
    text-align: center;
}
::v-deep .el-dialog{
    height: 100vh;
    .el-dialog__body{
        max-height: 90%;
    }
}
.search-btn {
    background: #20b09f;
    border-color: #20b09f;
}
#xlsx_incoming ::v-deep tr td {
    border: 1px solid #ccc;
    text-align: center;
}
</style>

使用预览达成的效果

vue预览PDF文件_文件流