文件预览方案总结(docx,xls,xlsx,pdf)

69 阅读2分钟
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"/>

其它方式也可实现

在线预览.png

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的数据。