前端如何实现文件的在线预览?

起步

在计算机的世界中,有各种各样的文件,文件类型千奇百怪,作为一名前端开发工程师,我们如何来实现这些文件的在线预览呢?在上篇文章,我们已经实现了前端如何实现压缩包解析?,但是也仅仅是能够查看压缩包中的内容,并不能真实的去进行线上预览,这节就是在上节的基础上,举例一些我们日常经常接触的文件来进行预览:

  1. 文本类文件(虽然类型很多,但是处理方式基本都是一样的)

    js 复制代码
     const txtType = ['txt','html','htm','asp','jsp','js','xml','json','properties','md','gitignore','log','java','py','c','cpp','sql','sh','bat','m','bas','prg','cmd','vue','ts','tsx','yml','yaml','css',];
  2. 图片const pictureType = ['jpg', 'png', 'gif','webp'];

  3. 音视频文件(这里以.mp4举例)

  4. office文件

    javascript 复制代码
    const wordType = ['docx', 'doc']; // word
    const excelType = ['xls', 'xlsx']; // excel
    const pptType = ['ppt', 'pptx']; //ppt

回顾一下,上节我们已经完成的页面,可以看作左右两部分,左侧为我们解析出来的压缩包内文件的树结构,右侧为我们需要预览的文件。

我们监听了树的点击事件当点击某个文件的时候能够拿到这个文件的相关信息,包括File对象。

我们的dom结构大概是这样的,根据我们当前点击的文件类型展示不同的元素。

html 复制代码
<div class='left'>
  <!-- 文件树结构 -->
  <a-tree></a-tree>
</div>
<div class='left'>
  <!-- 图片 -->
  <div v-if="pictureType.some(item => item == currentFile?.fileType)">
    <img :src="currentFile?.url" class="img" title="点击查看" v-viewer />
  </div>
  <!-- 文本 -->
  <div v-else-if="txtType.some((item) => item == currentFile?.fileType)" class="txt">
    <code>{{ textContent }}</code>
  </div>
  <!-- 视频 -->
  <div v-else-if="currentFile?.fileType == 'mp4'" style="width: 100%;">
    <video :src="currentFile.url"></video>
  </div>
  .....
</div>

那么我们如何读取文件的内容呢?这里我们需要用到一个api,FileReader - Web API | MDN

FileReader 接口允许 Web 应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 FileBlob 对象指定要读取的文件或数据。

调用这个构造函数会返回一个实例,通过这个实例我们就能将文件读取成任何我们想要的类型了。

1.文本类文件

js 复制代码
// 文本内容
const textContent: string = ref('')
const reader: any = new FileReader()

// 文本文件,直接使用readAsText将文件读取为文本再展示即可
if (txtType.some((item) => item == fileType)) {
  reader.readAsText(file)
  reader.onload = () => textContent.value = reader.result
}

2. 图片类文件

将文件读取为base64的字符串,直接借助浏览器的img标签展示即可展示。

javascript 复制代码
const reader: any = new FileReader()
// 图片
if (pictureType.some(item => item == fileType)) {
  reader.readAsDataURL(file)
  reader.onload = () => currentFile.value.url = reader.result
}

3. 音视频类文件

音视频文件的预览直接使用对应的标签即可,即和,但是都是通过src属性指定需要播放的内容的,所以,我们可以读取文件后调用URL.createObjectURL将对象转换为一个包含对象 URL 的字符串,然后赋值即可。

javascript 复制代码
const reader: any = new FileReader()
// 视频
if (fileType == 'mp4') {
  reader.readAsArrayBuffer(file)
  reader.onload = () => currentFile.value.url = URL.createObjectURL(new Blob([reader.result], { type: 'video/mp4' }))
}

4. office文件

4.1 docx、xlsx、pdf

docx、xlsx、pdf文件的预览,我们需要借助vue-office这个库帮我们完成,这里贴上需要安装的依赖,使用方法很简单可以参考官方给出的示例vue-office简介 | vue-office

bash 复制代码
#docx文档预览组件
npm install @vue-office/docx vue-demi

#excel文档预览组件
npm install @vue-office/excel vue-demi

#pdf文档预览组件
npm install @vue-office/pdf vue-demi
4.1.1 word预览
html 复制代码
<div v-else-if="wordType.some((item) => item == currentFile?.fileType)" class="word">
  <vue-office-docx :src="currentFile?.url" style=" height: 100vh;" />
</div>
javascript 复制代码
//引入VueOfficeDocx组件
import VueOfficeDocx from '@vue-office/docx'
//引入相关样式
import '@vue-office/docx/lib/index.css'

if (wordType.some((item) => item == fileType)) {
  reader.readAsArrayBuffer(file)
  reader.onload = () => currentFile.value.url = URL.createObjectURL(new Blob([reader.result]))  
}
4.1.2 excel预览
html 复制代码
<div v-else-if="excelType.some((item) => item == currentFile?.fileType)" class="excel">
  <VueOfficeExcel :src="currentFile?.url" style="width: 100vw; height: 100vh;" />
</div>
javascript 复制代码
//引入VueOfficeExcel组件
import VueOfficeExcel from '@vue-office/excel'
//引入相关样式
import '@vue-office/excel/lib/index.css'

if (excelType.some((item) => item == fileType)) {
  reader.readAsArrayBuffer(file)
  reader.onload = () => currentFile.value.url = URL.createObjectURL(new Blob([reader.result]))  
}
4.1.3 pdf预览
html 复制代码
<div v-else-if="currentFile?.fileType == 'pdf'" class="pdf">
  <vueOfficePdf :src="currentFile?.url" style="width: 100%; height: 100vh;" />
</div>
javascript 复制代码
//引入VueOfficePdf组件
import VueOfficePdf from '@vue-office/pdf'

if (fileType === 'pdf') {
  reader.readAsArrayBuffer(file)
  reader.onload = () => currentFile.value.url = URL.createObjectURL(new Blob([reader.result]))  
}

说明 :vue-office这个插件库基本可以满足我们的预览需求,但是要注意@vue-office/docx对word的预览只支持docx后缀的文件,还不支持doc后缀的文件,如果有预览doc文件的需求可以选择一些文档预览服务。

4.2 ppt文件预览

使用插件的方式目前找到了一款,PPTXjs这款库,进入链接后要先把源码下载下来,然后根据官方示例,将所需的文件引入完成预览。

结合后端的方案

部署ONLYOFFICE,后端提供接口,前端使用ONLYOFFICE相关的API完成文档的预览,下载 ONLYOFFICE Docs | ONLYOFFICE。下篇文章我们以spring boot+vue3的技术栈为例,在linux服务器部署ONLYOFFICE,实现下图的预览效果。


相关推荐
夫琅禾费米线29 分钟前
[有趣的JavaScript] 为什么typeof null返回 object
开发语言·前端·javascript
nothing_more_than4 小时前
draggable的el-dialog实现对话框标题可以选择
javascript·vue.js·element-plus
小镇程序员5 小时前
vue2 src自定义事件
前端·javascript·vue.js
炒毛豆6 小时前
vue3+echarts+ant design vue实现进度环形图
javascript·vue.js·echarts
AlgorithmAce8 小时前
Live2D嵌入前端页面
前端
nameofworld8 小时前
前端面试笔试(六)
前端·javascript·面试·学习方法·递归回溯
别拿曾经看以后~8 小时前
原生Android调用uniapp项目中的方法
android·vue.js·uni-app
前端fighter8 小时前
js基本数据新增的Symbol到底是啥呢?
前端·javascript·面试
GISer_Jing8 小时前
从0开始分享一个React项目:React-ant-admin
前端·react.js·前端框架
川石教育9 小时前
Vue前端开发子组件向父组件传参
前端·vue.js·前端开发·vue前端开发·vue组件传参