前几天因为业务需求,所维护的而后台中出现了大量关于上传下载Excel的操作。因为我们的后台是基于Vue,并且是在 vue-element-admin 的基础上结合实际需求开发而来。vue-element-admin 中也有一些相关操作 Excel 的示例,都十分清晰明了,很快就能上手。而我们当然首要参考了 vue-element-admin 的操作方式,如上传 Excel:

<template><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">Drop excel file here or<el-button :loading="loading" style="margin-left:16px;" size="mini" type="primary" @click="handleUpload">Browse</el-button></div></div>
</template><script>
import XLSX from 'xlsx'
///
</script>

在上传 Excel 中,vue-element-admin 的做法是,点击上传按钮时触发事先放在组件内的 input 的 click ,在通过监听 input 的 change 事件,获取读取到的 Excel 文档。事实上,对文件的处理也只能这样了,读取到 file 后通过 xlsx 工具库,对 file 进行 JSON 化处理再发给后端。(不要问我为什么这些事情要前端来做,问就是我乐意)。

刚刚说到这样做没得啥子问题,但是在实际项目中,尤其是后台管理系统,。几乎很多页面几乎都是表格、查询、批量操作等。最开始的时候,我就是直接把 input + 按钮 放在业务页面,但是随着项目慢慢变大,这样就显得有些臃肿了。不仅增加了代码量,也不利于维护。于是我把这个功能封装成了一个组将,就像 vue-element-admin 就类似那样。但是后来随着项目越来越来,越来越多的页面需要 Excel 操作,我对这种频繁引入此组件的方式也开始不厌其法。这个时候其实就有两种选择了:将组件注册为全局组件,或者使用自定义指令达到相同的效果。正如标题写的那样,我选择了后者。

因为 Excel 这个需求,体现上无非就是:点击了某个按钮,弹出文件选择,用户选择 Excel 后直接读取。因此,直接参与在业务中的只有按钮,至于用户在选择 Excel 后,我需要把这部操作封装一下,因为逐步操作和业务没有直接关系。因此,我需要实现一个针对选择 Excel 按钮的自定义指令:

  // 注册全局自定义快速读取 excel `v-read-excel`Vue.directive('read-excel', {inserted: (el, { value }) => {const id = Date.now()const input = document.createElement('input')el['read-excel-id'] = idinput.id = idinput.type = 'file'input.accept = '.xlsx, .xls'input.onchange = ({ target: { files: [excel] }}) => {if(!excel) return    const XLSX = require('xlsx')const reader = new FileReader()reader.onload = async({ target: { result }}) => {const workbook = XLSX.read(result, { type: 'array' })value && value(XLSX.utils.sheet_to_json(workbook.Sheets[workbook.SheetNames[0]]))}reader.readAsArrayBuffer(excel)}input.style.display = 'none'document.body.appendChild(input)el.addEventListener('click', () => document.getElementById(id).click())},unbind: el => document.getElementById(el['read-excel-id']).remove()})

使用起来无需引入组件,更无需 input ,只需要这样:

<template><div class="PageUploadExcel"><el-button v-read-excel="upload" type="primary">上传Excel</el-button></div>
</template><script>
export default {name: 'PageUploadExcel',data() {return {list: []}},methods: {upload(list) {this.list = list}}
}
</script>

原理很简单:在被绑定按钮插入文档后,给这个按钮配套一个 input 放在 body 里,点击按钮就会触发 input ... 在被绑定按钮被移除文档同时也删除掉自己所对应的 input。

这就是关于上传 Excel 的自定义指令封装操作。

至于下载,也是参考 vue-element-admin 的做法,不过也是为了使用简便,就直接把方法挂在 Vue 原型上了:

  Vue.prototype.$excel = function(list, name) {!list.length ? list = [{ '暂无数据': '' }] : ''import('@/utils/Export2Excel').then(excel => {excel.export_json_to_excel({header: Object.keys(list[0]),data: list.map(listItem => Object.keys(list[0]).map(j => listItem[j])),filename: name || '下载Excel',bookType: 'xlsx'})})}

这个用起来更简单:

<template><div class="PageDownloadExcel"><el-button type="primary" @click="download">下载Excel</el-button></div>
</template><script>
export default {name: 'PageDownloadExcel',data() {return {list: [{ '姓名': '张三', '年龄': 18, '爱好': '旅游' },{ '姓名': '李四', '年龄': 19, '爱好': '游泳' },{ '姓名': '王五', '年龄': 20, '爱好': '吃鸡' }]}},methods: {download() {this.$excel(this.list, '数据表格')}}
}
</script>

可能你也注意到了,我在这里使用的数据是:

[{ '姓名': '张三', '年龄': 18, '爱好': '旅游' },{ '姓名': '李四', '年龄': 19, '爱好': '游泳' },{ '姓名': '王五', '年龄': 20, '爱好': '吃鸡' }
]

是的,key - value 都是直接用来展示的汉字。这样做,除了方便外,也可以实现后端实时控制导出的字段,我司目前使用的就是这种方式。当然,这个要看具体的业务需求了。

input不管用 vue_Vue自定义指令实现快速读取Excel相关推荐

  1. qt快速读取excel

    很多人搜如何读写excel都会看到用QAxObject来进行操作,很多人试了之后都会发现一个问题,就是慢,非常缓慢!因此很多人得出结论是QAxObject读写excel方法不可取,效率低. 后来我曾试 ...

  2. html input ng model,Angular自定义指令中传递ngModel

    根据项目需要,希望写一个自定义指令,将指令中传递的数据(比如:my-model="name"),绑定到template中的ng-model中,并且可以被外部作用域使用. 参考了&l ...

  3. angular4获得焦点事件_深究AngularJS——如何获取input的焦点(自定义指令)

    关于如何获取input框.textarea等的焦点,网上有许多文章都只是会跟你说ng-focus这个内置指令.像这种解答,只能说明作者并为真正理解人家的需求.ng-focus是一个事件,跟原生JS(J ...

  4. 深究AngularJS——如何获取input的焦点(自定义指令)

    1. 写在前面 关于如何获取input框.textarea等的焦点,网上有许多文章都只是会跟你说ng-focus这个内置指令.像这种解答,只能说明作者并为真正理解人家的需求.ng-focus是一个事件 ...

  5. java通过POI快速读取excel大量数据的方式

    1.在pom.xml中引入poi相关依赖 <dependency><groupId>cn.afterturn</groupId><artifactId> ...

  6. python——快速读取excel文件并插入数据库

    写一个小功能. import cStringIO import pandas as pd from sqlalchemy import create_enginepath = "D://Us ...

  7. Qt快速读取Excel文件

    网上很多读取方式都是如下形式,太慢了,打开文件+读取文件要6s以上,实在是受不了! QAxObject excel("Excel.Application");excel.setPr ...

  8. vue基础--模板语法、常用指令:v-if、v-show、v-for、虚拟DOM、v-once、v-cloak、v-text、v-html、v-bind、v-on、自定义指令

    一.模板语法 Vue.js 使用了基于 HTML 的模板语法,允许开发者声明式地将 DOM 绑定至底层 Vue 实例的数据.所有 Vue.js 的模板都是合法的 HTML,所以能被遵循规范的浏览器和 ...

  9. 【Vue知识点- No6.】动态组件、插槽、自定义指令、tabbar案例

    动态组件.插槽.自定义指令 学习目标 1.能够了解组件进阶知识. 2.能够掌握自定义指令的创建和使用. 3.能够完成tabbar案例的开发. 1.组件进阶 1.0 动态组件 问题:如何切换2个组件,互 ...

最新文章

  1. 在Linux上使用图形界面的GitHub Desktop
  2. python while循环语句-python while循环控制流语句结构与用法
  3. optee3.16.0 qemu_v8的环境搭建篇(ubuntu20.10)
  4. Python十段经典代码
  5. linux组手机nas,linux 搭建nas服务器
  6. sqlite3数据库最大可以是多大?可以存放多少数据?读写性能怎么样?详述
  7. 我的学习JavaEE路线
  8. python里的拼接_Python拼接字符串的7种方法总结
  9. 图像仿射变换python实现
  10. android studio 应用全屏页,Android开发之设置应用设置全屏的两种解决方法 兼容android5.0等两种解决方法...
  11. 刘逖:ETF市场迎来发展时机 可从产品创新等方面推动
  12. matlab炮灰模型,非诚勿扰的数学分析
  13. imagenet2012 label
  14. 计算机unity文献综述,Unity3D密室逃脱游戏设计+文献综述.doc
  15. 「兔了个兔」看我如何抓取兔兔图片到本地(附源码)
  16. JS中onchange事件:域内容被改变的事件
  17. 购房流程 - 新浪网
  18. 面包牛奶的挖洞记录(一)漏洞扫描方面的法律须知和等级保护2.0简介
  19. Buffer Overflow Vulnerability Prediction from x86 executables using Static Analysis and ML
  20. 计算机网络中什么叫总衰耗_计算机网络中的四种延迟分别是什么?

热门文章

  1. ui设计师要养成哪些职场习惯呢?
  2. 零基础java培训如何规划学习路线
  3. 安卓x86_Android:虚拟机体验基于安卓10的BlissOS V12.2 Android X86版
  4. leetcode--最长连续递增序列--python
  5. ContentProvider访问问题
  6. java中如何应对读改写场景
  7. 硬中断与软中断的区别!
  8. 现在很火的答题赢钱游戏,让我来简单教你怎么做自动答题器
  9. selenium+python自动化81-html报告优化(饼图+失败重跑+兼容python23)
  10. Spring《五》集合的注入方式