vue自定义一个在线查看文件的组件(.xlsx、.docx、.pdf、图片等)

在组件目录下创建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=" 实现在线查看除图片外的文件

相关推荐
山河木马10 小时前
矩阵专题3-怎么创建投影矩阵(uProjectionMatrix)
javascript·webgl·计算机图形学
泯泷12 小时前
第 2 篇:设计第一套字节码:Opcode、Instruction 与 Constant Pool
前端·javascript·安全
泯泷12 小时前
第 1 篇:从 1 + 2 开始:亲手写出第一台 JSVM
前端·javascript·安全
古夕12 小时前
第三方 SSO 接入实践:redirect_uri 编码、回调一致性与跨项目联调
前端·vue.js
朦胧之12 小时前
页面白屏卡住排查方法
前端·javascript
Ruihong12 小时前
Vue withDefaults 转 React:VuReact 怎么处理?
vue.js·react.js·面试
犇驫聊AI13 小时前
Chrome DevTools MCP + Claude Code 自定义skills生成接口代码生成器
前端·javascript
kyriewen13 小时前
别再这样写 async/await 了:我在 Code Review 中见过最多的 8 个错误
前端·javascript·面试
稀土熊猫君14 小时前
一个人能做出什么开源项目?
vue.js·后端·开源
用户2986985301418 小时前
在 React 中使用 JavaScript 将 Excel 转换为 SVG
前端·javascript·react.js