当前位置: 首页 > article >正文

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

文件预览

    • 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.kler.cn/a/369208.html

相关文章:

  • vulnhub(16):sickos(两种打点方式)
  • HTTP与RPC
  • 衡石分析平台系统分析人员手册-导入图表库图表
  • logdata-anomaly-miner:一款安全日志解析与异常检测工具
  • 软考:中间件
  • 实验:使用Oxygen发布大型手册到Word格式
  • 「ZJUBCA秋季迎新见面会预告」
  • Netty的简介与实战
  • Java运行时数据区
  • 助力AI智能化时代:全国产化飞腾FT2000+/64+昇腾310B服务器主板
  • 关于k8s的cilium网络插件踩坑记
  • Android Audio基础——音频混音结束处理(十一)
  • 基于Matlab 火焰识别技术
  • 使用 Python 的 BeautifulSoup(bs4)解析复杂 HTML
  • remote: The project you were looking for could not be found.
  • ThingsBoard规则链节点:Device Profile节点详解
  • 字节的学习
  • iOS Swift逆向——被编译优化后的函数参数调用约定修复
  • C#中的事件
  • 029_Common_Plots_Matlab常见二维绘图
  • 【阅读笔记】Instruction-based Hypergraph Pretraining
  • PHP如何实现字符串翻转
  • 【实战案例】Django框架表单处理及数据库交互
  • 【YOLOv11[基础]】实例分割 + 跟踪
  • 二叉树习题其六【力扣】【算法学习day.13】
  • 基于KV260的基础视频链路通路(MIPI+Demosaic+VDMA)