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=" 实现在线查看除图片外的文件

相关推荐
avi911111 小时前
[AI教做人]AI平台做2项目;一个3D模型展示,另一个框架多人
javascript·人工智能·ai·3d模型·3d引擎·顶点和法线
kyriewen11 小时前
我用Claude Code两天干完了团队两周的排期——周报发出去那一刻我就后悔了
前端·javascript·ai编程
用户9385156350712 小时前
手写一个 LLM Harness 框架:用工程化手段把大模型幻觉踩在脚下
javascript·人工智能·后端
油丶酸萝卜别吃13 小时前
jquery-ajax.js 说明文档
前端·javascript·jquery
windliang13 小时前
Claude Code 源码分析(九):子 Agent 如何分叉、继续与回到父会话
前端·javascript·面试
柒和远方14 小时前
V063: TS 面试必考:interface 与 type 的四大差异,与 LLM Harness 的自动化择优
前端·javascript
宿67414 小时前
vue3-env环境
前端·vue.js
汉堡大王952714 小时前
Vue 3 + TS + Element Plus 实战:如何从零搭建企业级违章记录管理 SaaS 前端
前端·javascript·vue.js
海天鹰14 小时前
屏幕颜色检测
javascript·html5
用户79172867619715 小时前
opencode-plugin-peers完全指南:OpenCode如何实现 Claude Code式跨会话消息
javascript