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

相关推荐
叼烟扛炮1 小时前
[LangChain] 学习笔记(03):打破失忆症——对话机制与上下文管理
java·前端·javascript·笔记·学习·langchain
卋罖7502 小时前
Razor 视图 + JavaScript + Vue/iView 组件实现的表格自定义列
javascript·vue·iview·razor视图
系统集成-鹰翔16 小时前
ERP图片改名后仍命中识别缓存:缓存键、十分钟到期与调用计数
javascript·经验分享·后端
FlyWIHTSKY18 小时前
vue2和vue3有什么区别,用法上有哪些区别
前端·javascript·vue.js
程序员大阳19 小时前
副队长JavaScript教程(66)-本地存储实战:待办事项网页的开发
javascript·json·实战·待办事项·本地存储·案例
Dream-Y.ocean20 小时前
鸿蒙PC平台逻控 PLC 编辑器适配实战:基于 Electron 壳方案的纯 JavaScript 梯形图编程与仿真引擎开发
javascript·编辑器·harmonyos
前端小D1 天前
JS核心底层
前端·javascript
Dovis(誓平步青云)1 天前
启元 T1 Pro 人机相声搭档:语音-触摸双通道的启元机器人节奏引擎设计
开发语言·前端·javascript·microsoft·交互
ruanno_top1 天前
能点,但 Tab 不到:两个组件把「可操作」做了一半
vue.js
爱吃烧烤的技术渣1 天前
别再手写 CRUD 了:我把 Element Plus 的工作量压缩成一份列 schema
前端·vue.js