位置: IT常识 - 正文

【前端】批量导入和导出Excel数据(前端批量下载图片)

编辑:rootadmin
【前端】批量导入和导出Excel数据 1.准备

推荐整理分享【前端】批量导入和导出Excel数据(前端批量下载图片),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:前端批量删除功能,前端批量删除功能,前端导入导出,前端批量下载图片,前端批量删除功能,前端批量导入,前端批量上传图片,前端批量上传图片,内容如对您有帮助,希望把文章链接给更多的朋友!

excel导入功能需要使用npm包xlsx,所以需要安装xlsx插件,读取和写入都依赖她

$ npm i xlsx@0.17.0

vue-element-admin模板提供了一个导入excel数据的文件,我们只需用即可

代码地址:https://github.com/PanJiaChen/vue-element-admin/blob/master/src/components/UploadExcel/index.vue

将vue-element-admin提供的导入功能新建一个组件,位置:src/components/UploadExcel/index.vue

<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">将文件拖到此处<el-button :loading="loading" style="margin-left:16px;" size="mini" type="primary" @click="handleUpload">点击上传文件</el-button></div></div></template><script>import XLSX from 'xlsx'export default {props: {beforeUpload: Function, // eslint-disable-lineonSuccess: Function// eslint-disable-line},data() {return {loading: false,excelData: {header: null,results: null}}},methods: {generateData({ header, results }) {this.excelData.header = headerthis.excelData.results = resultsthis.onSuccess && this.onSuccess(this.excelData)},handleDrop(e) {e.stopPropagation()e.preventDefault()if (this.loading) returnconst files = e.dataTransfer.filesif (files.length !== 1) {this.$message.error('Only support uploading one file!')return}const rawFile = files[0] // only use files[0]if (!this.isExcel(rawFile)) {this.$message.error('Only supports upload .xlsx, .xls, .csv suffix files')return false}this.upload(rawFile)e.stopPropagation()e.preventDefault()},handleDragover(e) {e.stopPropagation()e.preventDefault()e.dataTransfer.dropEffect = 'copy'},handleUpload() {this.$refs['excel-upload-input'].click()},handleClick(e) {const files = e.target.filesconst rawFile = files[0] // only use files[0]if (!rawFile) returnthis.upload(rawFile)},upload(rawFile) {this.$refs['excel-upload-input'].value = null // fix can't select the same excelif (!this.beforeUpload) {this.readerData(rawFile)return}const before = this.beforeUpload(rawFile)if (before) {this.readerData(rawFile)}},readerData(rawFile) {this.loading = truereturn new Promise((resolve, reject) => {const reader = new FileReader()reader.onload = e => {const data = e.target.resultconst workbook = XLSX.read(data, { type: 'array' })const firstSheetName = workbook.SheetNames[0]const worksheet = workbook.Sheets[firstSheetName]const header = this.getHeaderRow(worksheet)const results = XLSX.utils.sheet_to_json(worksheet)this.generateData({ header, results })this.loading = falseresolve()}reader.readAsArrayBuffer(rawFile)})},getHeaderRow(sheet) {const headers = []const range = XLSX.utils.decode_range(sheet['!ref'])let Cconst R = range.s.r/* start in the first row */for (C = range.s.c; C <= range.e.c; ++C) { /* walk every column in the range */const cell = sheet[XLSX.utils.encode_cell({ c: C, r: R })]/* find the cell in the first row */let hdr = 'UNKNOWN ' + C // <-- replace with your desired defaultif (cell && cell.t) hdr = XLSX.utils.format_cell(cell)headers.push(hdr)}return headers},isExcel(file) {return /\.(xlsx|xls|csv)$/.test(file.name)}}}</script><style scoped>.excel-upload-input{display: none;z-index: -9999;}.drop{border: 2px dashed #bbb;width: 600px;height: 160px;line-height: 160px;margin: 0 auto;font-size: 24px;border-radius: 5px;text-align: center;color: #bbb;position: relative;}</style>

我们在需要导入和导出excel的index页面引入此组件

分析一下上面的代码,需要我们传入onSuccess函数

2.实现excel导入

首先我们封装一个向后端请求 数据的接口

/** ** 封装一个导入员工的接口,data是数组** ***/export function importEmployee(data) {return request({url: '/sys/user/batch',method: 'post',data})}

我们传入onSuccess函数

<template><!-- 公共导入组件 --><upload-excel :on-success="success" /></template>import { importEmployee } from '@/api/employees'// 在methods中修改success函数async success({ header, results }) {console.log(results)//results就是我们通过excel导入进来的数据,之后需要把他传递给后端}

从excel导进来的数据是数组,里面一堆员工信息对象,key值是中文,需要转化成英文导入

import { importEmployee } from '@/api/employees'// 在methods中修改success函数async success({ header, results }) {// 如果是导入员工//header中的数据是中文,results中的数据也是中文,要和新增的员工的属性是一致的//定义一个映射关系对象const userRelations = {'入职日期': 'timeOfEntry','手机号': 'mobile','姓名': 'username','转正日期': 'correctionTime','工号': 'workNumber'}// map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值var newArr = results.map(item => {var userInfo = {}Object.keys(item).forEach(key => {userInfo[userRelations[key]] = item[key]// 相当于 userInfo[mobile]=mobile这种})return userInfo})await importEmployee(newArr) // 调用导入接口,newArr就是转化好的数据,向后端发起请求this.$message.success('导入excel成功')}

但是此时 时间格式不对,当excel中有日期格式的时候,实际转化的值为一个数字,我们需要一个方法进行转化

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)} async success({ header, results }) {// console.log(header, results)// results里是 [{…}, {…}, {…},],每一个对象里和userRelations一样// 自定义一个映射关系const userRelations = {'入职日期': 'timeOfEntry','手机号': 'mobile','姓名': 'username','转正日期': 'correctionTime','工号': 'workNumber'}// 把中文的key变成英文var newArr = results.map(item => {var userInfo = {}// Object.keys(item)得到 ['手机号', '姓名', '入职日期', '转正日期', '工号']Object.keys(item).forEach(key => {if (userRelations[key] === 'timeOfEntry' || userRelations[key] === 'correctionTime') {console.log(item[key])// 44937console.log(this.formatDate(item[key]))// 20230210console.log(new Date(this.formatDate(item[key], '/')))// Tue Feb 21 2023 00:00:00 GMT+0800 (中国标准时间)userInfo[userRelations[key]] = new Date(this.formatDate(item[key], '/'))} else {userInfo[userRelations[key]] = item[key]}})return userInfo})// 请求接口await importEmployee(newArr)this.$message.success('导入excel成功')},// 格式化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)}3.实现excel导出

Excel 的导入导出都是依赖于js-xlsx来实现的。

由于 Export2Excel不仅依赖js-xlsx还依赖file-saver和script-loader。

在 js-xlsx的基础上又封装了Export2Excel.js来方便导出数据。

npm install xlsx@0.17.0 file-saver -Snpm install script-loader -S -D //懒加载,运行和开发时都用到

由于js-xlsx体积还是很大的,导出功能也不是一个非常常用的功能,所以使用的时候建议使用懒加载。使用方法如下:

/*懒加载script-loader的作用,等点击导出按钮时候才会引入这个包然后才会执行导出的方法import('@/vendor/Export2Excel').then ,意思是先引入包,包引入成功后执行then后得操作,then的参数excel就是包导出的内容,内容里有excel.export_json_to_excel方法里的东西*/import('@/vendor/Export2Excel').then(excel => {excel.export_json_to_excel({header: tHeader, //表头 必填data, //具体数据 必填 [[],[]]filename: 'excel-list', //非必填autoWidth: true, //非必填bookType: 'xlsx' //非必填})})

参数

说明

类型

可选值

默认值

header

导出数据的表头

Array

/

[]

data

导出的具体数据

Array

/

[[],[]...]

filename

导出文件名

String

/

excel-list

【前端】批量导入和导出Excel数据(前端批量下载图片)

autoWidth

单元格是否要自适应宽度

Boolean

true / false

true

bookType

导出文件类型

String

xlsx, csv, txt, more

xlsx

我们现在的数据是这种格式

需要变成这种格式才能导出,他没有key,只有value

我们最重要的一件事,就是把表头和数据进行相应的对应

因为数据中的key是英文,想要导出的表头是中文的话,需要将中文和英文做对应

// 导出excel数据exportData() {// 做操作// 表头对应关系const headers = {'姓名': 'username','手机号': 'mobile','入职日期': 'timeOfEntry','聘用形式': 'formOfEmployment','转正日期': 'correctionTime','工号': 'workNumber','部门': 'departmentName'}// 懒加载import('@/vendor/Export2Excel').then(async excel => {// page: this.page.total 的目的是要一次性把全部的员工列表查询出来//获取所有员工数据的接口const { rows } = await getEmployeeList({ page: 1, size: this.page.total })// [["张三", "13811111111","2018","1", "2018", "10002"],["李思", "13911111111","2018","1", "2018", "10002"],...]const data = this.formatList(headers, rows)excel.export_json_to_excel({header: Object.keys(headers),//表头data,//把转化好格式的data放这里,data是[[],[]..]格式filename: '员工信息表',autoWidth: true,bookType: 'xlsx'})})},// 该方法负责将数组转化成二维数组formatList(headers, rows) {// 首先遍历数组// [{ username: '张三', mobile: '13811111111', ...},{},{}] => [[’张三', '13811111111',...],[],[]]return rows.map(item => {// Object.keys(headers) => ['姓名','手机号',...]return Object.keys(headers).map(key => {return item[headers[key]] // 张三, 13811111111, 2018, ...}) // => ["张三", "13811111111","2018","1", "2018", "10002"]}) // [["张三", "13811111111","2018","1", "2018", "10002"],["李四", "13911111111","2018","1", "2018", "10002"]]}

此时导出来的数据就是[[],[]..]数组包数组的格式

但是发现日期和聘用形式不对,下面还需要格式化日期

function formatDate(date, fmt = 'yyyy-MM-dd') {if (!(date instanceof Array)) {date = new Date(date)}if (/(y+)/.test(fmt)) {fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length))}const o = {'M+': date.getMonth() + 1,'d+': date.getDate(),'h+': date.getHours(),'m+': date.getMinutes(),'s+': date.getSeconds()}for (const k in o) {if (new RegExp(`(${k})`).test(fmt)) {const str = o[k] + ''fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? str : padLeftZero(str))}}return fmt}

聘用形式需要改成文字形式,这个文件在src\api\constant\employees.js下,需要导入

1对应正式,2对应非正式

import EmployeeEnum from '@/api/constant/employees' // 员工信息的枚举formatList(headers, rows) {// console.log(rows)// [{},{},{}]// 需要把 [{ username: '张三', mobile: '13811111111', ...},{},{}] => [[’张三', '13811111111',...],[],[]]// 需要把每个对象里的value取出来组成数组,所以需要把每个对象里的key找到return rows.map(item => {// item是每个员工信息的对象return Object.keys(headers).map(key => { // key是手机号,姓名..if (headers[key] === 'timeOfEntry' || headers[key] === 'correctionTime') {return formatDate(item[headers[key]])} else if (headers[key] === 'formOfEmployment') {const isRepeat = EmployeeEnum.hireType.find(obj => {// 查找数组中符合条件的第一个元素return obj.id === item[headers[key]]})return isRepeat ? isRepeat.value : '未知'}// headers[key]是mobile,usernamereturn item[headers[key]]})})}复杂表头的导出(拓展)

需要添加两个额外的参数

参数

说明

类型

可选值

默认值

multiHeader

复杂表头的部分

Array

/

[[]]

merges

需要合并的部分

Array

/

[]

multiHeader里面是一个二维数组,里面的一个元素是一行表头,假设你想得到一个如图的结构

const multiHeader = [['姓名', '主要信息', '', '', '', '', '部门']]const header = ['姓名', '手机号', '入职日期', '聘用形式', '转正日期', '工号', '部门']

multiHeader中的一行表头中的字段的个数需要和真正的列数相等,假设想要跨列,多余的空间需要定义成空串

它主要对应的是标准的表头

如果,我们要实现其合并的效果, 需要设定merges选项

const merges = ['A1:A2', 'B1:F1', 'G1:G2']

merges的顺序是没关系的,只要配置这两个属性,就可以导出复杂表头的excel了

本文链接地址:https://www.jiuchutong.com/zhishi/288024.html 转载请保留说明!

上一篇:一只正在树上吃东西的山地大猩猩,乌干达布恩迪国家公园 (© Robert Haasmann/Minden Pictures)(一只正在树上吃的苹果)

下一篇:uniapp使用高德JS API(uniapp使用高德猎鹰服务)

  • Zotac 将 Nvidia A4500 GPU 压缩到 8 英寸机箱中

    Zotac 将 Nvidia A4500 GPU 压缩到 8 英寸机箱中

  • 三星手机微信视频怎么开美颜(三星手机微信视频不提醒,必须点开后才收到)

    三星手机微信视频怎么开美颜(三星手机微信视频不提醒,必须点开后才收到)

  • 享做笔记怎么删除某一页(享做笔记怎么删除图片)

    享做笔记怎么删除某一页(享做笔记怎么删除图片)

  • 华为nova5i搭载什么系统(华为nova5i好用吗 可以用多长时间)

    华为nova5i搭载什么系统(华为nova5i好用吗 可以用多长时间)

  • 胶体电池能用几年(胶体电池好吗)

    胶体电池能用几年(胶体电池好吗)

  • 交换机的三种交换方式(交换机的三种交换结构)

    交换机的三种交换方式(交换机的三种交换结构)

  • 双十一天猫规定的发货时间(双十一天猫有什么优惠活动)

    双十一天猫规定的发货时间(双十一天猫有什么优惠活动)

  • 饿了么致歉红包是什么意思(饿了么致歉红包会扣骑手钱吗)

    饿了么致歉红包是什么意思(饿了么致歉红包会扣骑手钱吗)

  • 苹果x手机屏幕不受控制乱跳(苹果x手机屏幕失灵解决方法)

    苹果x手机屏幕不受控制乱跳(苹果x手机屏幕失灵解决方法)

  • 怎么取消微博认证(怎么取消微博认证申请)

    怎么取消微博认证(怎么取消微博认证申请)

  • 淘宝店铺多久自动关闭(淘宝店铺多久自动确认收货)

    淘宝店铺多久自动关闭(淘宝店铺多久自动确认收货)

  • 手机卡关机了是怎么回事(手机卡关机是否可以定位)

    手机卡关机了是怎么回事(手机卡关机是否可以定位)

  • 淘宝二钻和一钻有区别吗(淘宝二钻和一钻哪个好)

    淘宝二钻和一钻有区别吗(淘宝二钻和一钻哪个好)

  • 快手关注别人又取消,别人会知道吗(快手关注别人又取关了别人能看到吗)

    快手关注别人又取消,别人会知道吗(快手关注别人又取关了别人能看到吗)

  • 微信不能播放视频怎么办(微信不能播放视频怎么解决)

    微信不能播放视频怎么办(微信不能播放视频怎么解决)

  • 淘宝聊天记录怎么恢复(淘宝聊天记录怎么删除)

    淘宝聊天记录怎么恢复(淘宝聊天记录怎么删除)

  • 12306订票后多久取票(12306订票多久退不用手续费)

    12306订票后多久取票(12306订票多久退不用手续费)

  • 陌陌为啥不能语音通话了(陌陌不能语音)

    陌陌为啥不能语音通话了(陌陌不能语音)

  • word能编辑的文件类型有(word编辑的文档怎么保存到桌面)

    word能编辑的文件类型有(word编辑的文档怎么保存到桌面)

  • 手机关机如何定位找人(手机关机如何定位)

    手机关机如何定位找人(手机关机如何定位)

  • 小米5sp要多久充满(小米5splus充满电要多久)

    小米5sp要多久充满(小米5splus充满电要多久)

  • 手机qq怎么改空间背景(手机QQ怎么改空白名字)

    手机qq怎么改空间背景(手机QQ怎么改空白名字)

  • 乐视手机怎么删除乐见和乐头条(乐视手机怎么删除全部联系人)

    乐视手机怎么删除乐见和乐头条(乐视手机怎么删除全部联系人)

  • win7对象不支持此属性(对象不支持enabletools)

    win7对象不支持此属性(对象不支持enabletools)

  • 拒接未接通是什么意思(电话拒接会显示未接来电)

    拒接未接通是什么意思(电话拒接会显示未接来电)

  • 淘宝闲鱼怎么交易(淘宝闲鱼怎么交易付款)

    淘宝闲鱼怎么交易(淘宝闲鱼怎么交易付款)

  • 小米蓝牙耳机充电指示灯怎么不亮(小米蓝牙耳机充不进去电怎么办)

    小米蓝牙耳机充电指示灯怎么不亮(小米蓝牙耳机充不进去电怎么办)

  • 【Pytorch深度学习50篇】·······第六篇:【常见损失函数篇】-----BCELoss及其变种

    【Pytorch深度学习50篇】·······第六篇:【常见损失函数篇】-----BCELoss及其变种

  • day02-HTML02

    day02-HTML02

  • 企业所得税汇算清缴补缴税款分录
  • 员工扣了个税但没交给税务局
  • 发票没有申报能开票吗
  • 本年计算扣除限额的基数怎么算
  • 如何开银行卡账户
  • 非居民劳务个税怎么计算
  • 一个人可以两家以上公司发放工资么
  • 采购商品成本包括
  • 营改增后计税依据
  • 房地产开发企业资质证书
  • 财务软件要入固定资产吗
  • 车间固定资产折旧属于什么科目
  • 国家税务总局2011年第25号公告
  • 个人开机械租赁发票需要什么
  • 物业公司安装监控
  • 其他收益纳税
  • 小企业会计准则主要按照什么计量
  • 这个月发票领完了,还可以领吗?
  • 企业清算期间账务怎么做
  • 暂估入库借方有余额怎么处理
  • 零申报逾期未申报怎么补报
  • 以前年度费用如何列支
  • 鸿蒙系统怎么隐藏状态栏
  • 苹果手机把旧手机的照片传到新手机
  • 个人投资额是什么意思
  • 买车的收费项目详细清单
  • 申请开立临时存款账户
  • 小规模企业有收入吗
  • 进出口公司出口退税额
  • 调入的无形资产记入哪里
  • 企业常用的成本核算方法有哪些
  • 长期债券投资业务处理
  • 转让专利权的会计处理结果
  • 哪些可以作为原始凭证
  • yolov5讲解
  • php导入php文件
  • centos安装软件教程
  • 融资租入固定资产
  • 股票收入需要交税
  • 个税各项减扣标准金额
  • 工程公司项目管理部管理制度
  • 维保措施及售后服务方案
  • 复核人和收款人一样了怎么办
  • 视同内销补税的财务处理
  • 网银可以给个人转账
  • SQL2008中通过DBCC OPENTRAN和会话查询事务
  • 个人所得税申请退税多久能到账
  • 制造业企业无形资产怎么摊销
  • 内账会计有法律风险吗
  • 车辆处置如何缴纳企业所得税
  • 微信转账如何处理退回去
  • 在建的工程收到的发票
  • 受疫情影响较大的上市公司
  • 社保局退回来的社保怎么入账
  • 应收账款少收会计分录
  • 交税务局的工会经费现金流
  • 公司的零星费用可以用对公转吗
  • 停车发票怎么盖章
  • 差旅费账务处理的摘要
  • 包含个人社保的保险
  • 建筑业属于货物经营吗
  • 实收资本会变吗?
  • 租来的办公室装修费摊销几年
  • sqlserver怎么创建临时表
  • 如何跨数据库查询
  • 关闭windowsxp窗口的方法有
  • win10 rs1是什么版本
  • Win10预览版镜像
  • os x10.12支持的机型
  • wind8系统怎么清除所有东西 恢复出厂
  • windows中的hosts文件
  • 可用分区az
  • unity控制
  • javascript面向对象编程
  • Android startActivities()的使用
  • Linux系统安装字体
  • node运行js文件
  • js基础教程
  • 工会经费支出审批制度
  • 房地产对外投资契税
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设