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

起步

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

  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,实现下图的预览效果。


相关推荐
毋若成25 分钟前
前端三大组件之CSS,三大选择器,游戏网页仿写
前端·css
红中马喽28 分钟前
JS学习日记(webAPI—DOM)
开发语言·前端·javascript·笔记·vscode·学习
Black蜡笔小新1 小时前
网页直播/点播播放器EasyPlayer.js播放器OffscreenCanvas这个特性是否需要特殊的环境和硬件支持
前端·javascript·html
秦jh_2 小时前
【Linux】多线程(概念,控制)
linux·运维·前端
蜗牛快跑2133 小时前
面向对象编程 vs 函数式编程
前端·函数式编程·面向对象编程
Dread_lxy3 小时前
vue 依赖注入(Provide、Inject )和混入(mixins)
前端·javascript·vue.js
涔溪3 小时前
Ecmascript(ES)标准
前端·elasticsearch·ecmascript
榴莲千丞4 小时前
第8章利用CSS制作导航菜单
前端·css
奔跑草-4 小时前
【前端】深入浅出 - TypeScript 的详细讲解
前端·javascript·react.js·typescript
羡与4 小时前
echarts-gl 3D柱状图配置
前端·javascript·echarts