在组件目录下创建PreViewFile组件:
src/components/PreViewFile.vue
javascript
<template>
<iframe v-if="props.viewFileVisible &&
(props.viewFileType === 'xlsx' ||
props.viewFileType === 'docx' ||
props.viewFileType === 'doc' ||
props.viewFileType === 'txt' ||
props.viewFileType === 'pdf')" :src="props.viewFileAdd" frameBorder="0"
style="height:65vh;width:100%"></iframe>
<img v-else-if="props.viewFileType === 'jpg' || props.viewFileType === 'jpeg' || props.viewFileType === 'png' ||
props.viewFileType === 'jpg' || props.viewFileType === 'jpeg' || props.viewFileType === 'png' ||
props.viewFileType === 'gif' || props.viewFileType === 'bmp' || props.viewFileType === 'tiff' ||
props.viewFileType === 'webp' || props.viewFileType === 'svg' || props.viewFileType === 'heif'"
:src="props.viewFileAdd" alt="" style="width:100%">
<p v-else>
暂不支持在线预览
<span class="fontPrimary cur"
@click="donwloadFileByUrl({ filePass: props.viewFileAdd, fileName: getNameByAddress(props.viewFileAdd) })">可点击下载文件</span>
</p>
</template>
<script setup>
const props = defineProps(['viewFileVisible','viewFileAdd','viewFileType']);
const emits = defineEmits(['goBack']);
// 点击(下载)文件
export const donwloadFile = async (item) => {
// window.location.href = item.filePass
console.log(item);
const a = document.createElement("a");
a.style.display = "none";
a.download = item.fileName;
a.href = item.filePass;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
};
// 网络请求下载文件
const donwloadFileByUrl = async (item) => {
axios.get(item.filePass, {
responseType: 'blob' // 重要:确保设置了这个
}).then(async (blob) => {
console.log(blob);
const url = URL.createObjectURL(blob.data);
const a = document.createElement('a');
a.style.display = 'none';
a.setAttribute('target', '_blank');
a.href = url;
a.download = item.fileName;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
}).catch(error => {
// 创建一个临时的a标签来触发下载
console.log(item);
donwloadFile(item)
});
};
// 获取文件名
const getNameByAddress = (address) => {
if(!address) return ''
return address.split('/')[address.split('/').length - 1];
}
</script>
<style scoped lang="less"></style>
其他页面使用:
javascript
<template>
<el-button v-for="item,index" @click="goViewFile(item)" >查看文件{{index = 1}}</el-button>
<el-dialog v-model="data.viewFileVisible" @close="" :title="'预览'" style="">
<PreViewFile :viewFileVisible="data.viewFileVisible"
:viewFileAdd="data.viewFileAdd" :viewFileType="data.viewFileType"></PreViewFile>
<el-button @click="data.viewFileVisible = false" >返回</el-button>
</el-dialog>
</template>
<script setup lang='ts'>
import PreViewFile from '@/components/PreViewFile.vue';
const data: any = reactive({
viewFileVisible:false,
viewFileAdd:'',//文件地址
viewFileType:'',//文件类型
fileList:[
'http:xxxxxx.png',
'http:xxxxxx.pdf',
'http:xxxxxx.xlsx',
'http:xxxxxx.docx',
'http:xxxxxx.svg',
],
});
// 获取地址的文件后缀
const getFileTypeByAddress = (address) => {
if(!address) return ''
return address.split('.')[address.split('.').length - 1];
}
// 查看需求单
const goViewFile = (address) => {
let viewer = 'https://view.officeapps.live.com/op/embed.aspx?src=';
let end = getFileTypeByAddress(address)
if (end === 'xlsx' || end === 'docx' || end === 'doc' || end === 'txt' || end === 'pdf'
) {
} else {
viewer = '';
}
data.viewFileType = end;
data.viewFileAdd = viewer + address;
data.viewFileVisible = true;
}
</script>
核心是使用iframe标签和微软的"https://view.officeapps.live.com/op/embed.aspx?src=" 实现在线查看除图片外的文件