前端实现文件预览功能(png/jpg/jpeg/gif/txt/xls/xlsx/docx)

背景:前段时间项目需求,要实现文件的预览功能,我也是耗费了一些时间去研究了下,已实现,并发布上线!目前主流格式的文件都可实现预览,主要有 图片文件(png/jpg/jpeg/gif)、文本文档和office文件(excel/word/pdf)。废话不多说,直接开始:下面的代码我本来是写在一起的,但是为了分开展示,逻辑部分分开写了,具体写入到哪里都有标注,需要那块的,自行合并即可。

前提:点击“预览”按钮,调取接口,后端返回数据为文件流

公共代码部分:

1 let type = ''
2 const that = this
3 axios({
4   method: 'GET',
5   url: '', // 你的接口地址
6   responseType: 'blob'
7 }).then(res => {
8   // 拿到数据后的逻辑处理部分!!!
9 })

 一、预览 xls/xlsx 文件 

1. 效果:

 2. 代码实现:

1 <div>
2   <table ref="xtable" class="xtable"></table>
3 </div>
1 import XLSX from 'xlsx' // $ npm install xlsx

 写入:公共代码的红色字体部分:

 1 let reader = new FileReader()
 2 reader.onload = e => {
 3   //预处理
 4   var binary = ''
 5   var buf = new Uint8Array(e.target.result)
 6   var length = buf.byteLength
 7   for (var i = 0; i < length; i++) {
 8     binary += String.fromCharCode(buf[i])
 9   }
10   //读取excel
11   const wb = XLSX.read(binary, { type: 'binary', cellDates: true })
12   //抓取第一个sheet
13   let wsname = wb.SheetNames[0]
14   let ws = wb.Sheets[wsname]
15   var csv = XLSX.utils.sheet_to_csv(ws)
16   that.$refs.xtable.innerHTML = that.csv2table(csv)
17 }
18 reader.readAsArrayBuffer(res.data)
 1 csv2table(csv) {
 2   var html = '<table>'
 3   var rows = csv.split('\n')
 4   rows.pop() // 最后一行没用的
 5   rows.forEach(function(row, idx) {
 6     var columns = row.split(',')
 7     html += '<tr>'
 8     columns.forEach(function(column) {
 9       html +=
10         `<td style="border: 1px solid #eee; padding: 10px">` +
11         column +
12         '</td>'
13     })
14     html += '</tr>'
15   })
16   html += '</table>'
17   return html
18 }

二、预览  png / gif / jpg /jpeg 文件(图片文件)

1. 效果:

2. 代码实现:

 1 <div class="demo-image__preview">
 2   <el-image
 3     style="
 4       padding: 0 50px;
 5       background-size: contain;
 6       left: 50%;
 7       transform: translate(-50%);
 8     "
 9     :src="imgSrc"
10     :preview-src-list="[imgSrc]"
11     :z-index="999999999"
12   >
13   </el-image>
14 </div>

写入:公共代码的红色字体部分:

1 let data = window.URL.createObjectURL(res.data)
2 this.imgSrc = data

三、预览  pdf 文件

1. 效果:

2. 代码实现:

1 <div class="pdf">
2   <iframe
3     :src="pdfSrc"
4     frameborder="0"
5     style="width: 1160px; height: 460px"
6   ></iframe>
7 </div>

写入:公共代码的红色字体部分:

1 type = 'application/pdf'
2 let blob = new window.Blob([res.data], { type: type })
3 let requestUrl = window.URL.createObjectURL(blob)
4 this.pdfSrc = requestUrl

四、预览  txt 文件

1. 效果:

 2. 代码实现:

1 <el-input v-model="txtPre" type="textarea" :rows="20"></el-input>

写入:公共代码的红色字体部分:

1 let reader = new FileReader()
2 reader.onload = function(e) {
3   that.txtPre = e.target.result
4 }
5 reader.readAsText(res.data)

五、预览 docx 文件

 1. 效果:

2. 代码实现:

1 <div
2   style="width: 100%; overflow-x: auto; overflow-y: hidden"
3   v-html="docContent"
4 ></div>
1 import mammoth from 'mammoth' // 只能转换.docx文档,转换过程中复杂样式被忽略。(居中、首行缩进等)$npm install mammoth

写入:公共代码的红色字体部分:

 1 let reader = new FileReader()
 2 reader.readAsArrayBuffer(res.data)
 3 reader.onload = e => {
 4   var buf = new Uint8Array(e.target.result)
 5   mammoth
 6     .convertToHtml({ arrayBuffer: buf })
 7     .then(result => {
 8       if (result) {
 9         that.docContent = result.value
10       }
11     })
12     .catch()
13     .done()
14 }

目前 doc 文件的预览暂时还没整理出来,上面的几种文件格式都可实现预览,亲测有效,赶紧码起来!!!

当然实现预览的方法也不止这些,我也没有 一 一做过研究对比,只是列出我所使用的,只要最后能实现都是可以的 ~

整理不易,如果你觉得有用的话就点赞关注一下吧 ~

posted @ 2021-09-07 15:41  拾忆-iiii  阅读(2392)  评论(0编辑  收藏  举报