文件预览是我们经常遇到的业务场景,不同类型的文件有不同的处理方式。GitHub Demo地址: github.com/beat-the-bu…
浏览器支持的文件类型
这一类文件预览,都是去使用我们熟悉的HTML标签。
图片
使用<img>
标签:
<img src="img.png" />
音频
使用<audio>
标签:
<audio controls>
<source src="audio.mp3" type="audio/mpeg">
您的浏览器不支持 audio 元素。
</audio>
视频
使用<video>
标签:
<video controls loop>
<source src="movie.mp4" type="video/mp4">
您的浏览器不支持 video 标签。
</video>
使用<embed>
标签,<embed>
标签定义外部资源的容器,例如网页、图片、媒体播放器或插件应用程序。
<embed src="PDF.pdf">
也可以使用第三方插件vue-pdf-embed
。
以上浏览器可以识别的文件类型,均可以用window.open
的方式打开一个窗口直接预览,但是要注意PDF类型的文件,需要看一下浏览器关于PDF的设置是预览模式还是下载模式:
office系列的文件
我们知道,office系列的文件只有office软件才能打开,浏览器是不认识这一类文件的。要想预览office文件,我们一般有两种方式:
方法一:使用office官方自带的在线预览功能。在下面的链接后面拼接上office文件的地址:view.officeapps.live.com/op/view.asp…
方法二:后端处理,将office文件转成PDF文件,在这里不做详细讨论。
markdown文件
这一类文件本质上是文本,该文本可以转换成HTML。我们需要两个插件,一个是marked
,用于将markdown的语法转成HTML,另一个是highlight.js
,用于给markdown中的代码块加一些高亮的展示。
import { onMounted, nextTick, ref } from 'vue'
import { marked } from 'marked'
import hljs from 'highlight.js'
import 'highlight.js/styles/github.css';
let str = '# Marked in the browser\n\nRendered by **marked**.\n ```js\nvar a = 1;\n```'
const html = ref('')
onMounted(async () => {
let trans = marked.parse(str);
html.value = trans
await nextTick()
hljs.highlightAll();
})
效果如下:
zip文件
对于压缩文件,我们需要将文件解析出来,得到一个子文件的列表,然后将子文件列表展示出来。我们需要借助jszip
。
我们需要一个文件输入框、读取文件按钮、按钮点击之后展示压缩包的内容。
<input type="file" id="fileId" />
<Button @click="readZip">读取压缩文件</Button>
<Table :dataSource="dataList" :columns="columns" :pagination="false" :rowKey="(record, index) => index">
<template #fileContent="{ record, text }">
<div v-if="text.indexOf('http') < 0">{{ text }}</div>
<Button type="link" v-else @click="downloadByUrl({
url: text,
fileName: record.fileName.split('/')[1]
})">下载</Button>
</template>
</Table>
准备一个zip文件,里面有md、pdf、jpeg文件:
后面就是对jszip的使用。
关键方法一:jszip.loadAsync
,传入File类型,返回一个带压缩包内容的Promise:
jszip.loadAsync(currFile).then(res => {
console.log(res) // 目录以及里面的内容
})
关键方法二:file
方法和async
方法
file方法可以根据压缩包内的文件名读取文件,async可以传读取的方式:
res.file(fileItem.name)?.async('blob').then(data => {
dataList.value.push({
fileName: fileItem.name,
fileType: '图片',
fileContent: URL.createObjectURL(data),
})
})
完整代码如下:
function readZip() {
var file = document.getElementById('fileId')
if (file && file.files && file.files[0]) {
dataList.value = []
let currFile = file.files[0]
let jszip = new JSZip()
jszip.loadAsync(currFile).then(res => {
for (let key in res.files) {
let fileItem = res.files[key]
if (!fileItem.dir && fileItem.name.indexOf('__MACOSX') < 0) {
// 这里就能拿到
if ((/\.(png|jpg|jpeg|webp|gif)$/).test(fileItem.name)) {
// png图片
res.file(fileItem.name)?.async('blob').then(data => {
dataList.value.push({
fileName: fileItem.name,
fileType: '图片',
fileContent: URL.createObjectURL(data),
})
})
}
if ((/\.md$/).test(fileItem.name)) {
// png图片
res.file(fileItem.name)?.async('string').then(data => {
dataList.value.push({
fileName: fileItem.name,
fileType: 'markdown',
fileContent: data,
})
})
}
if ((/\.pdf$/).test(fileItem.name)) {
// png图片
res.file(fileItem.name)?.async('blob').then(data => {
dataList.value.push({
fileName: fileItem.name,
fileType: 'pdf',
fileContent: URL.createObjectURL(data),
})
})
}
}
}
})
} else {
console.log('文件不存在,请先上传压缩文件')
}
}
最终效果:
GitHub Demo地址: github.com/beat-the-bu…