| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> JavaScript知识库 -> Excel表格导入导出功能实现 -> 正文阅读 |
|
[JavaScript知识库]Excel表格导入导出功能实现 |
## 01.员工管理-Excel导入功能介绍 ### 目标在前面员工的添加是一个一个进行的,如果一次性添加多个员工信息,这时候就会很繁琐 因此需要我们开发一个批量导入的功能,将用户的信息存储到 excel 中然后进行批量导入 ### 讲解#### 实现方式 1 前端主导(工作大量在前端) 1. ?上传 excel 文件,把 excel 文件的内容读出来,还原成最基本的行列结构 2. ?将数据按照后端接口要求格式化,并使用 AJAX 将数据发送到服务器 ? ? <img src="./images/007-员工管理/010-前端导入导出.png" style="zoom:75%; border: 1px solid #ccc" /> #### ?实现方式 2 后端主导(工作大量在后端) 1. 前端只需要负责将 excel 文件上传 ? ?<img src="./images/007-员工管理/011-前端导入导出.png" style="zoom:75%; border: 1px solid #ccc" /> ###拓展 小结1. excel文件上传有几种方式? ? 在前端, 把excel文件获取到, 用第三方包把文件数据读出, 转换后发给后台 ? 在后端, 前端把excel文件, 用FormData对象直接发给后台, 让后台读取/保存 2. 图片上传也有几种方式呢? 前端把图片转成base64字符串发给后台, 后台保存图片的base64字符串数据 ? 前端把图片文件, 放到formData表单对象中, 直接发给后台, 后台接收文件数据流, 把文件保存到后台 ## 02.员工管理-Excel导入方案 ### **目标** 分析 vue-element-admin 中的导入方案 ? <img src="images/012-导入导出.png" style="zoom:75%; border: 1px solid #ccc" /> ### 讲解 #### ?分析 1. ?打开我们前面下载的项目, 通过路由路径定位到源码位置进行分析 2. ?导入相关的代码文件有两个: ? ?- 使用组件:`src/views/excel/upload-excel.vue` ? ?- 定义组件:`src/components/UploadExcel/index.vue` #### 上传组件实现分析 1. ?源代码 `src/components/UploadExcel/index.vue`
? ? ? ?<script> ? ?import XLSX from 'xlsx' ? ?? ? ?
2. 这个组件引入了 xlsx 包, 因此我们需要提前安装 ? ?- Excel 的导入导出都是依赖于[js-xlsx](https://github.com/SheetJS/js-xlsx)来实现的, ? ?- 在 `js-xlsx`的基础上又封装了[Export2Excel.js](https://github.com/PanJiaChen/vue-element-admin/blob/master/src/vendor/Export2Excel.js)来方便导出数据 ? ?- 由于 `Export2Excel`不仅依赖`js-xlsx`还依赖`file-saver`和`script-loader` ? ? ?- file-saver 用户在客户端保存文件的 ? ? ?- script-loader 用于在前端执行一次js脚本文件的
3. ?需要给它提供两个 props: ? ?- beforeUpload:上传之前的函数,可以在上传之前做一些自己的特殊判断,如判断文件的大小是否大于 1 兆? ? ?- onSuccess: 成功调用之后的函数,它会返回表格的表头和内容。 #### ?导入组件使用分析 ?源代码:`src/views/excel/upload-excel.vue`
### 小结 1. 分析别的项目, 页面文件去哪里找, 具体标签在哪里找? ? ?<details> ? ?<summary>答案</summary> ? ?<ul> ? ?<li>页面组件看路由, 从路由里找到, 标签可以看关键字或者类名去代码全局搜索/页面搜索</li> ? ?</ul> ? ?</details> 2. 文件转数据是依赖哪些包实现的? ? ?<details> ? ?<summary>答案</summary> ? ?<ul> ? ?<li>xlsx包和它需要依赖的file-saver和script-loader包</li> ? ?</ul> ? ?</details>
## 03.员工管理-Excel导入组件准备 ### 目标 拷贝 vue-element-admin 中提供的 excel 导入功能组件到自己项目中 ### 讲解 #### 分析 1. ?安装包 2. ?拷贝核心组件 #### 实现 1. 安装必要的插件 ? ?> -S和-D (默认就是--save不写即可, -S -D(是--save-dev) : 具体区别可以看这里: https://www.bilibili.com/video/BV15M4y1u78F?spm_id_from=333.999.0.0 ? ?```bash ? ?npm install xlsx file-saver -S ? ?npm install script-loader -S -D ? ?``` 2. 引入UploadExcel组件并注册为全局 ? ?- 将 vue-element-admin 提供的组件复制到我们自己的项目 `src/components/UploadExcel`下 ? ?- 在 `src\components\index.js` 中将该组件注册成全局组件 ? ? ?![image-20211225141306579](images/image-20211225141306579.png) 3. 在index.js将它注册成全局组件 ? ?```js ? ?/** ? ? * 进行全局组件的挂载 ? ? */ ? ? ? ?import PageTools from './PageTools/index.vue' ? ?import UploadExcel from './UploadExcel/index.vue' ? ? ? ?export default { ? ? ?install(Vue) { ? ? ? ?Vue.component('PageTools', PageTools) ? ? ? ?Vue.component('UploadExcel', UploadExcel) ? ? ?} ? ?} ? ? ? ? ? ?```
4. 这里要格外注意, 最新版的xlsx包, 导出的方式改变了, 所以我们要修改UploadExcel组件代码 ? ?```js ? ?// import XLSX from 'xlsx' ? ?// 上面改成下面这样, 按需引入所有然后形成一个对象保存到XLSX变量上 ? ?import * as XLSX from 'xlsx' ? ?``` ? ? ### 小结 1. 我们为什么在components/index.js - 在这里导入和注册 ? ?<details> ? ?<summary>答案</summary> ? ?<ul> ? ?<li>统一注册和导出, 然后在main.js用Vue.use注册全局组件</li> ? ?</ul> ? ?</details>
## ?04.员工管理-Excel导入页面准备 ### 目标 1. ?根据业务要求配置一个独立的 excel导入功能 路由 2. ?创建 excel导入功能 对应的组件,在这个单独的页面中实现员工导入功能 ### 讲解 #### 分析 1. ?配置路由 2. ?建立对应的页面,然后在这个页面中引入 UploadExcel 组件实现导入功能
#### 实现 1. ? 建立公共导入的页面路由 ? ?- 在 `src` 目录下创建 `excel` 文件夹 ? ?- 创建 excel导入功能 组件,`src\views\excel\index.vue` ? ? 2. ?创建页面的结构,同时补充导入成功后的回调函数 ? ?```vue ? ?<template> ? ? ?<!-- Excel 导入功能组件 --> ? ? ?<upload-excel :on-success="handleSuccess" /> ? ?</template> ? ? ? ?<script> ? ?export default { ? ? ?name: 'Excel', ? ? ?methods: { ? ? ? ?// 导入成功以后的回调函数 ? ? ? ?handleSuccess({ results, header }) {} ? ? ?} ? ?} ? ?</script> ? ? ? ?<style lang="scss" scoped></style> ? ? ? ?``` ? ? 3. ?配置路由 ? ?这个路由不需要根据权限控制,直接定义为静态路由即可。在**`src/router/index.js`**下的静态路由表末尾404前添加一个路由 ? ?```js ? ?{ ? ? ?path: '/excel', ? ? ?component: Layout, ? ? ?hidden: true, // 不显示到左侧菜单 ? ? ?children: [{ ? ? ? ?path: '', ? ? ? ?component: () => import('@/views/excel') ? ? ?}] ? ?} ? ?``` ? ? 4. ? 在`views/employees/index.vue` 在<导入 Excel> 按钮绑定点击事件,点击后跳转到 Excel 导入页面 ? ?```vue ? ?<el-button type="danger" size="small" @click="uploadExcelBtnFn">导入excel</el-button> ? ?``` ? ? 5. ?事件方法中, 切换路由页面到/excel, 查看前面准备的上传表格页 ? ?```js ? ?// 导入excel按钮->点击事件 ? ? ? ?uploadExcelBtnFn() { ? ? ? ? ?this.$router.push('/excel') ? ? ? ?} ? ?``` ? ? ? ? ? ? 6. 测试导入效果 ? ?- excel 导入插件本质:把 excel 经过分析转换成js能够识别的常规数据,拿到数据我们可以进行任何操作 ? ?```js ? ?methods: { ? ? ?// 导入成功以后的回调函数 ? ? ?handleSuccess({ results, header }) { ? ? ? ?console.log(results) ? ? ? ?console.log(header) ? ? ?} ? ?} ? ?``` ? ? ### 小结 1. 我们是如何实现表格导入读取成数组的功能? ? ?<details> ? ?<summary>答案</summary> ? ?<ul> ? ?<li>使用xlsx的这个第三方的包, 然后使用模板项目里准备的组件文件使用即可</li> ? ?</ul> ? ?</details>
## 05.员工管理-Excel导入内容格式化 ### 目标 数据格式转换:将 excel 解析好的数据经过处理后,转成可以传给接口调用的数据 ? ? <img src="./images/007-员工管理/013-导入导出.png" style="zoom:75%; border: 1px solid #ccc" /> ### 讲解 #### 分析 1. ?调用接口进行excel上传的**重点其实是数据的处理**, 2. ?按照接口的要求,把 excel 表格中经过插件处理好的数据处理成后端接口要求的格式
#### 实现 1. ? 在`views/excel/index.vue`导入时间处理方法 ? ?```js ? ?import { formatExcelDate } from '@/utils' ? ?``` ? ? ? ? 2. 按接口要求,处理excel导入的数据。处理内容包含: ? ?- 字段中文转英文。excel中读入的是`姓名`,而后端需要的是`username` ? ?- 日期处理。从excel中读入的时间是一个 number 值,而后端需要的是标准日期 ? ?```js ? ?methods: { ? ? ?// 将表格中的数据进行格式化 ? ? ?transExcel(results) { ? ? ? ?const userRelations = { ? ? ? ? ?'入职日期': 'timeOfEntry', ? ? ? ? ?'手机号': 'mobile', ? ? ? ? ?'姓名': 'username', ? ? ? ? ?'转正日期': 'correctionTime', ? ? ? ? ?'工号': 'workNumber', ? ? ? ? ?'部门': 'departmentName', ? ? ? ? ?'聘用形式': 'formOfEmployment' ? ? ? ?} ? ? ? ? ? ?return results.map(item => { ? ? ? ? ?const obj = {} ? ? ? ? ? ? ?// 1. 取出这个对象所有的属性名: ['姓名', ‘手机号’] ? ? ? ? ?// 2. 遍历这个数组,通过 中文名去 userRelations 找对应英文名, 保存值 ? ? ? ? ?const contentKeys = Object.keys(item) ? ? ? ? ?contentKeys.forEach(key => { ? ? ? ? ? ?// 找到对应的英文名 ? ? ? ? ? ?const transKey = userRelations[key] ? ? ? ? ? ?// 如果格式化的是时间,需要进行转换 ? ? ? ? ? ?if (transKey === 'timeOfEntry' || transKey === 'correctionTime') { ? ? ? ? ? ? ? ?// 表格的天数->转成日期对象 ? ? ? ? ? ? ? ?const transDate = new Date(formatExcelDate(item[key])) ? ? ? ? ? ? ? ?// 再把日期对象转成->'年-月-日'保存到对象属性里给后台 ? ? ? ? ? ? ? ?obj[transKey] = parseTime(transDate, '{yyyy}-{mm}-{dd}') ? ? ? ? ? ? ?} else { ? ? ? ? ? ? ? ?obj[transKey] = item[key] ? ? ? ? ? ? ?} ? ? ? ? ?}) ? ? ? ? ? ? ?return obj ? ? ? ?}) ? ? ?}, ? ? ? ? ?// 导入成功以后的回调函数 ? ? ?handleSuccess({ results, header }) { ? ? ? ?const arr = this.transExcel(results) ? ? ? ?console.log('转换之后的格式是', arr) ? ? ?} ? ?} ? ?``` ? ? 3. 上面用到的日期处理函数在 `utils/index.js` 中定义如下 ? ?```js ? ?// 把excel文件中的日期格式的内容转回成标准时间 ? ?export function formatExcelDate(numb, format = '/') { ? ? ?const time = new Date((numb - 25567) * 24 * 3600000 - 5 * 60 * 1000 - 43 * 1000 - 24 * 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) ? ?} ? ?``` ? ?==为何要减少5分43秒, 因为1901年之前, 北京时间是东8时5分43秒不是真正意义上的东8区== ? ?具体解释: ? ?```js ? ?// 1. xlsx包, 读取表格里日期的时候, 会按照1900年01月01日进行天数的计算, 返回天数数字 ? ?// 43534天, 是1900年(当时的UTC时间算)->到2019年过的天数 ? ?// 注意1: 在1900年的时候, 时间是UTC+8:5:43 (43534天里, 照0时0分0秒, 多了5分43秒) ? ?// 可以查询每个年份, 时区: https://www.timeanddate.com/time/zone/china/shanghai ? ?// 注意2: 获取表格的天数, 1月0日也算了一天(43534天里, 多了1天) ? ? ? ?// 2. js中, new Date是从1970年开始计算日期对象 ? ?// 所以你传入给new Date的表格时间, 要把1970年之前的天数减掉, 就是上面说的1900-1970天数和多出来的5分43秒 ? ?``` ? ?图解 ? ?![image-20220321115020158](images/image-20220321115020158.png) ### 小结 1. 表格读出中文key对象, 如何转换英文key的对象的? ? ?<details> ? ?<summary>答案</summary> ? ?<ul> ? ?<li>准备一个中文key和英文key映射关系的对象, 然后遍历数据里所有中文key拿出来, 换取英文key</li> ? ?<li>再准备一个新的对象, 组织英文key和value值</li> ? ?</ul> ? ?</details>
## 06.员工管理-Excel导入接口调用 ### 目标 完成按钮跳转,导入完成(接口调用)之后,再跳回到原来的页面 ### 讲解 #### 分析 1. ?准备好excel 导入的接口 2. ? 在页面上,点击了导入之后,做跳转,跳到上传页面; #### 实现 1. ?在 `src/api/employee` 封装好导入的接口 ? ?```js ? ?/** ? ? * @description: 导入excel ? ? * @param {*} data ? ? * @return {*} ? ? */ ? ?export function importEmployeeAPI(data) { ? ? ?return request({ ? ? ? ?url: '/sys/user/batch', ? ? ? ?method: 'post', ? ? ? ?data ? ? ?}) ? ?} ? ?``` ? ? 2. 在`views/excel/index.vue`表格上传页面中导入封装的方法 ? ?```js ? ?import { importEmployeeAPI } from '@/api' ? ?``` ? ? 3. ?调用封装的方法,实现 Excel 导入功能 ? ?```js ? ?// 导入成功以后的回调函数 ? ?async handleSuccess({ results, header }) { ? ? ? ?const arr = this.transExcel(results) ? ? ? ?const res = await importEmployeeAPI(arr).catch(err => err) ? ? ? ?if (!res.success) return this.$message.error(res.message) ? ? ? ?this.$router.back() ? ? ? ?this.$message.success('操作成功') ? ?} ? ?``` ### 小结 1. $router.back作用是? ? ?<details> ? ?<summary>答案</summary> ? ?<ul> ? ?<li>跳转回到上一个路由历史的记录</li> ? ?</ul> ? ?</details>
## 07.员工管理-Excel导出功能介绍 ### 目标 在表格中查询到了我们需要的数据,希望用他们生成excel文件,保存在本地。
### 讲解 #### 实现方式 1 取回数据,解析数据,保存为 excel 文件,工作大量在前端 ? ? ? ?<img src="./images/007-员工管理/014-导入导出.png" style="zoom:75%; border: 1px solid #ccc" />
#### 实现方式 2 前端调用接口,获取 ?excel 文件,下载即可,工作大量在后端 ? ? ? ?<img src="./images/007-员工管理/015-导入导出.png" style="zoom:75%; border: 1px solid #ccc" />
### 小结 1. 在前端, 导出Excel形成一个文件, 如何做? ? ?<details> ? ?<summary>答案</summary> ? ?<ul> ? ?<li>先请求后台接口, 拿到列表所有数据</li> ? ?<li>然后借助xlsx包的方法, 把数据转成excel文件并下载</li> ? ?</ul> ? ?</details>
## 08.员工管理-Excel导出方案 ### 目标 先去vue-admin中去学习导出功能的用法,并归纳总结把它用到本项目中的步骤 > 前置工作:这个功能在我们课程一开始学习的vue-element-admin中有现成的功能参考,我们也在`项目资源`里提供了现成的插件包,大家先把它复制到自己项目的`src目录`下 ### 讲解 #### 分析 学习使用现成的excel导出组件,通过路由路径定位到源码位置 <img src="./images/007-员工管理/016-导入导出.png" style="zoom:75%; border: 1px solid #ccc" />
**熟悉案例代码** 网上示例地址:https://gitee.com/mirrors/vue-element-admin/blob/master/src/views/excel/export-excel.vue ```js import('@/vendor/Export2Excel').then(excel => { ? ? const tHeader = ['Id', 'Title', 'Author', 'Readings', 'Date'] ? ? const filterVal = ['id', 'title', 'author', 'pageviews', 'display_time'] ? ? const list = this.list ? ? const data = this.formatJson(filterVal, list) ? ? excel.export_json_to_excel({ ? ? ? header: tHeader, ? ? ? data, ? ? ? filename: this.filename, ? ? ? autoWidth: this.autoWidth, ? ? ? bookType: this.bookType ? ? }) ? ? this.downloadLoading = false ?}) ``` #### 具体说明 1. ?插件包位于`src/vendor/export2Excel`中,采用的是按需引入的方式 ? ?什么时候正式要使用导出功能了,插件才会被正式引入到应用里 ? ?``` ? ?import('@/vendor/Export2Excel').then(excel => {}) ? ?``` 2. `Export2Excel`依赖的包有`js-xlsx`、`file-saver`和`script-loader` ? ?也就是说,在项目跑起来之前要安装依赖 ? ?```bash ? ?npm install file-saver script-loader --save ? ?```
### 小结 1. 导出表格如何实现? ? ?<details> ? ?<summary>答案</summary> ? ?<ul> ? ?<li>使用xlsx包里,准备好的方法</li> ? ?</ul> ? ?</details>
## 09_员工管理-Excel导出基础实现 ### 目标 实现员工的基础导出功能实现 ### 讲解 #### 分析 1. ?把vue-element-admin 中的导出功能,迁移本项目 2. ?使用静态数据实现基础的导出功能(先不使用从接口获取的数据)
#### 实现 1. 将 `vue-element-admin` 中的 `src/vendor/export2Excel` 复制到本项目中,直接使用 ? ?格外注意, 新版的xlsx导入方式改变了, 所以要改变代码 ? ?```js ? ?import * as XLSX from 'xlsx' ? ?``` ? ? 2. 在项目中安装依赖 ? ?```bash ? ?npm install file-saver script-loader --save ? ?``` ? ? 3. 给导出按钮添加点击事件 ? ?```vue ? ?<el-button type="success" size="small" @click="downloadExcel">导出excel</el-button> ? ?``` ? ?```js ? ?// 导出excel按钮->点击事件 ? ?downloadExcel() { ? ? ? ?import('@/vendor/Export2Excel').then(excel => { ? ? ? ? ? ?// excel表示导入的模块对象 ? ? ? ? ? ?excel.export_json_to_excel({ ? ? ? ? ? ? ? ?header: ['姓名', '工资'], // 表头 必填 ? ? ? ? ? ? ? ?data: [ ? ? ? ? ? ? ? ? ? ?['刘备', 100], ? ? ? ? ? ? ? ? ? ?['关羽', 500] ? ? ? ? ? ? ? ?], // 具体数据 必填 ? ? ? ? ? ? ? ?filename: 'excel-list', // 文件名称 ? ? ? ? ? ? ? ?autoWidth: true, // 宽度是否自适应 ? ? ? ? ? ? ? ?bookType: 'xlsx' // 生成的文件类型 ? ? ? ? ? ?}) ? ? ? ?}) ? ?} ? ?``` ? ? 以上代码表示: 1. ?当我们正式点击`导出`按钮之后,才去加载 vendor 文件夹中的Export2Excel模块 2. ?import 方法执行完毕返回的是一个 promise 对象,在then方法中我们可以拿到使用的模块对象 3. ?重点关注 data 的配置部分,我们发现它需要一个严格的二维数组 **Excel导出参数说明** | 参数 ? ? ?| 说明 ? ? ? ? ? ? ? ? ? | 类型 ? ?| 可选值 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | 默认值 ? ? | | --------- | ---------------------- | ------- | ------------------------------------------------------------ | ---------- | | header ? ?| 导出数据的表头 ? ? ? ? | Array ? | / ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| [] ? ? ? ? | | data ? ? ?| 导出的具体数据 ? ? ? ? | Array ? | / ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| **[[]]** ? | | filename ?| 导出文件名 ? ? ? ? ? ? | String ?| / ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| excel-list | | autoWidth | 单元格是否要自适应宽度 | Boolean | true / false ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? | true ? ? ? | | bookType ?| 导出文件类型 ? ? ? ? ? | String ?| xlsx, csv, txt, [more](https://github.com/SheetJS/js-xlsx#supported-output-formats) | xlsx ? ? ? | ### 小结 1. 导出时的二个数组, 怎么来呢? ? ?需要我们按照目标表格需要的字段和数据, 用js代码进行排列
## 10.员工管理-Excel导出尝试实现 ### 目标 使用业务 真实数据实现导出功能 ### 讲解 #### 分析 1. 从后台重新获取数据(这样才能确保是最新的) 2. 对数据的**格式进行转换**(后端给的数据字段名都是英文的),以用来做导出 <img src="./images/007-员工管理/017-导入导出.png" style="zoom:75%; border: 1px solid #ccc" /> 核心在于把后端接口返回的数据转成 Export2Excel 这个插件需要的格式 #### 准备表头header数据 因为接口中返回的数据中的key是英文,而我们期望导出的表头是中文,所以提前准备中文和英文的映射关系 ```js const map = { ? 'id': '编号', ? 'password': '密码', ? 'mobile': '手机号', ? 'username': '姓名', ? 'timeOfEntry': '入职日期', ? 'formOfEmployment': '聘用形式', ? 'correctionTime': '转正日期', ? 'workNumber': '工号', ? 'departmentName': '部门', ? 'staffPhoto': '头像地址' } ``` #### 目标表格data数据 > 具体的表格数据我们需要通过接口从后端获取回来,难点在于如何把后端返回的数据处理成`Export2Excel`插件需求的二维数组格式。 下面是一个示例: ```json const dataArr = [ ?["13600000001", "吕勇锐", "1992-08-04", "正式", "2020-01-01", "0001", "总裁办"] ?["13600000002", "袁永安", "1993-08-04", "正式", "2020-01-01", "0002", "总裁办"] ] ```
#### 补充一个用来处理数据的函数 ```js transData(rows) { ? // 写代码 ? const map = { ? ? 'id': '编号', ? ? 'password': '密码', ? ? 'mobile': '手机号', ? ? 'username': '姓名', ? ? 'timeOfEntry': '入职日期', ? ? 'formOfEmployment': '聘用形式', ? ? 'correctionTime': '转正日期', ? ? 'workNumber': '工号', ? ? 'departmentName': '部门', ? ? 'staffPhoto': '头像地址' ? } ? const headerKeys = Object.keys(rows[0]) ? const header = headerKeys.map(item => { ? ? return map[item] ? }) ? const data = rows.map(obj => { ? ? return Object.values(obj) ? }) ? return { header, data } } ``` #### 最终的代码 ```js methods: { ? ? transData(rows) { ? ? ? ? // 写代码 ? ? ? ? const map = { ? ? ? ? ? ? 'id': '编号', ? ? ? ? ? ? 'password': '密码', ? ? ? ? ? ? 'mobile': '手机号', ? ? ? ? ? ? 'username': '姓名', ? ? ? ? ? ? 'timeOfEntry': '入职日期', ? ? ? ? ? ? 'formOfEmployment': '聘用形式', ? ? ? ? ? ? 'correctionTime': '转正日期', ? ? ? ? ? ? 'workNumber': '工号', ? ? ? ? ? ? 'departmentName': '部门', ? ? ? ? ? ? 'staffPhoto': '头像地址' ? ? ? ? } ? ? ? ? const headerKeys = Object.keys(rows[0]) ? ? ? ? const header = headerKeys.map(item => { ? ? ? ? ? ? return map[item] ? ? ? ? }) ? ? ? ? const data = rows.map(obj => { ? ? ? ? ? ? return Object.values(obj) ? ? ? ? }) ? ? ? ? return { header, data } ? ? } ? ? // 导出 Excel ? ? async downloadExcel() { ? ? ? ? const res = await getEmployeeList() ? ? ? ? const excelObj = this.transData(res.data.rows) ? ? ? ? import('@/vendor/Export2Excel').then(excel => { ? ? ? ? ? ? // excel表示导入的模块对象 ? ? ? ? ? ? excel.export_json_to_excel({ ? ? ? ? ? ? ? ? header: excelObj.header, // 表头 必填 ? ? ? ? ? ? ? ? data: excelObj.data, // 具体数据 必填 ? ? ? ? ? ? ? ? filename: '员工列表', // 文件名称 ? ? ? ? ? ? ? ? autoWidth: true, // 宽度是否自适应 ? ? ? ? ? ? ? ? bookType: 'xlsx' // 生成的文件类型 ? ? ? ? ? ? }) ? ? ? ? }) ? ? },
} ### 小结 1. 数据如果不是自己想要的结构要怎么办? ?先看好自己手上的数据, 和目标数据之间的关系, 找规律 用js代码, 把对应的数据结构, 熟练使用对象的方法和数组方法进行转换使用 2. 下载的只有当前页面的数据, 如果我想要全部的数据怎么办? ? ?<details> ? ?<summary>答案</summary> ? ?<ul> ? ?<li>请求第一次, 把总数据请求回来, 然后单独发送参数, 把1页所有数据拿回来导出成表格即可</li> ? ?</ul> ? ?</details>
## 11.员工管理-Excel导出顺序对应 ### 目标 刚才我们的数据对应不了页面, 而且数据顺序也有点错乱, 尝试解决 ### 讲解 1. 分析原因, Object.values拿到的值数组顺序不稳定, 所以我们决定自己来实现一个个取值和按顺序组织数组 ? ?```js ? ?transData(rows) { ? ? ? ? ?// // 写代码 ? ? ? ? ?// const map = { ? ? ? ? ?// ? 'id': '编号', ? ? ? ? ?// ? 'password': '密码', ? ? ? ? ?// ? 'mobile': '手机号', ? ? ? ? ?// ? 'username': '姓名', ? ? ? ? ?// ? 'timeOfEntry': '入职日期', ? ? ? ? ?// ? 'formOfEmployment': '聘用形式', ? ? ? ? ?// ? 'correctionTime': '转正日期', ? ? ? ? ?// ? 'workNumber': '工号', ? ? ? ? ?// ? 'departmentName': '部门', ? ? ? ? ?// ? 'staffPhoto': '头像地址' ? ? ? ? ?// } ? ? ? ? ? ? ?// const headerKeys = Object.keys(rows[0]) ? ? ? ? ?// const header = headerKeys.map(item => { ? ? ? ? ?// ? return map[item] ? ? ? ? ?// }) ? ? ? ? ? ? ?// const data = rows.map(obj => { ? ? ? ? ?// ? return Object.values(obj) ? ? ? ? ?// }) ? ? ? ? ? ? ?// return { header, data } ? ? ? ? ? ? ?// 考虑顺序 (页面上列保持一致顺序) ? ? ? ? ?// 4.0 准备一个列表头中文数组 (8个) ? ? ? ? ?const headerArr = ['序号', '姓名', '头像', '手机号', '工号', '聘用形式', '部门', '入职时间'] ? ? ? ? ?// 4.1 数据key的映射关系(思路: 遍历上边数组里按照顺序, 取出中文的名字, 但是对应数组值的数组, 要从英文key对象中取出value值, 我要用中文key换到英文key然后去取到值) ? ? ? ? ?const myObj = { ? ? ? ? ? ?// 序号可以等遍历的时候直接用索引值, 而不是来自于英文对象里 ? ? ? ? ? ?'姓名': 'username', ? ? ? ? ? ?'头像': 'staffPhoto', ? ? ? ? ? ?'手机号': 'mobile', ? ? ? ? ? ?'工号': 'workNumber', ? ? ? ? ? ?'聘用形式': 'formOfEmployment', ? ? ? ? ? ?'部门': 'departmentName', ? ? ? ? ? ?'入职时间': 'timeOfEntry' ? ? ? ? ?} ? ? ? ? ?// 4.2 按照顺序, 形成值的数组 (明确目标->想要数据结构->读代码(每个变量意思)读2-3遍->仿写3-5遍) ? ? ? ? ?const resultArr = rows.map((item, index) => { ? ? ? ? ? ?const valueArr = [] // 值小数组 ? ? ? ? ? ?headerArr.forEach(zhKey => { ? ? ? ? ? ? ?if (zhKey === '序号') { ? ? ? ? ? ? ? ?valueArr.push(index + 1) ? ? ? ? ? ? ?} else { ? ? ? ? ? ? ? ?const enKey = myObj[zhKey] ? ? ? ? ? ? ? ?valueArr.push(item[enKey]) ? ? ? ? ? ? ?} ? ? ? ? ? ?}) ? ? ? ? ? ?return valueArr ? ? ? ? ?}) ? ? ? ? ? ? ?return { header: headerArr, data: resultArr } ? ? ? ?}, ? ? ? ? ? ?// 导出 Excel ? ? ? ?async downloadExcel() { ? ? ? ? ?const res = await getEmployeeListAPI() ? ? ? ? ?const res2 = await getEmployeeListAPI({ ? ? ? ? ? ?page: 1, ? ? ? ? ? ?size: res.data.total ? ? ? ? ?}) ? ? ? ? ?const excelObj = this.transData(res2.data.rows) ? ? ? ? ?import('@/vendor/Export2Excel').then(excel => { ? ? ? ? ?// excel表示导入的模块对象 ? ? ? ? ? ?excel.export_json_to_excel({ ? ? ? ? ? ? ?header: excelObj.header, // 表头 必填 ? ? ? ? ? ? ?data: excelObj.data, // 具体数据 必填 ? ? ? ? ? ? ?filename: '员工列表', // 文件名称 ? ? ? ? ? ? ?autoWidth: true, // 宽度是否自适应 ? ? ? ? ? ? ?bookType: 'xlsx' // 生成的文件类型 ? ? ? ? ? ?}) ? ? ? ? ?}) ? ? ? ?} ### 小结 1. 值数组是如何和列标题头数组对应的? 首先, 遍历数组是按照顺序的, 拿到中文的key换成英文的key, 再去对象取值后, 按顺序push到值的数组中
|
|
JavaScript知识库 最新文章 |
ES6的相关知识点 |
react 函数式组件 & react其他一些总结 |
Vue基础超详细 |
前端JS也可以连点成线(Vue中运用 AntVG6) |
Vue事件处理的基本使用 |
Vue后台项目的记录 (一) |
前后端分离vue跨域,devServer配置proxy代理 |
TypeScript |
初识vuex |
vue项目安装包指令收集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/23 9:38:57- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |