EXCEL导入导出并展示数据详解
前言
前端程序员在做管理系统时,经常会需要做“excel表格的导入与导出”这一功能模块。
excel表格导入
下载xlsx第三方包
npm i xlsx
为了方便维护和复用,在做这种可能多次使用的功能模块时,使用ele-ment组件新建一个公共的导入页面组件,全局注册并正确挂载至路由,导入的模块代码引用:https://github.com/PanJiaChen/vue-element-admin/blob/master/src/components/UploadExcel/index.vue
范例:
<template>
<div class="upload-excel">
<div class="btn-upload">
<el-button :loading="loading" size="mini" type="primary" @click="handleUpload">
点击上传
</el-button>
</div>
<input ref="excel-upload-input" class="excel-upload-input" type="file" accept=".xlsx, .xls" @change="handleClick">
<div class="drop" @drop="handleDrop" @dragover="handleDragover" @dragenter="handleDragover">
<i class="el-icon-upload" />
<span>将文件拖到此处</span>
</div>
</div>
</template>
分析excel导入代码,封装接口
范例:
export function importEmployee(data) {
return request({
url: '/sys/user/batch',
method: 'post',
data
})
}
实现excel导入:获取导入的excel数据,导入excel接口
范例:
async success({ header, results }) {
// 如果是导入员工
const userRelations = {
'入职日期': 'timeOfEntry',
'手机号': 'mobile',
'姓名': 'username',
'转正日期': 'correctionTime',
'工号': 'workNumber'
}
const arr = []
results.forEach(item => {
const userInfo = {}
Object.keys(item).forEach(key => {
userInfo[userRelations[key]] = item[key]
})
arr.push(userInfo)
})
await importEmployee(arr) // 调用导入接口
this.$router.back()
}
当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表格中的类似于“姓名,年龄”等这种数据等大都是中文的,而后端值认识英文,所以我们需要进行逻辑判断将中文转化为英文
范例:
var newArr = 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], '/'))// 只有这样才能将时间以正确的格式存入数据库
} else {
userInfo[userRelations[key]] = item[key]
}
})
return userInfo
})
excel表格导出
Excel 的导入导出都是依赖于js-xlsx来实现的。
在 js-xlsx
的基础上又封装了Export2Excel.js来方便导出数据。
由于 Export2Excel
不仅依赖js-xlsx
还依赖file-saver
和script-loader
。
所以你先需要安装如下命令:
npm install xlsx file-saver -S
npm install script-loader -S -D
由于js-xlsx
体积还是很大的,导出功能也不是一个非常常用的功能,所以使用的时候建议使用懒加载。使用方法如下:
范例:
import('@/vendor/Export2Excel').then(excel => {
excel.export_json_to_excel({
header: tHeader, //表头 必填
data, //具体数据 必填
filename: 'excel-list', //非必填
autoWidth: true, //非必填
bookType: 'xlsx' //非必填
})
})
excel导出最重要的一件事就是:把表头和数据进行相应的对应
范例:
const headers = {
'手机号': 'mobile',
'姓名': 'username',
'入职日期': 'timeOfEntry',
'聘用形式': 'formOfEmployment',
'转正日期': 'correctionTime',
'工号': 'workNumber',
'部门': 'departmentName'
}
导出表格的时候需要将获取的数组转化为二维数组,并且要处理时间格式
范例:
formatJson(headers, rows) {
// 首先遍历数组
// [{ username: '张三'},{},{}] => [[’张三'],[],[]]
return rows.map(item => {
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 : '未知'
}
return item[headers[key]]
}) // => ["张三", "13811","2018","1", "2018", "10002"]
})
扩展:复杂表头的导出(vue-element-admin同样支持该类操作 )
vue-element-admin 提供的导出方法中有 multiHeader和merges 的参数(只要配置这两个属性,就可以导出复杂表头的excel了 ):
multiHeader---复杂表头的部分;merges---需要合并的部分;
范例:
const multiHeader = [['姓名', '主要信息', '', '', '', '', '部门']]
const merges = ['A1:A2', 'B1:F1', 'G1:G2']
注意:merges的顺序是没关系的 ;multiHeader中的一行表头中的字段的个数需要和真正的列数相等,假设想要跨列,多余的空间需要定义成空字符串,它主要对应的是标准的表头。