批量导入信息的时候就需要excel导入功能,可以大大提高工作效率,但是这个功能应该如何实现呢.
1.excel导入思路
1.1前端为主导
用户上传excel文件,前端将excel文件读取,然后还原成最基本的行列样式,按照后端给出的接口上传给服务器.
1.2后端为主导
前端只负责接收excel文件,将文件直接发给后端,后端处理数据.
2.前端数据处理数据
因为经常会有excel上传数据的功能,所有现在已经有成熟的解决方案,直接使用便可以.vue-admin-element中已经有了成熟的解决方案,寻找文件夹src/components/UploadExcel/index.vue,
将其复制到自己vue项目中.
<template> .... </template> <script> import XLSX from 'xlsx' export default { props: { beforeUpload: Function, // eslint-disable-line onSuccess: Function// eslint-disable-line } } </script>
这个组件使用了XLSX包,需要自行下载.命令为:npm install xlsx -S.
将其定义为组件(全局或者局部随意),在项目中引用该组件并且传入两个属性
<upload-excel-component :on-success="handleSuccess" :before-upload="beforeUpload" />
核心代码
methods: { beforeUpload(file) { const isLt1M = file.size / 1024 / 1024 < 1 if (isLt1M) { return true } this.$message({ message: 'Please do not upload files larger than 1m in size.', type: 'warning' }) return false }, handleSuccess({ results, header }) { this.tableData = results this.tableHeader = header } }
可以观察下handleSuccess的返回值 header返回值为excel中的标题, results的返回值为excel中的内容.
思路
调用接口进行excel上传的重点其实是数据的处理,我们需要按照接口的要求,把excel表格中经过插件处理好的数据处理成后端接口要求的格式
/** * results excel表格的内容 // [ {'姓名':'小张', '手机号': '13712345678'} , {.....} ] // 目标 // [ {'username':'小张','mobile': '13712345678'}, {.....} ] */ // 把一个对象数组中的每个对象的属性名,从中文改成英文 // 思路:对于原数组每个对象来说 // (1) 找出所有的中文key // (2) 得到对应的英文key // (3) 拼接一个新对象: 英文key:值 transExcel(results) { const mapInfo = { '入职日期': 'timeOfEntry', '手机号': 'mobile', '姓名': 'username', '转正日期': 'correctionTime', '工号': 'workNumber', '部门': 'departmentName', '聘用形式': 'formOfEmployment' } return results.map(zhObj => { const enObj = {} const zhKeys = Object.keys(zhObj) // ['姓名', '手机号'] zhKeys.forEach(zhKey => { const enKey = mapInfo[zhKey] enObj[enKey] = zhObj[zhKey] }) return enObj }) }
转换完成后发现问题从excel中读入的日期时间“变形”了
原因:excel内部时间编码与其他文件中的不同
解决
需要借助公式来进行还原。在utils/index.js中定义如下
// 把excel文件中的日期格式的内容转回成标准时间 // https://blog.csdn.net/qq_15054679/article/details/107712966 export function formatExcelDate(numb, format = '/') { const time = new Date((numb - 25567) * 24 * 3600000 - 5 * 60 * 1000 - 43 * 1000 - 24 * 3600000 - 8 * 3600000) time.setYear(time.getFullYear()) const year = time.getFullYear() + '' const month = time.getMonth() + 1 + '' const date = time.getDate() + '' if (format && format.length === 1) { return year + format + month + format + date } return year + (month < 10 ? '0' + month : month) + (date < 10 ? '0' + date : date) }
所以上方整理格式代码需要更新
import { formatExcelDate } from '@/utils/index.js' // 更新格式转换函数 transExcel(results) { const mapInfo = { '入职日期': 'timeOfEntry', '手机号': 'mobile', '姓名': 'username', '转正日期': 'correctionTime', '工号': 'workNumber', '部门': 'departmentName', '聘用形式': 'formOfEmployment' } return results.map(zhObj => { const enObj = {} const zhKeys = Object.keys(zhObj) // ['姓名', '手机号'] zhKeys.forEach(zhKey => { const enKey = mapInfo[zhKey] + if (enKey === 'timeOfEntry' || enKey === 'correctionTime') { // 后端需要的日期格式是标准时间 + enObj[enKey] = new Date(formatExcelDate(zhObj[zhKey])) } else { enObj[enKey] = zhObj[zhKey] } }) return enObj }) }
3.数据上传
导入API
封装doImport
async doImport(data) { try { const res = await importEmployee(data) console.log('importEmployee', res) this.$message.success('导入成功') // 页面后退 this.$router.back() } catch (err) { console.log('importEmployee', err) this.$message.error('导入失败') } }, // 1. 把数据从excel文件读入到浏览器内存 handleSuccess({ header, results }) { console.log(header, results) // 2. 按接口要求 组装数据 const data = this.transExcel(results) console.log('按接口要求 组装数据', data) // 3. 调用接口做上传 this.doImport(data) },
热门文章
- 动物医院名字有创意吗女生怎么取(动物医院有什么)
- 「11月10日」最高速度20.4M/S,2024年Clash/V2ray/Shadowrocket/SSR每天更新免费节点订阅链接
- 十大动物疫苗公司有哪些品牌的 十大动物疫苗公司有哪些品牌的
- 建议穷人养的10种猫母猫和公猫混养(母猫和公猫哪个好养知乎)
- 重庆正规免费领养宠物(重庆免费领养宠物的平台)
- 华中农业大学动物医院价目表(华中农业大学动物医院收费)
- 「12月6日」最高速度18.3M/S,2024年Shadowrocket/V2ray/Clash/SSR每天更新免费节点订阅链接
- 「12月9日」最高速度18.2M/S,2024年Shadowrocket/Clash/V2ray/SSR每天更新免费节点订阅链接
- 使用pyspark读取hive数据
- Linux网络服务之NFS共享服务