记录一下今日vue导入excel
先看一下实现效果
使用的是vue + element-ui 中<el-upload>组件
<!-- 方法名称:fileOnChange -->
<el-upload
ref="upload"
action=""
class="upload-demo"
accept=".xls,.xlsx"
:show-file-list="false"
:auto-upload="false"
:multiple="false"
:on-change="fileOnChange">
<el-button size="small" type="primary" icon="el-icon-plus">Excel导入</el-button>
</el-upload>
methods 中方法是一个异步的方法,因为FileReader中的onload() 的方法就是一个异步,我这边是创建了一个excel的工具类
// 第一个参数 sbbh: 类的名称;第二个参数对应了excel 表格中列的名称
// 这样就可以随着列的增加 而增加数据
const data = { sbbh: '设备编号', cs: '测试', cjdm: '厂家代码', cyr: '持有人' }
async fileOnChange(file, fileList) {
const files = { 0: file.raw }
if (files.length <= 0) { // 如果没有文件名
return false
} else if (!/\.(xls|xlsx)$/.test(files[0].name.toLowerCase())) {
this.$message.error('上传格式不正确,请上传xls或者xlsx格式')
return false
}
// 获取excel 中的数据 异步方法使用await将数据添加到data中
const data = { sbbh: '设备编号', cs: '测试', cjdm: '厂家代码', cyr: '持有人' }
// 这边我的方法是一个全局 若只是单页面调用使用 import 调用
await this.$ExcelUtil.importExcel(files, data).then(result => {
const list = []
for (const items of result) {
const item = items.sbbh
const objectBh = { sbbh: item, dwmc: items.cs, dwdm: item.substring(1, 3), cjdm: items.cjdm, cyr: items.cyr }
list.push(objectBh)
}
this.exceldata = list
})
console.log(this.exceldata)
}
然后创建工具类 excelUtil.js,类中调用
import FileSaver from 'file-saver'
import * as XLSX from 'xlsx'
若没有安装 请先 npm
npm install xlsx --save
npm install file-saver --save
export default {
// 导出Excel表格
exportExcel(name, tableName, size = 15) {
// .table要导出的是哪一个表格
const table = document.querySelector(tableName).cloneNode(true)
// 因为element-ui的表格的fixed属性导致多出一个table,会下载重复内容,这里删除掉
table.removeChild(table.querySelector('.el-table__fixed-right'))
table.removeChild(table.querySelector('.el-table__fixed'))
// name表示生成excel的文件名 tableName表示表格的id
const sel = XLSX.utils.table_to_book(table, { raw: true })
const list = []
for (let i = 0; i < size; i++) {
list.push({ wpx: 150 })
}
sel['Sheets']['Sheet1']['!cols'] = list
sel['Sheets']['Sheet1']['!rows'] = [{ hpx: 20 }]
const selIn = XLSX.write(sel, { bookType: 'xlsx', bookSST: true, type: 'array' })
const now = new Date()
const filename = now.getFullYear() + '' + (now.getMonth() + 1) + '' + now.getDate() + name
try {
FileSaver.saveAs(new Blob([selIn], { type: 'application/octet-stream' }), filename)
} catch (e) {
if (typeof console !== 'undefined') console.log(e, selIn)
}
return selIn
},
// 导入Execl表格
importExcel(files, map) {
return new Promise(function(resolve, reject) {
const fileReader = new FileReader()
fileReader.readAsBinaryString(files[0])
let newArr = null
fileReader.onload = (ev) => {
const data = ev.target.result
const workbook = XLSX.read(data, {
type: 'binary'
})
const excel_1 = workbook.SheetNames[0] // 取第一张表
const form_1 = XLSX.utils.sheet_to_json(workbook.Sheets[excel_1]) // 生成第一张表的json表格内容
newArr = form_1.map(item => {
// 在不改变原有基础上修改其他
const object = (JSON.parse(JSON.stringify(map)))
for (const key in map) {
const id = key
const name = item[map[id]]
object[id] = name
}
return object
/* return {
sbbh: item['设备编号']
} */
})
// 将工具类中的数据 传输到外部 onload为异步方法所以使用promise
resolve(newArr)
}
})
}
}
我们这边用到的是第二个方法