vue3项目,批量上传excel文件,然后读取excel中内容
// 读入excel
const readXLSX = (file: any) => {
return new Promise((resolve, reject) => {
const reader = new FileReader()
reader.readAsBinaryString(file)
reader.onload = (evt: any) => {
const data = evt.target.result
const wb = XLSX.read(data, { type: 'binary' })
const jsonData = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]], {
header: ['index', 'group', 'answer', 'questions', 'resources']
})
jsonData.splice(0, 2) //删除表头
resolve(jsonData)
}
})
}
-
函数定义:
readXLSX
函数接收一个参数file
,这个参数代表要读取的 Excel 文件。 -
返回 Promise:函数返回一个新的 Promise 对象,这使得函数可以异步执行并处理完成后的结果。
-
创建 FileReader 对象:创建一个
FileReader
对象,用于读取文件内容。 -
读取文件:使用
readAsBinaryString
方法读取文件,这会将文件内容作为二进制字符串读入。 -
处理文件加载事件:当文件加载完成时,触发
onload
事件。 -
解析 Excel 文件:在事件处理函数中,使用
XLSX.read
方法读取二进制字符串,将其解析为 Excel 工作簿对象wb
。 -
转换为 JSON 格式:使用
XLSX.utils.sheet_to_json
方法将工作簿的第一个工作表转换为 JSON 对象jsonData
。这里指定了header
选项,定义了 JSON 对象的键名。 -
删除表头:使用
splice
方法删除 JSON 数组的前两个元素,这通常是 Excel 文件的表头部分。 -
解析 Promise:调用
resolve
函数,将处理后的 JSON 数据作为 Promise 的结果。
这个函数主要用于读取 Excel 文件并将其内容转换为程序可以处理的 JSON 格式,以便进行后续的数据操作。
完整代码:
上传区域:使用 <el-upload>
组件创建了一个文件上传区域,允许用户选择文件,但限制了最大文件数量,并指定了接受的文件类型为 .xlsx
格式的 Excel 文件。
<template>
<div class="upload-demo">
<el-upload
ref="upload"
v-model="fileList"
:multiple="multiple"
:limit="max"
accept=".xlsx"
:auto-upload="autoUpload"
:show-file-list="showFileList"
:drag="drag"
:on-exceed="handleExceed"
:before-upload="handleUpload"
>
<div class="uploadText">
<img src="@/assets/icons/upload.svg" alt="" />
<div class="text mt-2">先下载模版后再 <span>点击上传</span></div>
</div>
</el-upload>
<!-- <el-button type="primary" @click="changeFlie"> 确认 </el-button> -->
</div>
</template>
<script setup lang="ts">
import { ref, defineProps, toRefs } from 'vue'
import { UploadFilled } from '@element-plus/icons-vue'
import { fetchAPIGets, fetchAPIPuts, fetchPostAPI } from '@/utils/https.js'
import { ElMessage } from 'element-plus'
import * as XLSX from 'xlsx'
const upload = ref()
// const objData = ref(null)
const fileList = ref([])
const props = defineProps({
multiple: {
type: Boolean,
default: false
},
autoUpload: {
type: Boolean,
default: true
},
showFileList: {
type: Boolean,
default: true
},
max: {
type: Number,
default: 1
},
drag: {
type: Boolean,
default: false
}
})
const { multiple, autoUpload, showFileList, max, drag } = toRefs(props)
const handleExceed = (files, fileList) => {
console.warn(
`当前限制选择 ${max.value} 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`
)
}
// 读入excel
const readXLSX = (file: any) => {
return new Promise((resolve, reject) => {
const reader = new FileReader()
reader.readAsBinaryString(file)
reader.onload = (evt: any) => {
const data = evt.target.result
const wb = XLSX.read(data, { type: 'binary' })
const jsonData = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]], {
header: ['index', 'group', 'answer', 'questions', 'resources']
})
jsonData.splice(0, 2) //删除表头
resolve(jsonData)
}
})
}
// 上传文件
const handleUpload = (file: any) => {
// 检查文件大小是否超过1MB
const isSizeValid = file.size <= 1024 * 1024 // 1MB in bytes
if (!isSizeValid) {
ElMessage.error('文件大小不能超过1MB!')
return // 阻止超过1MB的文件上传
}
//读取excel文件
readXLSX(file).then((res: any) => {
// 过滤掉空数据
let data = res.filter((item: any) => {
return Object.keys(item).length >= 3
})
data = data.map((item: any) => {
// questions 用换行符分割
item['questions'] = item['questions']?.split(/\r\n|\r|\n/) || []
// 过滤掉数组中的空字符串
item['questions'] = item['questions'].filter((str: string) => str.trim() !== '')
return {
questions: item['questions'],
answer: item['answer'],
group: item['group'] ? item['group'] : '',
resources: item['resources'] ? JSON.parse(item['resources']) : []
}
})
console.log(data)
})
}
const changeFlie = () => {
// 手动触发上传
upload.value.submit()
}
</script>
<style scoped lang="scss">
.upload-demo {
/* 可以添加自定义样式 */
width: 336px;
height: 320px;
border-radius: 12px;
.uploadText {
width: 336px;
height: 320px;
margin: 100px auto;
text-align: center;
.text {
font-size: 14px;
span {
color: #3283ff;
}
}
img {
width: 54px;
height: 54px;
margin: 0px auto;
}
}
}
</style>