【Vue】word / excel / ppt / pdf / 视频(mp4,mov) 预览

news2024/11/25 19:55:04

文件预览

    • Vue3
    • 一. word
    • 二. excel
    • 三. ppt
    • 四. pdf
      • 4.1 vue-pdf-embed
      • 4.2 iframe
    • 五. 视频
    • 六:扩展——kkFileView

Vue3

一. word

  1. 安装:npm install docx-preview
  2. 父页面
<template>
	<div>
		<DocPreview
          v-if="filePath.includes('docx')"
          :doc-url="filePath"
        />
	</div>
</template>
<script setup>
import DocPreview from '@/components/DocPreview'
const filePath = ref('https://xxxxxxxxxxxx.docx') 
</script>
  1. 组件
    路径:@/components/DocPreview
<!-- word 文档阅读 -->
<template>
  <div>
    <div v-if="message" class="doc-empty">{{ message }}</div>
    <div v-else class="doc-render-wraper">
      <div ref="fileRef">
        <div ref="fileStyleRef"></div>
      </div>
    </div>
  </div>
</template>

<script setup>
import axios from 'axios'
// const docx = require('docx-preview')
import { renderAsync } from 'docx-preview'

const props = defineProps({
  // 文档地址
  docUrl: {
    type: String,
    default: ''
  }
})

const service = axios.create({
  baseURL: props.docUrl,
  timeout: 600000
})
const fileRef = ref(null)
const fileStyleRef = ref(null)
const message = ref('')
// 预览
const init = async () => {
  const { data } = await service({
    method: 'get',
    responseType: 'blob'
  })
  // console.log(data)
  if (data.size === 0) {
    message.value = '当前文档内容为空,无可阅读内容'
  } else {
    message.value = ''
    renderAsync(data, fileRef.value, fileStyleRef.value)
  }
}

watch(
  () => props.docUrl,
  newVal => {
    if (newVal !== null && newVal !== '') {
      init()
    }
  }
)

init()
</script>
<style lang="scss" scoped>
.doc-render-wraper {
  width: 840px;
  padding-top: 10px;
  margin: 0 auto;
  overflow-x: auto;

  // fileStyleRef css
  > div {
    border: 1px solid #e6edf5;
  }
}
.doc-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  color: #0f5c9f;
  background-color: #e6edf5;
  width: 100%;
  height: 50px;
}
</style>

二. excel

在这里插入图片描述

  1. 安装:npm install @vue-office/excel
  2. 父页面
<template>
	<div>
		<XlsxPreview :xlsx-url="filePath" />
	</div>
</template>
<script setup>
import XlsxPreview from '@/components/XlsxPreview'
</script>
  1. 组件
<!-- excel 文档阅读 -->
<template>
  <div class="xlsx-preview">
    <vue-office-excel :src="source" class="vue-office-excel" />
  </div>
</template>
<script setup>
// 引入VueOfficeExcel组件
import VueOfficeExcel from '@vue-office/excel'
// 引入相关样式
import '@vue-office/excel/lib/index.css'
const props = defineProps({
  // 文档地址
  xlsxUrl: {
    type: String,
    default: ''
  }
})
const source = ref(props.xlsxUrl)
</script>
<style lang="scss" scoped>
.xlsx-preview {
  width: 840px;
  height: 100%;
  padding: 20px 0;
  margin: 0 auto;
  box-sizing: border-box;
}
.vue-office-excel {

  width: 100%;
  height: 100%;
  border: 1px solid #e5e5e5;
  margin: 0 auto;
  box-sizing: border-box;
}
</style>

三. ppt

  1. 官网:https://github.com/meshesha/PPTXjs
    demo:https://pptx.js.org/pages/demos.html
  2. 注意:先引入pptjs
    在这里插入图片描述
    在这里插入图片描述
  3. 父文件
<template>
	<div>
		<PptxPreview :pptx-url="filePath" />
	</div>
</template>
<script setup>
import PptxPreview from '@/components/PptxPreview/index.vue'
const filePath = ref("")

</script>
  1. 组件
<!-- pptx 文档阅读 -->
<template>
  <div class="xlsx-preview">
    <div class="page-tool">
      <div class="page-tool-item" @click="pageZoomOut">放大</div>
      <div class="page-tool-item" @click="pageZoomIn">缩小</div>
    </div>
    <!-- <div style="display: grid; place-content: center; color: darkgrey">pptx文件暂时无法预览~~~</div> -->
    <div style="height: 1200px; width: 90%; zoom: 0.5; overflow-y: auto; overflow-x: auto; margin: 0 30px">
      <div
        id="your_div_id_result"
        style="position: relative"
        :style="`transform:scale(${size});transform-origin:0% 0%`"
      ></div>
    </div>
  </div>
</template>
<script setup>
const props = defineProps({
  // 文档地址
  pptxUrl: {
    type: String,
    default: ''
  }
})
const size = ref(1)
function init(newVal) {
  $('#your_div_id_result').pptxToHtml({
    pptxFileUrl: newVal,
    slidesScale: '50%'
  })
}
onBeforeUnmount(() => {
  $('#your_div_id_result').empty()
})
const pageZoomOut = () => {
  if (size.value < 3) {
    size.value += 0.1
  }
}
const pageZoomIn = () => {
  if (size.value > 0.8) {
    size.value -= 0.1
  }
}
watch(
  () => props.pptxUrl,
  newVal => {
    if (newVal) {
      setTimeout(() => {
        init(newVal)
      }, 1000)
    }
  },
  { immediate: true }
)
</script>
<style lang="scss" scoped>
// import './css/pptxjs.css' import './css/nv.d3.min.css'
.xlsx-preview {
  width: 840px;
  height: 100%;
  // margin-left: 80px;
  padding: 20px 0;
  // margin: 0 auto;
  box-sizing: border-box;
}
.vue-office-excel {
  width: 100%;
  height: 100%;
  border: 1px solid #e5e5e5;
  margin: 0 auto;
  box-sizing: border-box;
}

.page-tool {
  display: flex;
  align-items: center;
  justify-content: center;
  margin-left: 50px;
  margin-bottom: 20px;
  padding: 8px 0;
  // width: 400px;
  width: 80%;
  text-align: center;
  background: #e6edf5;
  color: #0f5c9f;
  border-radius: 19px;
  cursor: pointer;
}

.page-tool-item {
  padding: 0 15px;
  padding-left: 10px;
  cursor: pointer;
}
</style>

  1. 缺陷
    (1)不支持上传jpg格式的图片:若ppt中含有jpg格式的图片,报错
    (2)支持仅pptx文件格式

四. pdf

4.1 vue-pdf-embed

功能:放大、缩小、跳转到某页
在这里插入图片描述

  1. 安装: npm install vue-pdf-embed
  2. 父页面
<template>
	<div>
		<PdfPreview :key="fileIndex" :pdf-url="filePath" />
	</div>
<template>
<script setup>
const fileIndex = ref(0)
const filePath = ref(https://xxxxxxxxxxxxxxx.pdf)

</script>
  1. 组件
<template>
  <div class="pdf-preview">
    <div v-if="props.pdfUrl.indexOf('undefined') == -1" v-loading="pdfLoading">
      <div class="page-tool">
        <div class="page-tool-item" @click="lastPage">上一页</div>
        <div class="page-tool-item" @click="nextPage">下一页</div>
        <div class="page-tool-item">{{ state.pageNum }}/{{ state.numPages }}</div>
        <div class="page-tool-item" @click="pageZoomOut">放大</div>
        <div class="page-tool-item" @click="pageZoomIn">缩小</div>
        <div class="page-tool-item">前往</div>
        <el-input v-model.number="currentPage" style="width: 100px" @input="goToPage(currentPage)" /></div>
      <div class="pdf-wrap">
        <vue-pdf-embed
          ref="pdfRef"
          :source="{
            cMapUrl: 'https://cdn.jsdelivr.net/npm/pdfjs-dist@2.6.347/cmaps/',
            url: state.source,
            cMapPacked: true
          }"
          class="vue-pdf-embed"
          :style="`transform:scale(${state.scale});transform-origin:0% 0%`"
          :page="state.pageNum"
          @loading-failed="pdfLoading = false"
          @rendered="handleDocumentRender"
        />
      </div>
    </div>
  </div>
</template>
<script setup>
import { defineAsyncComponent } from 'vue'
const { proxy } = getCurrentInstance()
const VuePdfEmbed = defineAsyncComponent(() => import('vue-pdf-embed'))
const props = defineProps({
  pdfUrl: {
    type: String,
    required: true,
    default: ''
  }
})
const pdfLoading = ref(true)
const currentPage = ref(1)
const state = reactive({
  source: props.pdfUrl, // 预览pdf文件地址
  pageNum: 1, // 当前页面
  scale: 1, // 缩放比例
  numPages: 0 // 总页数
})

// 加载完成
const handleDocumentRender = () => {
  pdfLoading.value = false
  state.numPages = proxy.$refs.pdfRef.pageCount
}
const lastPage = () => {
  if (state.pageNum > 1) {
    state.pageNum -= 1
    currentPage.value = state.pageNum
  }
}

const nextPage = () => {
  if (state.pageNum < state.numPages) {
    state.pageNum += 1
    currentPage.value = state.pageNum
  }
}
const pageZoomOut = () => {
  if (state.scale < 3) {
    state.scale += 0.1
  }
}
const pageZoomIn = () => {
  if (state.scale > 0.8) {
    state.scale -= 0.1
  }
}

const goToPage = page => {
  if (page >= 1 && page <= state.numPages) {
    currentPage.value = page
    state.pageNum = page
  }
}
</script>
<style lang="scss" scoped>
.pdf-preview {
  //   position: relative;
  width: 840px;
  // height: 1250px;
  padding: 10px 0;
  margin: 0 auto;
  box-sizing: border-box;
}
.pdf-wrap {
  overflow-y: auto;
}
.vue-pdf-embed {
  text-align: center;
  width: 100%;
  border: 1px solid #e5e5e5;
  margin: 0 auto;
  box-sizing: border-box;
}

.page-tool {
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 10px auto;
  // width: 400px;
  width: 80%;
  text-align: center;
  background: #e6edf5;
  color: #0f5c9f;
  border-radius: 19px;
  cursor: pointer;
}

.page-tool-item {
  padding: 0 15px;
  padding-left: 10px;
  cursor: pointer;
}
</style>

4.2 iframe

<template>
	<div>
		<iframe type="application/pdf" :src="filePath"width="800" height="1000">
    	</iframe>
	</div>
<template>
<script setup>
const filePath = ref("")
<script>

五. 视频

在这里插入图片描述

  1. 支持格式:.mov,.mp4
  2. 父文件
<template>
	<div>
		<VideoPreview
          v-if="subfix == 'mp4' || 'mov')"
          :url="videoUrl"
          :isExport="isExport"
        />
	</div>
</template setup>
<script>
import VideoPreview from '@/components/VideoPreview'
const subfix = ref('mp4') // 视频文件后缀
const videoUrl = ref('')
const isExport = ref(true)
</script>
  1. 组件
<template>
  <div v-if="filePath" style="overflow-x: auto">
    <video
      oncontextmenu="return false;"
      :src="filePath"
      :style="`width: ${widths}% `"
      class="w-[218px] h-[140px] rounded-[4px] bg-second video"
      controls
      autoplay
      disablePictureInPicture
      :controlsList="isDownload ? 'noremoteplayback noplaybackrate' : 'noremoteplayback noplaybackrate nodownload'"
    >
      <source />
    </video>
  </div>
</template>
<script setup>
import dragWidthStore from '@/views/satisfiedEngineering/evaluationProcedure/store/dragWidth'
const widths = computed(() => dragWidthStore().width)
const filePath = ref('')
const isDownload = ref(false) // 是否给控件赋予下载权限
const props = defineProps({
  url: {
    type: String,
    default: ''
  },
  isExport: {
    type: Boolean,
    default: true,
    require: false
  }
})

watch(
  () => props.url,
  newValue => {
    filePath.value = newValue
  },
  { deep: true, immediate: true }
)

watch(
  () => props.isExport,
  newValue => {
    isDownload.value = newValue
  },
  { deep: true, immediate: true }
)
</script>

六:扩展——kkFileView

项目中没涉及到,大致记录一下

  1. 官网:https://kkfileview.keking.cn/kkFileView-4.1.0-docker.tar

  2. 支持格式
    在这里插入图片描述

  3. 组件

<!-- 文件预览
  支持 doc, docx, xls, xlsx, xlsm, ppt, pptx, csv, tsv, dotm, xlt, xltm, dot, dotx, xlam, xla, pages 等 Office 办公文档
  支持 wps, dps, et, ett, wpt 等国产 WPS Office 办公文档
  支持 odt, ods, ots, odp, otp, six, ott, fodt, fods 等OpenOffice、LibreOffice 办公文档
  支持 vsd, vsdx 等 Visio 流程图文件
  支持 wmf, emf 等 Windows 系统图像文件
  支持 psd, eps 等 Photoshop 软件模型文件
  支持 pdf ,ofd, rtf 等文档
  支持 xmind 软件模型文件
  支持 bpmn 工作流文件
  支持 eml 邮件文件
  支持 epub 图书文档
  支持 obj, 3ds, stl, ply, gltf, glb, off, 3dm, fbx, dae, wrl, 3mf, ifc, brep, step, iges, fcstd, bim 等 3D 模型文件
  支持 dwg, dxf, dwf, iges , igs, dwt, dng, ifc, dwfx, stl, cf2, plt 等 CAD 模型文件
  支持 txt, xml(渲染), md(渲染), java, php, py, js, css 等所有纯文本
  支持 zip, rar, jar, tar, gzip, 7z 等压缩包
  支持 jpg, jpeg, png, gif, bmp, ico, jfif, webp 等图片预览(翻转,缩放,镜像)
  支持 tif, tiff 图信息模型文件
  支持 tga 图像格式文件
  支持 svg 矢量图像格式文件
  支持 mp3,wav,mp4,flv 等音视频格式文件
  支持 avi,mov,rm,webm,ts,rm,mkv,mpeg,ogg,mpg,rmvb,wmv,3gp,ts,swf 等视频格式转码预览
  支持 dcm 等医疗数位影像预览
  支持 drawio 绘图预览

  Docker环境部署:
  网络环境方便访问docker中央仓库
  docker pull keking/kkfileview:4.1.0

  网络环境不方便访问docker中央仓库
  wget https://kkfileview.keking.cn/kkFileView-4.1.0-docker.tar
  docker load -i kkFileView-4.1.0-docker.tar -->
<template>
  <div>
    <iframe
      :src="`${containerUrl}/onlinePreview?url=` + encodeURIComponent(Base64.encode(fileUrl))"
      frameborder="0"
      class="fileView"
    >
    </iframe>
  </div>
</template>

<script setup>
import { Base64 } from 'js-base64'

const props = defineProps({
  // 浏览器访问容器地址
  containerUrl: {
    type: String,
    default: ''
  },
  // 文档地址
  fileUrl: {
    type: String,
    default: ''
  }
})
</script>
<style lang="scss" scoped>
.fileView {
  width: 800px;
  height: 1020px;
  border-width: 1px;
}
</style>

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

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

相关文章

E. Sakurako, Kosuke, and the Permutation (置换环) Codeforces Round 981 (Div. 3)

哈哈哈, 之前做过一道置换环的题目, 但是当时不知道这是置换环 昨天写这道题目时老眼昏花, 读错题目, 如今一朝有悟,甄至化境 原题 E. Sakurako, Kosuke, and the Permutation 思路 这道题目与排序的不同在于, 如果第 i 个数不等于 i, 但是第 i 个数指向的数等于 i, 那么也…

基于RabbitMQ,Redis,Redisson,RocketMQ四种技术实现订单延时关闭功能及其相关优缺点介绍(以12306为主题)

目录 1. 延迟关闭订单 1.1 订单延时关闭功能技术选型 1.1.1 定时任务 1.1.2 RabbitMQ 1.1.3 Redis 过期监听 1.1.4 Redisson 1.1.5 RocketMQ 1.2 RocketMQ订单延时关闭发送方实现 1.3 RocketMQ订单延时关闭的消费方实现 1. 延迟关闭订单 用户发起订单后&#xff0c;如…

基于SSM的BBS社区论坛系统源码

运行环境&#xff1a;ideamysql5.7jdk8maven 使用技术&#xff1a;ssmmysqlshirolayui 功能模块&#xff1a;用户管理、模板管理、帖子管理、公告管理、权限管理等

使用 v-html 指令渲染的标签, 标签内绑定的 click 事件不生效

背景 在项目开发中&#xff0c;实现用户友好的输入交互是提升用户体验的关键之一。例如&#xff0c;在客服对话框中&#xff0c;其中有包含多个快捷选项用于快速问答&#xff0c;每个快捷选项都是一个可点击的按钮&#xff0c;并需要绑定点击事件来执行相应操作。然而&#xf…

Android Junit 单元测试 | 依赖配置和编译报错解决

问题 为什么在依赖中添加了testImplement在build APK的时候还是会报错&#xff1f;是因为没有识别到test文件夹是test源代码路径吗&#xff1f; 最常见的配置有: implementation - 所有源代码集(包括test源代码集)中都有该依赖库.testImplementation - 依赖关系仅在test源代码…

【CSS in Depth 2 精译_054】8.2 CSS 层叠图层(cascade layer)的推荐组织方案

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 【第三部分 现代 CSS 代码组织】 ✔️【第八章 层叠图层及其嵌套】 ✔️ 8.1 用 layer 图层来操控层叠规则&#xff08;上篇&#xff09; 8.1.1 图层的定义&#xff08;上篇&#xff09;8.1.2 图层的…

华为云实战杂记

配置nginx服务器 首先我们拿到一台服务器时&#xff0c;并不知道系统是否存在Nginx我们可以在Linux命令行执行如下命令查看 find / -name nginx* find / -name nginx* 查找所有名字以nginx开头的文件或者目录&#xff0c;我们看看系统里面都有哪些文件先&#xff0c;这样可以快…

Linux系统安装Redis详细操作步骤(二进制发布包安装方式)

安装方式介绍 在Linux系统中&#xff0c;安装软件的方式主要有四种&#xff0c;这四种安装方式的特点如下&#xff1a; 安装方式特点二进制发布包安装软件已经针对具体平台编译打包发布&#xff0c;只要解压&#xff0c;修改配置即可rpm安装软件已经按照redhat的包管理规范进…

雷池社区版有多个防护站点监听在同一个端口上,匹配顺序是怎么样的

如果域名处填写的分别为 IP 与域名&#xff0c;那么当使用进行 IP 请求时&#xff0c;则将会命中第一个配置的站点 以上图为例&#xff0c;如果用户使用 IP 访问&#xff0c;命中 example.com。 如果域名处填写的分别为域名与泛域名&#xff0c;除非准确命中域名&#xff0c;否…

NGINX 保护 Web 应用安全之基于 IP 地址的访问

根据客户端的 IP 地址控制访问 使用 HTTP 或 stream 访问模块控制对受保护资源的访问&#xff1a; location /admin/ { deny 10.0.0.1; allow 10.0.0.0/20; allow 2001:0db8::/32; deny all; } } 给定的 location 代码块允许来自 10.0.0.0/20 中的任何 IPv4 地址访问&#xf…

UE4_Niagara基础实例—9、使用条带渲染器来制作闪电

效果图&#xff1a; 一、通过模板Static Beam来熟悉条带渲染器 从Static Beam发射器新建niagara系统&#xff0c;更名为NS_StaticBeam。 打开粒子系统&#xff0c;界面如下&#xff1a; Beam Emitter Setup模块可以设置条带的开始点、结束点和切线。 我们就可以通过这个Beam E…

自动化测试:等待方式

在自动化测试中&#xff0c;等待是一个重要的技术&#xff0c;用于处理页面加载、元素定位、元素状态改变等延迟问题。 等待能够确保在条件满足后再进行后续操作&#xff0c;提高自动化测试的稳定性以及可靠性。 等待方式&#xff1a;显示等待、隐式等待、线程睡眠 1. 显式等…

【python】OpenCV—WaterShed Algorithm(1)

文章目录 1、功能描述2、代码实现3、完整代码4、效果展示5、涉及到的库函数5.1、cv2.pyrMeanShiftFiltering5.2、cv2.morphologyEx5.3、cv2.distanceTransform5.4、cv2.normalize5.5、cv2.watershed 6、参考 1、功能描述 基于分水岭算法对图片进行分割 分水岭分割算法&#x…

什么是域名?什么是泛域名?

域名 定义 域名是互联网上用于识别和定位网站或网络服务的名称。它是由一串用点分隔的字符组成&#xff0c;例如 “baidu.com”。就像是现实生活中建筑物的地址&#xff0c;方便用户在互联网的海量信息中找到特定的网站。 结构 域名从右到左依次为顶级域名&#xff08;TLD&…

go语言中的Scan()和Scanln()输入函数

Scan()输入函数 package mainimport "fmt"func main() {var a intvar b stringfor {fmt.Println("请输入一个整数和一个字符串&#xff08;用空格分隔&#xff09;&#xff1a;")fmt.Scan(&a, &b) // 直接读取输入到变量中fmt.Println("整数…

图书管理系统的简单实现

文章目录 图书系统逻辑分析各种操作功能的实现完整代码 个人主页 JavaSE专栏 图书系统逻辑分析 该程序设置有三个包&#xff0c;user 包&#xff0c;book 包&#xff0c;operation包。 book包中包含对于书的一些信息和操作;operation包中包含有对 书 的所有操作功能;user包中包…

‘perl‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件。

‘perl’ 不是内部或外部命令,也不是可运行的程序 或批处理文件。 明明已经根据教程安装了perl环境,但是在cmd中依赖报该错误,本章教程提供解决办法。 一、激活perl环境 state shell ActiveState-Perl-5.36.0此时输入perl -v 是可以直接输出perl版本号的。 二、找到perl的执…

想进体制内?到底有哪些路可走?原来有这么多方法

在如今的就业大环境下&#xff0c;体制内工作越来越受到大家的青睐。那么&#xff0c;体制内为何如此受欢迎呢&#xff1f; 一、体制内为何备受青睐 体制内工作首先给人一种强烈的稳定感和安全感。一旦进入体制&#xff0c;你不用时刻担心失业的风险&#xff0c;能够拥有一份长…

安康旅游网站:SpringBoot设计与实现详解

目 录 目 录 I 摘 要 III Abstract IV 第一章 绪论 1 1.1 研究现状 1 1.2 设计原则 1 1.3 研究内容 2 第二章 相关技术简介 1 2.1 JSP技术 1 2.2 Java技术 2 2.3 MYSQL数据库 2 2.4 B/S结构 3 2.5 Spring Boot框架 4 第三章 系统分析 5 3.1可行性分析 5 3.1.1技术可行性 5 3.1.…

阿里云项目启动OOM问题解决

问题描述 随着项目业务的增长&#xff0c;系统启动时内存紧张&#xff0c;每次第一次启动的时候就会出现oom第二次或者第n的时候&#xff0c;就启动成功了。 带着这个疑问&#xff0c;我就在阿里云上提交了工单&#xff0c;咨询为什么第一次提交失败但是后面却能提交成功尼&a…