前言
星期五,又可以熬夜了,嘻嘻嘻,当然我说的是熬夜学习,把最近项目中的导入拿了出来,写了一个小Demo,方便大家直接使用
导入总结
说起导入,很多的后台管理里面都有,******什么一键导入,一键导出啊。可怜的开发仔,小丑竟是我自己
话不多说,先看电视
- 项目业务:导入存本地,导出从本地拿
这里用到了
element
的上传组件,如果你也是,直接拿走
导出看下集<<<<<<<<<<
安装
npm install xlsx
上传的页面,如果你使用的是 element 的直接拷贝,小白可以看有每一步的注释
<template>
<div class="uploadBox">
<!-- 返回主页 -->
<div class="homeBox">
<router-link to="/">
<el-tooltip content="返回列表页面" placement="top">
<i class="el-icon-tickets"></i>
</el-tooltip>
</router-link>
</div>
<!-- 上传文件按钮 -->
<div class="buttonBox">
<el-upload
action
accept=".xlsx,.xls"
:auto-upload="false"
:show-file-list="false"
:on-change="handle"
>
<el-button type="primary" slot="trigger">选取 Excel 文件</el-button>
</el-upload>
<el-button type="success" @click="submit">采集数据提交</el-button>
</div>
<!-- 解析出来的数据 -->
<div class="tableBox" v-show="show">
<h3>
<i class="el-icon-info">
小主,以下是采集完成的数据,请您检查无误后,点击“采集数据提交”按钮上传至服务器</i
>
</h3>
<el-table :data="tempData" border style="width: 100%" :height="height">
<el-table-column
prop="name"
label="姓名"
min-width="50%"
></el-table-column>
<el-table-column
prop="phone"
label="电话"
min-width="50%"
></el-table-column>
</el-table>
</div>
</div>
</template>
<script>
import xlsx from 'xlsx' // 需要安装的导入插件
import { Loading } from 'element-ui' // element的loading 服务
import { readFile, character, delay } from '../assets/js/utils' // 封装的方法 必看
export default {
name: 'Upload',
data() {
return {
height: document.documentElement.clientHeight - 130,
tempData: [], // 表格数据
show: false // 表格是否显示
}
},
methods: {
// 采集 EXCEL 数据
async handle(e) {
let file = e.raw // 拿到 File 对象
if (!file) return // 没有就不往下走
this.show = false // 没次进来,表格先不显示
let loading = Loading.service({ // 提前定义一个 element的一个异步loading服务
text: '小主,请您稍等片刻,女家正在玩命处理中...',
background: 'rgba(0,0,0,.5)'
})
await delay(300) // 调用的外部方法,看下面,作用是人性化等待300毫秒,代码再像下走
// 读取FILE中的数据
let data = await readFile(file) // 调用的外部方法,二进制读取表格里的数据
// 打开xlsx文件,最下面是你打开的哪一个表卡
let workbook = xlsx.read(data, { type: 'binary' }), // 利用xlsx的内置方法得到读取到所有的表卡的xlsx数据
worksheet = workbook.Sheets[workbook.SheetNames[0]], // 拿到你第一个
list = xlsx.utils.sheet_to_json(worksheet) // xlsx转换成JSON格式 顺便给空的单元格赋值为空字符串
// console.log(list)
// 把读取出来的数据变为可以提交为服务器的数据格式
let arr = [] // 定义一个空数组
let oldData = JSON.parse(window.localStorage.getItem('excel') || '[]') // 查看本地的excel
let index = oldData.length // 赋值一个index索引
list.forEach(item => { // 循环上面拿到的表格数据
let obj = {} // 定义一个对象,一会给显示表单当数据
for (let key in character) { // 别问从哪来的,看引入的方法
if (!character.hasOwnProperty(key)) break // 根据 key去重
let v = character[key], // 下面这是改变读取到表单的名字(刚看有点,不防自己修改方法里的对象打印一下)
text = v.text,
type = v.type
v = item[text] || ''
type === 'string' ? (v = String(v)) : null // 给不同的数据定义类型
type === 'number' ? (v = Number(v)) : null
obj[key] = v // 给对象里的Key赋值
}
obj.id = ++index // id 索引加加
obj.time = new Date() // new一个时间给每一个对象,可能你们用不到
arr.push(obj) // arr 就是给后端的数据
})
await delay(300) // 让时间静止300毫秒,体验感爆棚
// 展示到页面中
this.show = true // 此时已经改整理好的数据准备好了,让传递给后端的表格显示把,可以检查数据对不对
console.log(arr,'这就是传给后端的数据')
this.tempData = arr // 给表格赋值
loading.close() // loading的服务也可以关了
},
// 提交数据给服务器
submit() {
if (this.tempData.length <= 0) { // 如果没有上传东西
return this.$message({ // 提示
message: '小主,请您先选择 EXCEL 文件!',
type: 'warning',
showClose: true
})
}
// 存到本地,为下节导入导出做准备 在实际项目中这里就是给后端传数据的接口了
let oldData = JSON.parse(window.localStorage.getItem('excel') || '[]'), // 深拷贝
newData = [...oldData, ...this.tempData] // 结构
window.localStorage.setItem('excel', JSON.stringify(newData)) // 存到本地,为下节导入导出做准备
this.$message({
message: '文件已保存到本地!',
type: 'success',
showClose: true
})
}
}
}
</script>
<style lang="less" scoped>
.homeBox {
position: fixed;
top: 10px;
right: 20px;
z-index: 9999;
font-size: 40px;
}
.buttonBox {
padding: 15px;
display: flex;
width: 35%;
justify-content: flex-start;
& .el-button {
margin-right: 20px !important;
}
}
.tableBox {
padding: 0 15px;
h3 {
font-size: 18px;
color: #f56c6c;
padding-bottom: 15px;
}
}
</style>
引入的三个方法的文件
// 设置异步延迟间隔
export function delay(interval = 0) {
return new Promise(resolve => {
let timer = setTimeout(_ => {
clearTimeout(timer)
resolve()
}, interval)
})
}
// 按照二进制读取文件
export function readFile(file) {
return new Promise(resolve => {
let reader = new FileReader()
reader.readAsBinaryString(file)
reader.onload = e => {
resolve(e.target.result)
}
})
}
// 字段对应表
export let character = { // 根据实际情况,添加表头信息,类型
name: {
text: '姓名',
type: 'string'
},
phone: {
text: '电话',
type: 'string'
}
}
// 时间字符串格式化
export function formatTime(str, tpl) {
let arr = str.match(/\d+/g).map(item => {
return item.length < 2 ? '0' + item : item
})
tpl = tpl || '{0}年{1}月{2}日 {3}时{4}分{5}秒'
return tpl.replace(/\{(\d+)\}/g, (_, group) => {
return arr[group] || '00'
})
}
有需要源码的,call 我…