4

一、问题描述:

在浏览器在线预览xls,需要引入2个模块,所以本人整理上传npm。开发时只需要引入vue-excelview即可
vue-excelview

二、参考

此npm模块开发用到相关资料
  1. js-xlsx ---来自SheetJS
  2. SheetJS
  3. SpreadJS 中文官方
  4. canvas-datagrid ---xls绘制canvas

三、npm模块源代码(已封装的Vue组件):

<template>
  <div>
      <div ref="excel-dom"></div>
      <el-button-group class="m-t-md">
        <el-button
          v-for="(item, index) in sheetNames"
          :key="index"
          :type="sheetActive===item?'primary':''"
          @click="onTabWorkbook(index)">
          {{item}}
        </el-button>
      </el-button-group>
  </div>
</template>
<script>
import XLSX from 'xlsx' // 预览
import canvasDatagrid from 'canvas-datagrid'
export default {
  name: 'excel',
  props: {
    datas: null
  },
  data () {
    return {
      excelGridData: [],
      excelGridDom: null,
      workbook: null,
      sheets: [],
      sheetNames: [],
      sheetActive: ''
    }
  },
  methods: {
    onTabWorkbook (index) {
      var datas = this.sheets[this.sheetNames[index]] // 这里读取第index张sheet
      var csv = XLSX.utils.sheet_to_csv(datas)
      // console.log(csv)
      this.excelGridData = []
      this.$refs['excel-dom'].innerHTML = ''
      var rows = csv.split('\n')
      rows.pop() // 最后一行(空数组)没用的
      rows.forEach((row, idx) => {
        var columns = row.split(',')
        let obj = {}
        this.excelGridData.push(obj)
        for (var i = 0; i < columns.length; i++) {
          let key = String.fromCharCode(65 + i)
          this.excelGridData[idx][key] = columns[i]
        }
      })
      this.excelGridDom = canvasDatagrid({
        editable: false // 禁止单元编辑
      })
      this.excelGridDom.data = this.excelGridData
      console.log(this.excelGridData)
      this.$refs['excel-dom'].appendChild(this.excelGridDom)
      this.sheetActive = this.sheetNames[index]
    },
    readWorkbook (workbook) {
      console.log(workbook)
      this.workbook = workbook
      this.sheetNames = workbook.SheetNames
      this.sheets = workbook.Sheets
      this.onTabWorkbook(0)
    }
  },
  watch: {
    datas () {
      this.excelGridData = []
      this.excelGridDom = null
      let data = new Uint8Array(this.datas)
      let workbook = XLSX.read(data, { type: 'array' })
      this.readWorkbook(workbook)
    }
  }
}
</script>

四、XLS与PDF导出代码示例

逻辑

  1. 接口请求 设置 responseType: 'arraybuffer'
  2. 从接口获取data直接prop注入上面组件即可
<template>
  <div>
    <el-table :data="tableData"
              class="table-default">
      <el-table-column
        prop="id"
        label="操作"
        align="center"
        width="300"
        >
        <template slot-scope="scope">
          <el-button
            size="mini"
            type="primary"
            @click="onSee(scope.row)">查看</el-button>
        </template>
      </el-table-column>
    </el-table>
    <el-dialog
      title="预览"
      :visible.sync="seeVisible"
      width="800px"
      fullscreen
      center>
      <div style="padding: 10px; overflow: auto;" v-loading="excelLoading">
        <excel-view :datas="excelData"/>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button type="primary" @click="seeVisible = false">关  闭</el-button>
      </span>
    </el-dialog>

  </div>
</template>

<script>
import excelview from 'vue-excelview'
export default {
  name: 'query',
  components: {
    'excel-view': excelview
  },
  data () {
    return {
      seeVisible: false,
      excelData: null,
      excelLoading: false,
      downloadDisabled: false
    }
  },
  created () {
    this.getTable()
  },
  mounted () {
  },
  methods: {
    getTable () {
      this.tableData = []
      this.axios.get('', { params: {
      } })
        .then((res) => {
        })
    },
    onSee (obj) {
      if (obj.suffix === '.pdf') {
        window.open(obj.url)
      } else {
        this.excelLoading = true
        this.seeVisible = true
        this.axios.get(obj.url, {
          responseType: 'arraybuffer'
        })
          .then((res) => {
            this.excelData = res.data
            this.excelLoading = false
          })
      }
    }
  }
}
</script>

LazyYou2016
6 声望0 粉丝