在查阅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' });
  • 1.
  • 2.

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

2.通过 blob 创建了对象 URL,用于显示 PDF 文件;
this.pdfUrl = window.URL.createObjectURL(blob);
  • 1.
3.使用iframe渲染PDF
<iframe id="xlsx_incoming" :src="pdfUrl" frameborder="0" style="width: 100%; height: 600px" type="application/x-google-chrome-pdf"></iframe>
  • 1.

具体实现代码

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)
        }
      })
    },
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.

封装一个预览组件

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

预览弹出框组件

<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>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.

使用预览达成的效果

vue预览PDF文件_PDF预览