vue中Excel导入导出
vue中导入导出Excel文件是借助插件实现的,所以需要安装xlsx插件。
安装命令:npm i xlsx
导入excel数据:
1、先封装一个导入excel数据的组件,类似于下图样式,类似功能vue-element-admin中有提供,稍作改造即可。(要在组件中引入插件xlsx)
2、使用:将封装好的组件进行注册使用。使用一定要给组件提供on-succcess方法
<upload-excel :on-success='success'/> //给组件提供 :on-success='success' 事件函数。
export default {
data() {
return {
type: this.$route.query.type
}
},
//success事件方法:
methods: {
async success({ header, results }) {//两个重要的参数,headers,results,表头和数据
if (this.type === 'user') {//为提高页面的复用可以服务更多的导入功能,在本项目中用参数来判断,是否导入员工。
const userRelations = { // 建立数据之间的联系将中文转换为英文key
'入职日期': 'timeOfEntry',
'手机号': 'mobile',
'姓名': 'username',
'转正日期': 'correctionTime',
'工号': 'workNumber'
}
/*resuts是插件函数获取到的导入的excel数据,将数据整理为存入接口的格式,进行导入。*/
const arr = []
results.forEach(item => {
const userInfo = {}
Object.keys(item).forEach(key => {
//判段是否是日期格式,如果是,则进行格式化
if (userRelations[key] === 'timeOfEntry' || userRelations[key] === 'correctionTime') {
userInfo[userRelations[key]] = new Date(this.formatDate(item[key], '/'))
return
}
userInfo[userRelations[key]] = item[key]
})
arr.push(userInfo)
})
await importeEmployee(arr)
this.$message.success('导入成功')
}
this.$router.back()
// 2.用map实现,自动返回userInfo的数组对象,不用每次push进数组
// var arr = results.map(item => {
// var userInfo = {}
// Object.keys(item).forEach(key => {
// //时间的值要进行格式化
// if(userRelations[key] === 'timeOfEntry' || userRelations[key] === 'correctionTime'){
// userInfo[userRelations[key]] =new Date(this.formatDate(item[key],'/'))
// return
// }
// userInfo[userRelations[key]] = item[key]
// })
// return userInfo
// })
// console.log('map',arr);
// //获取到要导入的数据后,调用接口将数据导入
// await importeEmployee(arr)
// this.$message.success('导入成功')
// }
// this.$router.back()
// },
},
// 转化excel的日期格式的方法,因为excel中有日期格式的时候,实际转化的为一个数字,所以需要一个方法进行转化。
formatDate(numb, format) {
const time = new Date((numb - 1) * 24 * 3600000 + 1)
time.setYear(time.getFullYear() - 70)
const year = time.getFullYear() + ''
const month = time.getMonth() + 1 + ''
const date = time.getDate() - 1 + ''
if (format && format.length === 1) {
return year + format + month + format + date
}
return year + (month < 10 ? '0' + month : month) + (date < 10 ? '0' + date : date)
}
}
}
导出excel:
Excel 的导入导出都是依赖于js-xlsx来实现的。在 js-xlsx的基础上又封装了Export2Excel.js来方便导出数据,Export2Excel.js还依赖于file-saver,script-loader。以及Export2Zip.js(导出为压缩包)。
3、安装导出excel的依赖和按需加载
npm i xlsx file-saver -S
npm i script-loader -S -D
由于xlsx体积很大,导出功能不是一个常用的功能,所以使用懒加载更好。
(1)excel导出参数介绍
- header:导出数据的表头,类型为Array,可选值为‘/’,默认值[]。
- data:导出的具体数据,类型为Array,可选值为‘/’,默认值[ [ ] ],二维数组。
- filename:导出文件名,类型为String,可选值为‘/’,默认值excel-list。
- autoWidth:单元格是否要自适应,类型为Boolean,默认为true.
- bookType:导出文件类型,类型为String,可选值有:xlsx,csv,txt等,默认为xlsx.
// 导出员工数据,把表头和数据进行相应的对应,导出数据的时间也需要处理格式
exportData() {
const headers = {
'姓名': 'username',
'手机号': 'mobile',
'入职日期': 'timeOfEntry',
'聘用形式': 'formOfEmployment',
'转正日期': 'correctionTime',
'工号': 'workNumber',
'部门': 'departmentName'
}
// js-xlsx的体积较大,且导入导出功能不常用,故用懒加载
import('@/vendor/Export2Excel').then(async excel => {
const { rows } = await getEmployeeList({ page: 1, size: this.page.total })
console.log('rows', rows)
const data = this.formatJson(headers, rows)
// excel.export_json_to_excel({
// header: Object.keys(headers),
// data,
// filename: '员工信息表',
// autoWidth: true
// })
const multiHeader = [['姓名', '主要信息', '', '', '', '', '部门']]
const merges = ['A1:A2', 'B1:F1', 'G1:G2']
excel.export_json_to_excel({ // 复杂表头导出数据示例
header: Object.keys(headers),
data,
filename: '员工信息表',
autoWidth: true,
multiHeader,
merges
})
})
},
// 格式化要导出的数据
// headers:['uername','moobile',....]
// rows原数据形式为:{username: "管理员",mobile: "13800000002", …}
// rows:[['黎明','1376543322'...]] 将rows中每个对象的值拿出来并将字段对应表头
formatJson(headers, rows) {
return rows.map(item => {
// Object.keys就是表头的数据
return Object.keys(headers).map(key => {
if (headers[key] === 'timeOfEntry' || headers[key] === 'correctionTime') {
return formatDate(item[headers[key]])
} else if (headers[key] === 'formOfEmployment') {
var en = EmployeeEnum.hireType.find(obj => obj.id === +item[headers[key]]) // 转换字符串为数字,才能比较得到
return en ? en.value : '未知'
}
console.log(item[headers[key]])
return item[headers[key]]
})
})
}
3、复杂表头的导出
- multiHeader:复杂表头的部分,类型为数组,默认值为二维数组,里面的一个元素是一行表头.
- merges:需要合并的部分,类型为数组,默认值为[ ].
合并示例:
在实现复杂表头的时候,还是要定义标准表头,且multiHeader中的一行表头中的字段个数应是和标准表头中个数相等的,若想跨列,多余的空间需要定义成空字符串。
const header = ['姓名', '手机号', '入职日期', '聘用形式', '转正日期', '工号', '部门']
const multiHeader = [['姓名', '主要信息', '', '', '', '', '部门']]
需要合并的效果,需设定merges选项。示例如下。
const merges = ['A1:A2', 'B1:F1', 'G1:G2']
// 导出excel,将各参数配置好,就可以导出想要结构的表了
import('@/vendor/Export2Excel').then(async excel => {
// excel是引入文件的导出对象
// 导出 header从哪里来
// data从哪里来
// 现在没有一个接口获取所有的数据
// 获取员工的接口 页码 每页条数 100 1 10000
const { rows } = await getEmployeeList({ page: 1, size: this.page.total })
const data = this.formatJson(headers, rows) // 返回的data就是 要导出的结构
const multiHeader = [['姓名', '主要信息', '', '', '', '', '部门']]
const merges = ['A1:A2', 'B1:F1', 'G1:G2']
excel.export_json_to_excel({
header: Object.keys(headers),
data,
filename: '员工资料表',
multiHeader, // 复杂表头
merges // 合并选项
})