一、问题形容:
在浏览器在线预览xls,须要引入2个模块,所以自己整顿上传npm。开发时只须要引入vue-excelview即可
vue-excelview
二、参考
此npm模块开发用到相干材料
- js-xlsx ---来自SheetJS
- SheetJS
- SpreadJS 中文官网
- 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导出代码示例
逻辑
- 接口申请 设置 responseType: 'arraybuffer'
- 从接口获取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>