先上效果圖
?
?插件安裝
先說 word 文件是docx-preview插件
? ? ? ? ? excel文件是用?xlsx 插件? ??
介紹后端返回的數(shù)據(jù)
因?yàn)樵跀r截器處 做了對(duì)數(shù)據(jù)的處理 最后你調(diào)接口拿到的數(shù)據(jù)是 一個(gè)對(duì)象 里面包含:
url :?blob對(duì)象轉(zhuǎn)換的用于訪問Blob
數(shù)據(jù)的臨時(shí)鏈接。這個(gè)鏈接可以被用于在網(wǎng)頁中展示二進(jìn)制數(shù)據(jù),比如顯示圖像或者播放音視頻文件
blobs:??返回的Blob
對(duì)象,代表了從網(wǎng)絡(luò)請(qǐng)求中獲取到的二進(jìn)制數(shù)據(jù)
這上下倆部分很重要!!!!!!!!
如果返回的普通格式的話就大家直接轉(zhuǎn)化
-
const blob = new Blob([res], { type: 'application/pdf' })? //你需要的類型 轉(zhuǎn)化為blob對(duì)象
-
const url = window.URL.createObjectURL(blob)? ? ? ? ?//將對(duì)象轉(zhuǎn)化為鏈接
也就是你后面掉接口返回的數(shù)據(jù)??
給大家打印一下 我當(dāng)時(shí)在網(wǎng)上搜索這類資料的時(shí)候 就是在這一部分弄糊涂了 對(duì)數(shù)據(jù)格式不了解
?
?然后就到正式書寫了
下載引入插件 (我這是v3 引入 vue2版本 csdn官網(wǎng)上搜vue預(yù)覽文件 一大堆 大家自己搜一下)
//word文檔注釋
import { renderAsync } from 'docx-preview';
//excel注釋
import * as XLSX from "xlsx";
Word預(yù)覽? ?
不清楚result 返回內(nèi)容的往上滑 這里傳遞的是blob對(duì)象!!
<!-- 若是word文檔格式數(shù)據(jù)號(hào)展示 我這里是加自己定義的類型判斷了 fileType 大家可刪除掉 -->
<div ref="refWord" id="fileShow" v-else-if="fileType == 'docx'" style="width: 100%;height: 100%;"></div>
//js代碼處
const previewContainer = document.getElementById('fileShow');
renderAsync(result.blob, previewContainer) //渲染
Excel預(yù)覽
不清楚result 返回內(nèi)容的往上滑 這里傳遞的是blob對(duì)象!!? ??中間內(nèi)容是在拿到數(shù)據(jù)渲染的時(shí)候插件數(shù)據(jù)處理 最后將處理的數(shù)據(jù)當(dāng)參數(shù)傳遞到處理樣式的方法中
<!-- 若是excel格式數(shù)據(jù)展示 -->
<div id="fileShowTwo" style="width: 100%;height: 100%;" v-else-if="fileType == 'xlsx'">
<div class="tab">
<el-radio-group size="small" v-model="excel.sheetNameActive" @change="getSheetNameTable">
<el-radio-button v-for="(item, index) in excel.sheetNames" :key="index" :label="item"></el-radio-button>
</el-radio-group>
</div>
<div
style="margin-top: 5px;border: 1px solid #a0a0a0;overflow:auto;">
<div v-html="excel.SheetActiveTable" style="padding: 10px 15px"></div>
</div>
</div>
<div v-else-if="fileType == 'mp4'" style="width: 100%;height: 100%;">
<video :src="fileAddress" controls style="width: 100%;height: 100%;"></video>
</div>
//js代碼處
//表格預(yù)覽所需數(shù)據(jù) 定義
const data = reactive({
excel: {
// 數(shù)據(jù)
workbook: {},
// 表名稱集合
sheetNames: [],
// 激活項(xiàng)
sheetNameActive: "",
// 當(dāng)前激活表格
SheetActiveTable: ""
}
})
const { excel } = toRefs(data);
// 視頻預(yù)覽所需數(shù)據(jù)
const emptyTips = ref('暫無內(nèi)容');
//格式為excel時(shí) 方法中書寫的內(nèi)容
const reader = new FileReader(); //創(chuàng)建了一個(gè)FileReader對(duì)象,這個(gè)對(duì)象用于異步讀取文件內(nèi)容
//通過readAsArrayBuffer將blob轉(zhuǎn)換為ArrayBuffer對(duì)象
reader.readAsArrayBuffer(result.blob) // 這里的res.data是blob文件流
reader.onload = (event) => {
// 讀取ArrayBuffer數(shù)據(jù)變成Uint8Array
var data = new Uint8Array(event.target.result);
// 這里的data里面的類型和后面的type類型要對(duì)應(yīng)
var workbook = XLSX.read(data, { type: "array" });
const sheetNames = workbook.SheetNames // 工作表名稱集合
excel.value.workbook = workbook
excel.value.sheetNames = sheetNames
excel.value.sheetNameActive = sheetNames[0]
//方法
getSheetNameTable(sheetNames[0])
};
//定義的方法
const getSheetNameTable = (sheetName) => {
try {
// 獲取當(dāng)前工作表的數(shù)據(jù)
const worksheet = excel.value.workbook.Sheets[sheetName]
// 轉(zhuǎn)換為數(shù)據(jù) 1.json數(shù)據(jù)有些問題,2.如果是html那么樣式需修改
let htmlData = XLSX.utils.sheet_to_html(worksheet, { header: '', footer: '' })
htmlData = htmlData === '' ? htmlData : htmlData.replace(/<table/, '<table class="default-table" border="1px solid #ccc" cellpadding="0" cellspacing="0"')
// 第一行進(jìn)行改顏色
htmlData = htmlData === '' ? htmlData : htmlData.replace(/<tr/, '<tr style="background:#b4c9e8"')
excel.value.SheetActiveTable = htmlData
} catch (e) {
// 如果工作表沒有數(shù)據(jù)則到這里來處理
excel.value.SheetActiveTable = '<h4 style="text-align: center">' + emptyTips.value + '</h4>'
}
}
pdf 預(yù)覽??
這個(gè)需要用到iframe標(biāo)簽? 他的blob對(duì)象的type需要是"type": "application/pdf"? 大家可以看一下自己的blob對(duì)象 如果是后端返回的直接是blob格式 但是type不對(duì) 那等下我下面代碼有轉(zhuǎn)化? 如果返回的普通數(shù)據(jù) 大家自己根據(jù)上面的格式自己轉(zhuǎn)化blob對(duì)象的時(shí)候自己設(shè)置一下type?
<!-- 若是pdf數(shù)據(jù)展示 -->
<iframe :src="fileAddress" type="application/pdf" v-else-if="fileType == 'pdf'" id="pdfShow" width="100%" height="100%"></iframe>
//js代碼處
//格式為pdf時(shí)
const reader = new FileReader();
reader.readAsArrayBuffer(result.blob);
reader.onload = function () {
fileAddress.value = URL.createObjectURL(new Blob([reader.result], { "type": "application/pdf" }))
}
最后是jpg png ,mp4格式預(yù)覽
//這里就用到blob對(duì)象轉(zhuǎn)化的鏈接了 注意區(qū)分!!
if (type == 'jpg' || type == 'png' || type == 'mp4') {
fileAddress.value = result.url
}
//圖片類型展示
<img style="width: 150px;height: 150px;" :src="fileAddress" alt="" v-if="fileType == 'jpg' || fileType == 'png'">
//視頻類型展示
<div v-else-if="fileType == 'mp4'" style="width: 100%;height: 100%;">
<video :src="fileAddress" controls style="width: 100%;height: 100%;"></video>
</div>
下載文件 !!
<el-button @click="DownloadFn()"> 下載</el-button>
// 文件下載
const DownloadFn = () => {
let a = document.createElement('a')
// 下載鏈接
a.href = blobUploadValue.value //這個(gè)就是那個(gè)blob鏈接!!
// 下載文件名,如果后端沒有返回,可以自己寫a.download = '文件.pdf'
//這里是你上傳的文件名 加上他的類型 jpg,png,docx.....
a.download = fileNameValue.value + '.' + fileType.value
document.body.appendChild(a)
// 點(diǎn)擊a標(biāo)簽,進(jìn)行下載
a.click()
// 移除元素
document.body.removeChild(a)
}
最后是完整代碼?
<el-dialog v-model="dialogTabsVisible" title="附件展示" class="file-show-box" @close="closeDialog()">
<div class="file-body">
<!-- 左側(cè)附件列表 -->
<div class="file-left" >
<div class="list" :class="{'list-active' : listAct == index}" v-for="(item, index) in fileList" :key="index" @click="handleClick(item,index)">{{ item.name }}</div>
</div>
<div class="file-right">
<div class="downFile" v-if="fileType != 'pdf'">
<el-button @click="DownloadFn()"> 下載</el-button>
</div>
<!-- 若是圖片數(shù)據(jù)展示 -->
<img style="width: 150px;height: 150px;" :src="fileAddress" alt="" v-if="fileType == 'jpg' || fileType == 'png'">
<!-- 若是txt格式數(shù)據(jù)展示 -->
<iframe :src="fileAddress" frameborder="0" v-else-if="fileType == 'txt'" style="width: 90%; height: 100%;"></iframe>
<!-- 若是pdf數(shù)據(jù)展示 -->
<iframe :src="fileAddress" type="application/pdf" v-else-if="fileType == 'pdf'" id="pdfShow" width="100%" height="100%"></iframe>
<!-- 若是word文檔格式數(shù)據(jù)號(hào)展示 -->
<div ref="refWord" id="fileShow" v-else-if="fileType == 'docx'" style="width: 100%;height: 100%;"></div>
<!-- 若是excel格式數(shù)據(jù)展示 -->
<div id="fileShowTwo" style="width: 100%;height: 100%;" v-else-if="fileType == 'xlsx'">
<div class="tab">
<el-radio-group size="small" v-model="excel.sheetNameActive" @change="getSheetNameTable">
<el-radio-button v-for="(item, index) in excel.sheetNames" :key="index" :label="item"></el-radio-button>
</el-radio-group>
</div>
<div
style="margin-top: 5px;border: 1px solid #a0a0a0;overflow:auto;">
<div v-html="excel.SheetActiveTable" style="padding: 10px 15px"></div>
</div>
</div>
<div v-else-if="fileType == 'mp4'" style="width: 100%;height: 100%;">
<video :src="fileAddress" controls style="width: 100%;height: 100%;"></video>
</div>
<div v-else>
該文件暫不支持預(yù)覽,請(qǐng)下載查看
</div>
</div>
</div>
</el-dialog>
//js部分
//表格預(yù)覽所需數(shù)據(jù)
const data = reactive({
excel: {
// 數(shù)據(jù)
workbook: {},
// 表名稱集合
sheetNames: [],
// 激活項(xiàng)
sheetNameActive: "",
// 當(dāng)前激活表格
SheetActiveTable: ""
}
})
const { excel } = toRefs(data);
// 視頻預(yù)覽所需數(shù)據(jù)
const emptyTips = ref('暫無內(nèi)容');
// 下載文件
// 文件地址
const fileAddress = ref('')
// 下載流數(shù)據(jù)
const blobUploadValue = ref('')
//我這里的參數(shù)type是其他地方傳遞過來的 注意甄別
const downloadFn = (id, type) => {
let params = { fileId: id }
download(params).then(result => {
console.log(result.url, 'resolve');
console.log(result.blob, 'blob');
blobUploadValue.value = result.url
if (type == 'jpg' || type == 'png' || type == 'mp4') {
//格式為圖片 視頻時(shí)
fileAddress.value = result.url
} else if (type == 'docx') {
//格式為word時(shí)
const previewContainer = document.getElementById('fileShow');
renderAsync(result.blob, previewContainer) //渲染
} else if (type == 'xlsx') {
//格式為excel時(shí)
const reader = new FileReader();
//通過readAsArrayBuffer將blob轉(zhuǎn)換為ArrayBuffer對(duì)象
reader.readAsArrayBuffer(result.blob) // 這里的res.data是blob文件流
reader.onload = (event) => {
// 讀取ArrayBuffer數(shù)據(jù)變成Uint8Array
var data = new Uint8Array(event.target.result);
// 這里的data里面的類型和后面的type類型要對(duì)應(yīng)
var workbook = XLSX.read(data, { type: "array" });
const sheetNames = workbook.SheetNames // 工作表名稱集合
excel.value.workbook = workbook
excel.value.sheetNames = sheetNames
excel.value.sheetNameActive = sheetNames[0]
getSheetNameTable(sheetNames[0])
};
} else if (type == 'pdf') {
//格式為pdf時(shí)
const reader = new FileReader();
reader.readAsArrayBuffer(result.blob);
reader.onload = function () {
fileAddress.value = URL.createObjectURL(new Blob([reader.result], { "type": "application/pdf" }))
}
}
})
}
// 文件下載
const DownloadFn = () => {
let a = document.createElement('a')
// 下載鏈接
a.href = blobUploadValue.value
// 下載文件名,如果后端沒有返回,可以自己寫a.download = '文件.pdf'
a.download = fileNameValue.value + '.' + fileType.value
document.body.appendChild(a)
// 點(diǎn)擊a標(biāo)簽,進(jìn)行下載
a.click()
// 移除元素
document.body.removeChild(a)
}
const getSheetNameTable = (sheetName) => {
try {
// 獲取當(dāng)前工作表的數(shù)據(jù)
const worksheet = excel.value.workbook.Sheets[sheetName]
// 轉(zhuǎn)換為數(shù)據(jù) 1.json數(shù)據(jù)有些問題,2.如果是html那么樣式需修改
let htmlData = XLSX.utils.sheet_to_html(worksheet, { header: '', footer: '' })
htmlData = htmlData === '' ? htmlData : htmlData.replace(/<table/, '<table class="default-table" border="1px solid #ccc" cellpadding="0" cellspacing="0"')
// 第一行進(jìn)行改顏色
htmlData = htmlData === '' ? htmlData : htmlData.replace(/<tr/, '<tr style="background:#b4c9e8"')
excel.value.SheetActiveTable = htmlData
} catch (e) {
// 如果工作表沒有數(shù)據(jù)則到這里來處理
excel.value.SheetActiveTable = '<h4 style="text-align: center">' + emptyTips.value + '</h4>'
}
}
?這里是后端返回回來一個(gè)附件名稱列表 我渲染到左側(cè)的附件列表中 然后通過選中不同的附件 右側(cè)展示不同的文件預(yù)覽 他的文件類型我也是從這里得到的 然后我通過點(diǎn)擊不同的附件列表 執(zhí)行上面的預(yù)覽方法 獲取到不同的blob數(shù)據(jù) 然后進(jìn)行展示?
我只能給大家說一下我的邏輯 畢竟每個(gè)人代碼不一樣 不一定能直接復(fù)制? 還是希望能幫到大家
最后貼上效果圖
文章來源:http://www.zghlxwxcb.cn/news/detail-723414.html
?文章來源地址http://www.zghlxwxcb.cn/news/detail-723414.html
到了這里,關(guān)于Vue3 實(shí)現(xiàn)文件預(yù)覽 Word Excel pdf 圖片 視頻等格式 大全!!!!的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!