当前位置:   article > 正文

Excel 前端主导方案导出下载_exportaction showexportdialog getexportdata

exportaction showexportdialog getexportdata
  1. <template>
  2. <div class="employees-container">
  3. <div class="app-container">
  4. <page-tools>
  5. <template #left>
  6. <div class="tips">
  7. <i class="el-icon-info" />
  8. <span>本月: 社保在缴 公积金在缴</span>
  9. </div>
  10. </template>
  11. <template #right>
  12. <el-button type="warning" size="small" @click="$router.push('/import')">excel导入</el-button>
  13. <el-button type="danger" size="small" @click="exportExcel">excel导出</el-button>
  14. <el-button type="primary" size="small" @click="addEmployee">新增员工</el-button>
  15. </template>
  16. </page-tools>
  17. <el-card style="margin-top: 10px;">
  18. <el-table border :data="list">
  19. <el-table-column label="序号" type="index" />
  20. <el-table-column label="姓名" prop="username" />
  21. <el-table-column label="工号" prop="workNumber" />
  22. <!--
  23. prop指定一个字段名称 此时原样输出 后端返回什么就显示什么
  24. 如果你想做定制化 拿到源数据利用作用域插槽 再做优化
  25. -->
  26. <el-table-column label="聘用形式">
  27. <template #default="{row}">
  28. <!--
  29. 差值表达式 内部支持三元运算 函数调用等等
  30. 如果格式化的情况只有两种 -> 三元表达式
  31. 如果格式化的情况很多 -> 格式化函数
  32. 方案:格式化的函数 {{fn()}} 渲染出来的是什么?渲染的函数的返回值
  33. 思路:把拿到的源数据作为实参传入格式化函数 在函数内部做一些格式化 最终return出去
  34. -->
  35. {{ formatEmployee(row.formOfEmployment) }}
  36. </template>
  37. </el-table-column>
  38. <el-table-column label="部门" prop="departmentName" />
  39. <el-table-column label="入职时间" width="180" prop="timeOfEntry">
  40. <template #default="{row}">
  41. {{ formatTime(row.timeOfEntry) }}
  42. </template>
  43. </el-table-column>
  44. <el-table-column label="操作" fixed="right" width="200">
  45. <template #default="{row}">
  46. <el-button type="text" size="small" @click="goDetail(row.id)">查看</el-button>
  47. <el-button type="text" size="small">分配角色</el-button>
  48. <el-button type="text" size="small">删除</el-button>
  49. </template>
  50. </el-table-column>
  51. </el-table>
  52. <!--
  53. 分页器组件
  54. layout: 定制分页器的结构 上一页 下一页 页数 跳转 切换条数
  55. 分页逻辑: 总条数 / 每页条数 = 页数 总条数一定要传 每页条数默认10条
  56. 点击分页切换table数据显示: 点击时拿到当前的页数 -> 使用这个页数获取新的数据重新交给list
  57. 传给后端的size可以和分页组件要求的每页条数不一致吗?
  58. 这里必须一致 否则后端的分页逻辑和前端的分页对不上!!!
  59. 如果后端一共20条数据 传给后端的size=10 后端的数据可以分俩页出来
  60. 如果前端size=5 前端可以分4页出来 请求3页4页哪里还有数据呀??
  61. -->
  62. <el-pagination
  63. layout="prev, pager, next"
  64. :total="total"
  65. :page-size="params.size"
  66. @current-change="pageChange"
  67. />
  68. </el-card>
  69. </div>
  70. <add-employee-vue
  71. :dialog-visible="dialogVisible"
  72. @close-dialog="closeDialog"
  73. />
  74. </div>
  75. </template>
  76. <script>
  77. /**
  78. 新增
  79. 1. 抽离一个子组件 把弹框的部分放到子组件内部
  80. 2. 把子组件在index.vue中引入 形成一个父子嵌套的关系
  81. 3. 通过父传子的方式 实现弹框的打开
  82. 4. 通过子传父的方式 实现弹框的关闭
  83. */
  84. import { fetchEmployeeList } from '@/api/employee'
  85. import dayjs from 'dayjs'
  86. import addEmployeeVue from './components/add-employee.vue'
  87. import { getExportData } from '@/utils/excel'
  88. export default {
  89. name: 'EmployeeIndex',
  90. components: {
  91. addEmployeeVue
  92. },
  93. data() {
  94. return {
  95. list: [],
  96. params: {
  97. page: 1,
  98. size: 10
  99. },
  100. total: 0,
  101. dialogVisible: false
  102. }
  103. },
  104. mounted() {
  105. this.getList()
  106. },
  107. methods: {
  108. async getList() {
  109. const res = await fetchEmployeeList(this.params)
  110. this.list = res.rows
  111. this.total = res.total
  112. },
  113. formatEmployee(value) {
  114. // 把value按照需求格式化
  115. // 1 -> 正式 2 -> 非正式 4->其他
  116. // 前端枚举优化: 先把所有的对应关系通过对象定义出来 + 对象的取值 -> 策略模式 优化多分支语句的
  117. const MAP = {
  118. 1: '正式',
  119. 2: '非正式',
  120. 4: '其它'
  121. }
  122. return MAP[value]
  123. // if (value === '1') {
  124. // return '正式'
  125. // } else if (value === '2') {
  126. // return '非正式'
  127. // } else {
  128. // return '其他'
  129. // }
  130. },
  131. formatTime(value) {
  132. return dayjs(value).format('YYYY-MM-DD')
  133. },
  134. pageChange(page) {
  135. this.params.page = page
  136. this.getList()
  137. },
  138. addEmployee() {
  139. this.dialogVisible = true
  140. },
  141. closeDialog() {
  142. this.dialogVisible = false
  143. },
  144. // 导出
  145. exportExcel() {
  146. // import是一个动态导入模块的语法
  147. // 只有用到它的时候才会动态加载 进行打包不会出现在打出的包里 不会占用体积
  148. import('@/vendor/Export2Excel').then(async excel => {
  149. // 一个表格最重要俩部分 1.表头 theader 2.表体 tbody
  150. // 1. 先请求当前页的最新的数据
  151. const res = await fetchEmployeeList(this.params) // res -> 对象数组
  152. // 2. 把后端最新数据格式化成插件需要的格式
  153. const headerRelation = {
  154. '姓名': 'username',
  155. '手机号': 'mobile',
  156. '入职日期': 'timeOfEntry',
  157. '工号': 'workNumber',
  158. '聘用形式': 'formOfEmployment',
  159. '部门': 'departmentName'
  160. }
  161. const { data } = getExportData(res.rows, headerRelation)
  162. // 3. 配置到对应的位置即可
  163. excel.export_json_to_excel({
  164. header: Object.keys(headerRelation), // 配置表头的位置 -> 数组格式
  165. data: data, // 配置表体的位置 -> 二维数组
  166. filename: 'excel-employee', // 文件名称
  167. autoWidth: true, // 单元格宽度是否自动撑开
  168. bookType: 'xlsx' // excle文件类型
  169. })
  170. })
  171. },
  172. goDetail(id) {
  173. // query + path
  174. this.$router.push({
  175. path: '/detail',
  176. query: {
  177. id
  178. }
  179. })
  180. }
  181. }
  182. }
  183. </script>

其中的数据格式化代码

  1. /**
  2. * @description: 获取导出时的表头数据和表格数据
  3. * @param {*} { sourceData:后端返回的源数据,header:表格头中因为对应关系}
  4. * @return {*}
  5. */
  6. // 处理函数中对key判断如果发生当前它是聘用形式 通过枚举做一下处理 返回中文
  7. // 枚举处理函数 根据1/2返回正式或者非正式
  8. function transEmployment(value) {
  9. const TYPES = {
  10. 1: '正式',
  11. 2: '非正式'
  12. }
  13. return TYPES[value]
  14. }
  15. export function getExportData(sourceData, headerRelation) {
  16. const data = sourceData.map(item => {
  17. const arr = []
  18. Object.values(headerRelation).forEach(key => {
  19. // 关键位置:把所有的value不做任何处理直接扔到了数组中 导致excel是源数据
  20. // 如果是当前要处理的是聘用形式 就先转化一步再添加到数组中
  21. if (key === 'formOfEmployment') {
  22. const formatValue = transEmployment(item[key])
  23. arr.push(formatValue)
  24. } else {
  25. arr.push(item[key])
  26. }
  27. })
  28. return arr
  29. })
  30. return {
  31. data
  32. }
  33. }
  34. /**
  35. * @description: 获取导入时的处理之后的接口数据
  36. * @param {*} results
  37. * @return {*}
  38. */
  39. export function getImportJsData(results, headerRelation) {
  40. const newArr = []
  41. // 将所有的中文key转换成英文key 然后添加到新数组中
  42. results.forEach(item => {
  43. const map = {}
  44. Object.keys(item).forEach(key => {
  45. map[headerRelation[key]] = item[key]
  46. })
  47. newArr.push(map)
  48. })
  49. // 时间处理
  50. newArr.forEach(item => {
  51. Object.keys(item).forEach(key => {
  52. if (key === 'timeOfEntry') {
  53. item[key] = new Date(formatDate(item[key], '/'))
  54. }
  55. })
  56. })
  57. return newArr
  58. }
  59. export function formatDate(numb, format) {
  60. const time = new Date((numb - 1) * 24 * 3600000 + 1)
  61. time.setYear(time.getFullYear() - 70)
  62. const year = time.getFullYear() + ''
  63. const month = time.getMonth() + 1 + ''
  64. const date = time.getDate() - 1 + ''
  65. if (format && format.length === 1) {
  66. return year + format + (month < 10 ? '0' + month : month) + format + (date < 10 ? '0' + date : date)
  67. }
  68. return year + (month < 10 ? '0' + month : month) + (date < 10 ? '0' + date : date)
  69. }

 下载Excel表格的俩种方式

前端主导方案图

后端主导方案图

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/煮酒与君饮/article/detail/770394
推荐阅读
相关标签
  

闽ICP备14008679号