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

起步

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

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


相关推荐
0思必得03 分钟前
[Web自动化] Selenium设置相关执行文件路径
前端·爬虫·python·selenium·自动化
雯0609~13 分钟前
hiprint:实现项目部署与打印1-官网提供普通html版本
前端·html
不绝1911 小时前
UGUI——进阶篇
前端
~牧马~1 小时前
【记录63】electron打包vue项目之踩坑
vue.js·electron·electron与node兼容
Exquisite.1 小时前
企业高性能web服务器(4)
运维·服务器·前端·网络·mysql
2501_944525542 小时前
Flutter for OpenHarmony 个人理财管理App实战 - 账户详情页面
android·java·开发语言·前端·javascript·flutter
计算机学姐2 小时前
基于SpringBoot的电影点评交流平台【协同过滤推荐算法+数据可视化统计】
java·vue.js·spring boot·spring·信息可视化·echarts·推荐算法
2601_949857432 小时前
Flutter for OpenHarmony Web开发助手App实战:快捷键参考
前端·flutter
wangdaoyin20102 小时前
若依vue2前后端分离集成flowable
开发语言·前端·javascript
心柠2 小时前
vue3相关知识总结
前端·javascript·vue.js