Vue在线预览excel、word、ppt等格式数据。

news2025/6/8 7:06:40

目录

前言

1.安装库

2.预览文件子组件代码

3、新建store/system.ts

4、父页面进行使用

总结


前言

 纯前端处理文件预览,包含excel、word、ppt、txt等格式,不需要后端服务器进行部署,并且内网也可以使用。

 


1.安装

npm install @vue-office/docx @vue-office/excel @vue-office/pdf
# 或
yarn add @vue-office/docx @vue-office/excel @vue-office/pdf

2.预览文件子组件代码

<template>
  <div class="fileView">
    <n-modal v-model:show="fileViewVisible">
      <n-card
        style="
          width: 65%;
          position: fixed;
          top: 50px;
          left: 50%;
          transform: translateX(-50%);
        "
        :title="sysStore.fileViewInfo.name"
        :bordered="true"
        size="medium"
        role="dialog"
        aria-modal="true"
      >
        <template #header-extra>
          <n-button circle @click="fileViewVisible = false">
            <template #icon>
              <n-icon>
                <Close />
              </n-icon>
            </template>
          </n-button>
        </template>
        <div>
          <iframe
            v-if="sysStore.fileViewInfo.fileType === 'txt'"
            style="width: 100%; height: calc(100vh - 190px)"
            :src="sysStore.fileViewInfo.viewUrl"
            frameborder="0"
          ></iframe>
          <vue-office-pdf
            v-if="sysStore.fileViewInfo.fileType === 'pdf'"
            style="width: 100%; height: calc(100vh - 180px)"
            :src="sysStore.fileViewInfo.viewUrl"
            frameborder="0"
          ></vue-office-pdf>
          <vue-office-docx
            v-if="sysStore.fileViewInfo.fileType === 'doc'"
            style="width: 100%; height: calc(100vh - 180px)"
            :src="sysStore.fileViewInfo.viewUrl"
            frameborder="0"
          ></vue-office-docx>
          <vue-office-excel
            v-if="sysStore.fileViewInfo.fileType === 'xlsx'"
            style="width: 100%; height: calc(100vh - 180px)"
            :src="sysStore.fileViewInfo.viewUrl"
            frameborder="0"
          ></vue-office-excel>
        </div>
      </n-card>
    </n-modal>
  </div>
</template>
<script lang="ts" setup>
import { ref } from "vue";
import useSystemStore from "@/store/system";
import { Close } from "@vicons/ionicons5";
// 引入VueOffice组件
import VueOfficeDocx from "@vue-office/docx";
import VueOfficeExcel from "@vue-office/excel";
import VueOfficePdf from "@vue-office/pdf";
// 引入相关样式
import "@vue-office/docx/lib/index.css";
import "@vue-office/excel/lib/index.css";


const sysStore = useSystemStore();

const fileViewVisible = ref(false);

const show = () => {
  fileViewVisible.value = true;
};

// 监听外部变化
watch(() => props.visible, (newVal) => {
  fileViewVisible.value = newValue
}, {
 immediate: true
})
// 暴漏show给父组件使用
defineExpose({
  show,
});
</script>
<style lang="less" scoped></style>

 

3、新建store/system.ts

代码如下:

import { defineStore } from "pinia";

interface State {
  fileViewInfo: any; // 文件预览信息
}

const useSystemStore = defineStore("system", {
  state: (): State => ({
    fileViewInfo: {},
  }),
  actions: {
    setFileViewInfo(val: any) {
      this.fileViewInfo = val;
    },
  },
});

export default useSystemStore;

4、父页面进行使用

<template>
  <n-space class="file-view" style="gap: 8px 8px" :inline="true">
    <div
      class="file-item"
      v-for="(file, index) in fileComp"
      :key="index"
      @click="fileView(file)"
    >
      <div class="file-icon">
        <img width="28" :src="file.iconIamge" alt="" />
      </div>
    </div>
  </n-space>
  <FilePreviewDialog v-model:visible="obj.showDialog" ref="filePreviewDialogRef" />
</template>
<script lang="ts" setup>

import { computed, ref } from "vue";
// 以下icon是不同后缀名的文件图片 可要可不要
import excelImg from "@/assets/images/fileIcon/excel.png";
import pdfImg from "@/assets/images/fileIcon/pdf.png";
import wordImg from "@/assets/images/fileIcon/word.png";
import textImg from "@/assets/images/fileIcon/text.png";
import unknownImg from "@/assets/images/fileIcon/unknown.png";
import { getFileSize } from "@/utils/useFunc";
import useSystemStore from "@/store/system";
import FilePreviewDialog from "@/components/FilePreviewDialog.vue";

const filePreviewDialogRef = ref<any>();
const props = defineProps({
  files: {
    type: [Object,Array],
    required: true,
  },
  role: {
    type: String,
  },
});

// 引入vuex
const sysStore = useSystemStore();

// 文件信息
const obj = reactive({
  showDialog: false, // 是否展示附件
  fileUrl: [] // 附件地址
})

const getIcon = (type: string) => {
  type = type.toLowerCase();
  let fileType: "doc" | "pdf" | "xlsx" | "txt" | "" = "";
  let iconIamge = "";
  const docMap = [
    "doc",
    "docx",
    "application/msword",
    "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
  ];
  const pdfMap = ["application/pdf", "pdf"];
  const xlsxMap = [
    "application/vnd.ms-excel",
    "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
    "xls",
    "xlsx",
  ];
  const textMap = ["txt", "text/plain", "text"];
  if (docMap.includes(type)) {
    fileType = "doc";
    iconIamge = wordImg;
  } else if (pdfMap.includes(type)) {
    fileType = "pdf";
    iconIamge = pdfImg;
  } else if (xlsxMap.includes(type)) {
    fileType = "xlsx";
    iconIamge = excelImg;
  } else if (textMap.includes(type)) {
    fileType = "txt";
    iconIamge = textImg;
  } else {
    fileType = "";
    iconIamge = unknownImg;
  }
  return {
    fileType,
    iconIamge: iconIamge,
  };
};

// 获取文件数据
const fileView = async(item) => {
const {id} = item
const res = await getPolicy(id)
const {url,name,size,mime_type} = res.data
// 这里拿到的数据:url:完整的url文件流地址
 // name: 文件名
 //size: 文件字节大小
 // mime_type: 文件对应的类型 譬如txt对应 text/plain
// 获取文件后缀类型
const {fileType} = getIcon(mime_type)
const fileInfo = {
  name,
  fileType,
  type: mime_type,
  size,
  viewUrl: url
}
 // 更新文件信息
 sysStore.setFileViewInfo(fileInfo);
// 先关闭
obj.showDialog = false
// 确保dom更新后再次打卡
await nextTick()
obj.showDialog = true
};




</script>



<style lang="less" scoped>
.file-view {
  .file-item {
    display: flex;
    align-items: center;
    border: 1px solid var(--baseColor);
    padding: 8px;
    cursor: pointer;
    min-width: 240px;
    max-width: 300px;
    border-radius: 5px;
    .file-icon {
      margin-right: 5px;
    }
    .file-info {
      max-width: calc(100% - 28px);
      .file-size {
        font-size: var(--fontSizeSmall);
      }
    }
  }
}
</style>

总结

记录一下 希望能帮助到你

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2403855.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

增量式网络爬虫通用模板

之前做过一个项目&#xff0c;他要求是只爬取新产生的或者已经更新的页面&#xff0c;避免重复爬取未变化的页面&#xff0c;从而节省资源和时间。这里我需要设计一个增量式网络爬虫的通用模板。可以继承该类并重写部分方法以实现特定的解析和数据处理逻辑。这样可以更好的节约…

【JVM】三色标记法原理

在JVM中&#xff0c;三色标记法是GC过程中对象状态的判断依据&#xff0c;回收前给对象设置上不同的三种颜色&#xff0c;三色分为白色、灰色、黑色。根据颜色的不同&#xff0c;决定对象是否要被回收。 白色表示&#xff1a; 初始状态&#xff1a;所有对象未被 GC 访问。含义…

【uniapp开发】picker组件的使用

项目uniapp&#xff0c;结合fastadmin后端开发 picker组件的官方文档说明 https://en.uniapp.dcloud.io/component/picker.html#普通选择器 先看效果&#xff1a; 1、实现设备类型的筛选&#xff1b;2、实现设备状态的筛选&#xff1b; 前端代码&#xff08;节选&#xff0…

【HarmonyOS Next之旅】DevEco Studio使用指南(三十一) -> 同步云端代码至DevEco Studio工程

目录 1 -> 同步云函数/云对象 1.1 -> 同步单个云函数/云对象 1.2 -> 批量同步云函数/云对象 2 -> 同步云数据库 2.1 -> 同步单个对象类型 2.2 -> 批量同步对象类型 3 -> 一键同步云侧代码 1 -> 同步云函数/云对象 说明 对于使用DevEco Studio…

go-zero微服务入门案例

一、go-zero微服务环境安装 1、go-zero脚手架的安装 go install github.com/zeromicro/go-zero/tools/goctllatest2、etcd的安装下载地址根据自己电脑操作系统下载对应的版本&#xff0c;具体的使用自己查阅文章 二、创建一个user-rpc服务 1、定义user.proto文件 syntax &qu…

Python控制台输出彩色字体指南

在Python开发中&#xff0c;有时我们需要在控制台输出彩色文本以提高可读性或创建更友好的用户界面。本文将介绍如何使用colorama库来实现这一功能。 为什么需要彩色输出&#xff1f; 提高可读性&#xff1a;重要信息可以用不同颜色突出显示更好的用户体验&#xff1a;错误信息…

开源之夏·西安电子科技大学站精彩回顾:OpenTiny开源技术下沉校园,点燃高校开发者技术热情

开源之夏2025编程活动正在如火如荼的进行中&#xff0c;当前也迎来了报名的倒计时阶段&#xff0c;开源之夏组织方也通过高校行系列活动进入各大高校&#xff0c;帮助高校开发者科普开源文化、开源活动、开源技术。 6月4日 开源之夏携手多位开源技术大咖、经验型选手走进西安电…

解决数据库重启问题

最近部署软件时&#xff0c;发现mysql会一直在重启&#xff0c;记录下解决办法&#xff1a; 1.删除/home/dataexa/install/docker/datas/mysql路径下的data文件夹 2.重新构建mysql docker-compose up -d --build mysql 3.停掉所有应用&#xff0c;在全部重启&#xff1a; do…

前后端交互过程中—各类文件/图片的上传、下载、显示转换

前后端交互过程中—各类文件/图片的上传、下载、显示转换 图片补充&#xff1a;new Blob()URL.createObjectURL()替代方案&#xff1a;FileReader.readAsDataURL()​​对比&#xff1a; tiff文件TIFF库TIFF转换通过url转换tiff文件为png通过文件选择的方式转换tiff文件为png 下…

数据库同步是什么意思?数据库架构有哪些?

目录 一、数据库同步是什么 &#xff08;一&#xff09;基本概念 &#xff08;二&#xff09;数据库同步的类型 &#xff08;三&#xff09;数据库同步的实现方式 二、数据库架构的类型 &#xff08;一&#xff09;单机架构 &#xff08;二&#xff09;主从复制架构 &a…

【数据结构】详解算法复杂度:时间复杂度和空间复杂度

&#x1f525;个人主页&#xff1a;艾莉丝努力练剑 ❄专栏传送门&#xff1a;《C语言》、《数据结构与算法》 &#x1f349;学习方向&#xff1a;C/C方向 ⭐️人生格言&#xff1a;为天地立心&#xff0c;为生民立命&#xff0c;为往圣继绝学&#xff0c;为万世开太平 前言&…

Rest-Assured API 测试:基于 Java 和 TestNG 的接口自动化测试

1. 右键点击项目的文件夹&#xff0c;选择 New > File。 2. 输入文件名&#xff0c;例如 notes.md&#xff0c;然后点击 OK。 3. 选择项目类型 在左侧的 Generators 部分&#xff0c;选择 Maven Archetype&#xff0c;这将为你生成一个基于 Maven 的项目。 4. 配置项目基…

react public/index.html文件使用env里面的变量

env文件 ENVdevelopment NODE_ENVdevelopment REACT_APP_URL#{REACT_APP_URL}# REACT_APP_CLIENTID#{REACT_APP_CLIENTID}# REACT_APP_TENANTID#{REACT_APP_TENANTID}# REACT_APP_REDIRECTURL#{REACT_APP_REDIRECTURL}# REACT_APP_DOMAIN_SCRIPT#{REACT_APP_DOMAIN_SCRIPT}#pu…

chili3d 笔记17 c++ 编译hlr 带隐藏线工程图

这个要注册不然emscripten编译不起来 --------------- 行不通 ---------------- 结构体 using LineSegment std::pair<gp_Pnt, gp_Pnt>;using LineSegmentList std::vector<LineSegment>; EMSCRIPTEN_BINDINGS(Shape_Projection) {value_object<LineSegment&g…

创建一个纯直线组成的字体库

纯直线组成的字体&#xff0c;一个“却”由五组坐标点组成&#xff0c;存储5个点共占21字节&#xff0c;使用简单&#xff0c;只要画直线即可&#xff0c; “微软雅黑”&#xff0c;2个轮廓&#xff0c;55坐标点&#xff0c;使用复杂&#xff0c;还填充。 自创直线字体 “微软…

Linux进程(中)

目录 进程等待 为什么有进程等待 什么是进程等待 怎么做到进程等待 wait waitpid 进程等待 为什么有进程等待 僵尸进程无法杀死&#xff0c;需要进程等待来消灭他&#xff0c;进而解决内存泄漏问题--必须解决的 我们要通过进程等待&#xff0c;获得子进程退出情况--知…

【计算机组成原理】计算机硬件的基本组成、详细结构、工作原理

引言 计算机如同现代科技的“大脑”&#xff0c;其硬件结构的设计逻辑承载着信息处理的核心奥秘。从早期程序员手动输入指令的低效操作&#xff0c;到冯诺依曼提出“存储程序”概念引发的革命性突破&#xff0c;计算机硬件经历了从机械操控到自动化逻辑的蜕变。本文将深入拆解…

MVC分层架构模式深入剖析

&#x1f504; MVC 交互流程 #mermaid-svg-5xGt0Ka13DviDk15 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-5xGt0Ka13DviDk15 .error-icon{fill:#552222;}#mermaid-svg-5xGt0Ka13DviDk15 .error-text{fill:#552222…

新能源汽车热管理核心技术解析:冬季续航提升40%的行业方案

新能源汽车热管理核心技术解析&#xff1a;冬季续航提升40%的行业方案 摘要&#xff1a;突破续航焦虑的关键在热能循环&#xff01; &#x1f449; 本文耗时72小时梳理行业前沿方案&#xff0c;含特斯拉/比亚迪等8家车企热管理系统原理图 一、热管理为何成新能源车决胜关键&am…

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1开通指南及使用心得

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;CSDN领军人物&#xff0c;全栈领域优质创作者✌&#xff0c;CSDN博客专家&#xff0c;阿里云社区专家博主&#xff0c;2023年CSDN全站排名top 28。 &#x1f3c6;数年电商行业从业经验&#xff0c;AWS/阿里云资深使用用…