前言
我們公司目前在做基于tiptap的在線協(xié)同文檔,其中有上傳附件的功能。在協(xié)同操作中,不能讓用戶看別人上傳的附件時,還需要下載到本地,又麻煩體驗又差。需要實現(xiàn)在線預(yù)覽的功能,方便其他閱讀者有更好的閱讀體驗。
像一般的圖片、視頻、office 等文件,我們都可以實現(xiàn)在線預(yù)覽功能,但始終不能覆蓋全部,萬一用戶上傳什么奇奇怪怪的文件。所以我們需要做好兜底處理,在無法預(yù)覽時給用于一個提示。比如下面這張圖對壓縮文件的處理,提示用戶主動下載進(jìn)行查看。

下面,我們將常見附件進(jìn)行分類,然后分別看一下不同的預(yù)覽方式。
圖片預(yù)覽
圖片的預(yù)覽可以直接使用<img>標(biāo)簽即可
<template>
<img v-if="file.type === 'img'" :style="imgStyle" :src="file.url" alt="" />
</template>
imgStyle用于設(shè)置圖片的樣式,比如一般會為圖片添加放大、縮小、旋轉(zhuǎn)功能,只需要設(shè)置圖片的scale、rotate屬性即可。
音視頻預(yù)覽
HTML5 的<video>和<audio>標(biāo)簽用于播放視頻和音頻,所以我們可以封裝一個組件專門來處理音視頻。
<template>
<RenderMedia />
</template>
<script setup lang="tsx">
const AUDIO_TYPE = ['mp3', 'ogg', 'mpeg']
const VIDEO_TYPE = ['mp4', 'ogg', 'webm']
const props = defineProps({
viewType: {
type: String,
required: true,
},
viewFileUrl: String,
})
const controls: any = 'controls'
const renderAudio = () => (
<audio
class="media-content__audio"
controls={controls}
controlslist="nodownload"
>
{AUDIO_TYPE.map((type) => (
<source width="100%" src={props.viewFileUrl} type={`audio/${type}`} />
))}
<embed width="100%" src={props.viewFileUrl} />
<embed width="100%" src={props.viewFileUrl} />
</audio>
)
const renderVideo = () => (
<video
class="media-content__video"
controls={controls}
controlslist="nodownload"
disablePictureInPicture // disablePictureInPicture取消畫中畫
>
{VIDEO_TYPE.map((type) => (
<source width="100%" src={props.viewFileUrl} type={`video/${type}`} />
))}
<object data={props.viewFileUrl} width="100%">
<embed src={props.viewFileUrl} width="100%" />
</object>
</video>
)
const RenderMedia = () => (
<div class="media-content">
{props.viewType === 'audio' ? renderAudio() : renderVideo()}
</div>
)
</script>
<style lang="scss" scoped>
.media-content {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
</style>
上面我封裝的 vue3+ts 的組件,因為我接觸 vue3 不久,還不知道里面的 JSX 語法怎么寫,剛好學(xué)習(xí)了 vue3 中的 JSX 語法前端 Vuer,請收下這份《Vue3 中使用 JSX 簡明語法》。
需要注意的是:在不支持 video 和 audio 元素的瀏覽器中,標(biāo)簽中間的內(nèi)容會顯示,作為降級處理。
最簡單的就是使用瀏覽器直接打開 pdf,也就是通過 iframe 的方式加載 pdf 文件,當(dāng)然也可以使用pdfjs這類比較成熟的 pdf 在線預(yù)覽方式,我們采用的是 iframe 方式,簡單直接。
<template>
<iframe
v-if="viewType === 'pdf'"
:src="viewFileUrl"
width="100%"
height="100%"
class="file-reader file-reader__iframe"
/>
</template>
代碼、文本等
本來想做代碼的預(yù)覽,想的是用codemirror來實現(xiàn),不過一般很少有人附件上傳代碼,所以我們暫時沒做代碼的預(yù)覽,要看直接可以使用代碼組件替代。
txt 文本的預(yù)覽也很簡單
先通過 url 將文本以
arraybuffer方式請求回來;-
接著通過 Blob 將 arraybuffer 數(shù)據(jù)轉(zhuǎn)換成 blob,通過 FileReader 去讀里面的內(nèi)容,最后賦值到我們需要展示的內(nèi)容上;
const blob = new Blob([bufferData], { type: 'text/plain', }) const fileReader = new FileReader() fileReader.readAsText(blob, 'utf-8') fileReader.onloadend = (e) => { content.value = fileReader.result || '' } -
將獲取到的文本展示在
<pre>標(biāo)簽中。<template> <pre class="previewer-content">{{ content }}</pre> </template>
office 在線預(yù)覽
office 的預(yù)覽可以直接采取網(wǎng)上的一些免費在線預(yù)覽即可。
先說幾款免費的
-
首推微軟在線 Office Web Viewer
優(yōu)點
免費,預(yù)覽效果比較好,官網(wǎng)地址
-
接入簡單,文件地址 url 需要通過
encodeURIComponent轉(zhuǎn)一下,url,否則會打不開<iframe style="width: 100%; min-height: 600px" :src="`https://view.officeapps.live.com/op/view.aspx?src=${encodeURIComponent(url)}`" width="100%" height="100%" frameborder="1" /> 支持多種格式
Word: .DOCX, .DOCM, .DOTM, .DOTX, .DOC
Excel: .XLSX, .XLSB, .XLS, .XLSM
PowerPoint: .PPTX, .PPSX, .PPT, .PPS, .PPTM, .POTM, .PPAM, .POTX, .PPSM
缺點
- Word、PPT 文件不能大于 10M,Excel 文件不能大于 5M-
- 加載文件較多,各種圖片、文字、樣式等,頁面臃腫,加載速度慢
- 內(nèi)網(wǎng)無法使用
-
Google Drive 查看器
- 免費,預(yù)覽效果不如 Office Web Viewer
- 接入簡單,同 Office Web Viewer,只需要把 src 改為
https://drive.google.com/viewer?embedded=true&hl=en-US&url=${encodeURIComponent(url)}即可 - 缺點:不能預(yù)覽 word 文件、excel 和 ppt 都行
支持私有化部署
-
微軟 Office Online Server
- 私有化部署,預(yù)覽效果同 Office Web Viewer
-
kkfileview
- 官網(wǎng)地址
- 支持 office 文檔的在線預(yù)覽,如 doc,docx,xls,xlsx,ppt,pptx,pdf 等,同時支持 txt,zip,rar,圖片,視頻,音頻等格式預(yù)覽
再說說付費的預(yù)覽方式
-
office365
-
XDOC 文檔預(yù)覽
- 官網(wǎng)地址,付費使用
- 預(yù)覽效果不如 Office Web Viewer,但打開速度更快
- 接入簡單,同 Office Web Viewer,只需要把 src 改為
https://view.xdocin.com/view?src=${encodeURIComponent(url)}即可 - 缺點:內(nèi)網(wǎng)無法使用
其他
其他格式文件
這些不支持的文件格式,我們只需要提示不可預(yù)覽,并提供下載的方式即可,如最開始圖片展示的那樣。
完結(jié)
以上就是本文的全部內(nèi)容,希望這篇文章對你有所幫助,歡迎點贊和收藏??,如果發(fā)現(xiàn)有什么錯誤或者更好的解決方案及建議,歡迎隨時聯(lián)系。