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

相关推荐
ComPDFKit16 小时前
PDF发票生成怎么做?从零到服务化落地的完整指南
pdf·pdf生成·文件生成·发票生成
Hello--_--World16 小时前
为什么 用vite进行分包后,可以通过 浏览器强制缓存 提高性能?路由懒加载进行的分包与 vite进行的分包有什么不同?
前端·javascript·缓存·vite
三*一16 小时前
Mapbox GL JS 前端多边形分割实战:从踩坑到优雅实现
开发语言·前端·javascript·vue.js
xChive16 小时前
前端请求取消:用 AbortController 从 fetch 到 axios
前端·vue.js·axios·fetch·abortcontroller
一棵树735116 小时前
js总结介绍
前端·javascript·html
踩着两条虫17 小时前
AI 低代码引擎可视化设计器交互机制实战
前端·vue.js·人工智能·低代码·架构
白菜__17 小时前
微信小程序网关逆向分析
javascript·微信小程序·小程序·node.js·网络爬虫·微信网关·小程序网关
放下华子我只抽RuiKe517 小时前
React 从入门到生产(三):副作用与数据获取
前端·javascript·深度学习·react.js·开源·ecmascript·集成学习
Cobyte17 小时前
12.响应式系统演进:揭秘多级脏检查机制的设计哲学与实现原理(Vue3.4)
前端·javascript·vue.js
ZC跨境爬虫17 小时前
跟着 MDN 学CSS day_1:(CSS 基石与色彩的艺术)
前端·javascript·css·ui·html