1.微软,谷歌在线预览:
<iframe width="100%" height="1000px" frameborder="1" scrolling="no" :src="fileSrc"></iframe>
let fileWRSrc = ref(`https://view.officeapps.live.com/op/view.aspx?src=${文件下载地址}`)
let fileGGSrc = ref(`https://docs.google.com/viewer?src=${文件下载地址}`)
注意事项:资源必须是公共可访问的。
2.后端各类型文件同一转换为PDF,再由前端实现预览
3.docx,xlsx,pdf可以使用vue-office插件统一实现在线预览
官网地址:501351981.github.io/vue-office/…
<vue-office-excel v-if="['xlsx'].includes(fileType)" :src="docx" @rendered="rendered"></vue-office-excel>
<vue-office-docx :src="docx" v-if="['docx'].includes(fileType)" @rendered="rendered"></vue-office-docx>
<vue-office-pdf :src="docx" v-if="['pdf'].includes(fileType)" @rendered="rendered" @error="errorHandler"/>
其它方式也可实现
4.doc文件暂未查到纯前端实现在线预览的方案,建议后端转PDF
5.xls文件实现在线预览(有缺陷)
官网:hondrytravis.com/x-spreadshe…
<div v-if="['xls'].includes(fileType)" style="padding: 10px 15px" ref="excelContainerRef" id="excelPreview"></div>
//转换函数 将 ArrayBuffer 转换为 Blob
function bufToBlob(buf, mimeType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"){
return new Blob([buf], { type: mimeType });
}
//处理数据
function fixData(data) {
let o = '',
l = 0,
w = 10240
for (; l < data.byteLength / w; ++l)
o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w, l * w + w)))
o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w)))
return o
}
// sheet转换为x-sheet格式
function stox(wb) {
let out = []
wb.SheetNames.forEach(name => {
let o = { name: name, rows: {}, merges: [] }
let ws = wb.Sheets[name]
let aoa = XLSX.utils.sheet_to_json(ws, { raw: false, header: 1 })
aoa.forEach((r, i) => {
let cells = {}
r.forEach((c, j) => {
cells[j] = { text: c }
})
o.rows[i] = { cells: cells }
})
// 获取表格行数,下方空20行
totalRows.value = Object.keys(o.rows).length + 20
if (totalRows.value < 100) {
totalRows.value = 100
}
// 设置合并单元格
if (ws['!merges']) {
ws['!merges'].forEach(merge => {
/** merge = {
* s: {c: 0, r: 15}
* e: {c: 15, r: 15}
* }
*/
// 修改 cell 中 merge [合并行数,合并列数]
let cell = o.rows[merge.s.r].cells[merge.s.c]
//无内容单元格处理
if (!cell) {
cell = { text: '' }
}
cell.merge = [merge.e.r - merge.s.r, merge.e.c - merge.s.c]
o.rows[merge.s.r].cells[merge.s.c] = cell
// 修改 merges
o.merges.push(XLSX.utils.encode_range(merge))
})
}
out.push(o)
})
return out
}
//Spreadsheet组件创建xls表初始化
function initExcel(sheetData) {
xs.value = new Spreadsheet创建xls表初始化('#excelPreview', {
mode: 'read',
showToolbar: false,
showGrid: true,
showContextmenu: true,
showBottomBar: true,
view: {
height: () => {
if (excelContainerRef.value) {
return excelContainerRef.value.offsetHeight
} else {
return
}
},
width: () => {
if (excelContainerRef.value) {
return excelContainerRef.value.offsetWidth
} else {
return
}
},
},
style: {
bgcolor: '#ffffff',
align: 'left',
valign: 'middle',
textwrap: false,
strike: false,
underline: false,
color: '#0b0b0b',
font: {
name: 'Helvetica',
size: 11,
bold: false,
italic: false,
},
},
row: {
len: totalRows.value,
height: 28,
},
col: {
len: 26,
width: 100,
indexWidth: 60,
minWidth: 60,
},
})
//追加数据
xs.value.loadData(sheetData[0]);
}
//根据docx(http://xxx.xxxx.xx.xls)获取该文件的arraybuffer对象
const init=()=>{
let tempType = docx.value.split('.');
fileType.value = tempType[tempType.length -1];
if(fileType.value == 'xls'){
try {
let xhr = new XMLHttpRequest()
xhr.open('get', docx.value, true)
xhr.responseType = 'arraybuffer'
xhr.onload = function (e) {
if (xhr.status === 200) {
//转换为blob对象
blobFile.value = bufToBlob(xhr.response)
xlsMap(blobFile.value)
} else if (xhr.status === 404) {
message.error("文件不存在")
} else {
message.error("读取服务器文档异常")
}
}
xhr.onerror = function () {
message.error("访问服务器异常,请检查访问链接是否正常")
}
xhr.send()
} catch (e) {
console.log(e,'116')
}finally {
}
}
}
//读取转换完成的blob对象,进行后续处理
let xlsMap=(value)=>{
let reader = new FileReader()
reader.onload = e => {
try{
let data = e.target.result
let fixedData = fixData(data)
let workbook = XLSX.read(btoa(fixedData), { type: 'base64' })
let sheetData = stox(workbook)
initExcel(sheetData)
}catch (e) {
emit('closeModule')
message.error('该文件不支持预览!')
}
}
reader.readAsArrayBuffer(value)
}
注意事项:该方法只能展示一个sheet的数据。