共计 2855 个字符,预计需要花费 8 分钟才能阅读完成。
一、问题形容:
在浏览器在线预览 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>
正文完