各种文件实现在线预览

5,444 阅读1分钟

前言

最近开发接到一个需要在线预览各种文件,没有文件服务器,后端直接返回文件流,前端处理进行在线预览的需求。文件类型分别有图片、pdf、docx、excel,作为一个菜鸟来记录一下啦,有不对的地方希望大家可以指导指导。

一、  图片预览

// 处理从接口返回的文件流
let that = this
// 读取文件
let reader = new FileReader()
// 文件读取成功完成时
reader.onload = function( event ) {
  try {
     that imgSrc = event.target.result
  }catch(error){
    let jsonData = JSON.parse(reader.result)
    that.$message.error(JSONData.msg)     
  }
  reader.readAsDataUrl(res.data)
}

二、 docx预览

使用docx-preview插件进行预览docx文件,这个插件不能预览doc文件。使用npm安装: npm install docx-preview --save

<template>
  <div>
    <div ref="word"></div>
  </div>
</template>
<script>
let docx = require('docx-preview')
export default {
  data(){
    return {
      fileId: ''
    }
  },
  methods: {
    // 请求接口下载文件
    downloadFile(){
       request({
          method: 'get',
          params: {fileId: this.fileId},
          url: url, // 下载文件接口地址
          // 文件流
          responseType: 'blob',
       }).then(res => {
       // 渲染在界面上
       docx.renderAsync(res.data, this.$refs.word).then(res => {})
    })
  }
 }
}
</script>

三、pdf预览

pdf预览一开始使用的是vue-pdf预览,后面系统从windows服务器更换到linux服务器后vue-pdf打包上线后预览报错,本地是没有问题的,试过更换插件版本不行,重新安装插件发现服务器上项目下的node_modules文件里的vue-pdf文件不一样。最后改成使用iframe进行在线预览。目前还不知道什么什么原因,若有知道的jym可以帮忙解答一下。上线之后报错预览报错截图:

WechatIMG14.jpeg

1. vue-pdf预览,npm安装:npm install vue-pdf --save

<template>
  <div class="pdf-content">
    <div  v-if="src">
     <!-- 循环显示pdf内容 -->
       <pdf v-for="i in numsPage" :key="i" :src="pdfSrc
" :page="i"></pdf>
    </div>
   
  </div>
</template>
<script>
// 引入vue-pdf组件
import pdf from 'vue-pdf'
import { preview } from '@/utils/download'
export default {
 // 注册pdf组件
  components: { pdf },
  data() {
    return {
      src'',
      numsPage0,
      fileId''
    }
  },
 computed: {
 // 解决PDF中文字体丢失的问题
   pdfSrc(){
     let src = pdf.createLoadingTask({
       url: this.src,
       // 引入字体
       cMapUrl: 'https://cdn.jsdelivr.net/npm/pdfjs-dist@2.5.207/cmaps/',
       cMapPacked: true
     })
     return src
   }
 }
  created() {
    this.fileId = this.$route.query.fileId
    preview(this.fileId).then(res => {
      this.src = res
       console.log('文件'this.src);
     // 获取pdf页码
      this.getPageNums()
    }).catch(() => {})
  },
  methods: {
    getPageNums() {
      let loadingTask = pdf.createLoadingTask(this.src)
      loadingTask.promise.then(pdf => {
        this.numsPage = pdf.numPages
      }).catch(() => {})
    }
  }
}
</script>
<style lang="scss" scoped>
.pdf-content {
  width100%;
  height100%;
}
</style>

download.js

export function preview(fileId, filename, responseType) {
    return new Promise((resolve, reject) => {
        request({
            method'get',
            params: {
                fileId,
            },
            url'/file/download',
            responseType: responseType ? responseType : 'blob',
            timeout0
        }).then(res => {
            let url = getUrl(res, filename) || ''
             // 返回Url
            resolve(url)
        }).catch((error) => {
            reject(error)
        });
    })
}

function getUrl(res, fileName) {
    let blob = new Blob([res.data], {type'application/pdf;charset-UTF-8'})
    let url = URL.createObjectURL(blob)
    return url
}

2. iframe预览

<template>
   <div>
     <iframe :scr="pdf文件下载地址"></iframe>
   </div>
</template>

四、excel预览

使用xlsx插件进行excel预览,npm安装:nmp insatll xlsx --save

<template>
  <div>
    <el-tabs type="card" v-model="tableIndex">
      // 遍历工作表
      <el-tab-pane v-for="(item, index) in tableNums" :key="index" :label="item" :name="index">
        <div v-html="xlsxData"></div>
      </el-tab-pane>
    </el-tabs>
  </div>
</template>
<Script>
import request from './request'
import xlsx from 'xlsx'
export default {
  data(){
    return {
      xlsxData: '',
      fileId: '',
      fileName: '',
      tableNums: [],
      tableIndex: 0,
      excelData: null,
    }
  },
  watch: {
    // 动态渲染工作表
    tableIndex(val) {
      this.renderExcel()
    }
  },
  created() {
    this.fileId = this.$route.query.fileId
    this.fileName = this.$route.query.fileName
    this.downloadFile()
  },
  methods: {
    downloadFile(){
      request({
              method'get',
              params: {
                  fileIdthis.fileId,
              },
              url: url,
              // arraybuffer
              responseType'arraybuffer',
              timeout0
            }).then(res => {
              this.excelData = res.data
              this.renderExcel()
            }).catch((error) => {})
    },
    // 渲染
    renderExcel(){
      if(this.excelData) {
        // 解析数据
        let workbook = xlsx.read(new Unit8Array(this.excelData), { type:'array' })
        this.tableNums = workbook.sheetNames
        // workbook.sheetNames存这每个工作表的名字
        let worksheet = workboot.Sheets[workboot.SheetNames[this.tableIndex]]
        // 渲染
        this.xlsxData = xlsx.utils.sheet_to_html(worksheet)
      }
    }
  }

}
</script>