在查阅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>
使用预览达成的效果