vue使用elemtui + xlsx实现excel导入,上传到koa后端

  1. 引入el-upload组件,使用el-upload
<template>
  <div id="excel">
    <el-upload class="upload-demo"
               action="https://jsonplaceholder.typicode.com/posts/"
               :on-change="handleChange"
               :auto-upload="false"
               :show-file-list="false"
               multiple
               :limit="3"
               ref="uploadRef"
               accept=".xls, .xlsx">
      <el-button size="middle"
                 type="primary">点击上传</el-button>
    </el-upload>
  </div>
</template>

// script中的data
data () {
    return {
      // 用来保存上传的excel数据
      excel: []
    }
  }
  1. 引入第三方库xlsx
// npm install xlsx --save
// npm install -S file-saver
// npm install -D script-loader
  1. 封装读取excel的方法
import XLSX from 'xlsx'

readExcel (file) {
      // 将它做成一个promise对象
      return new Promise((resolve, reject) => {
        // 使用文件对象打开文件,获取其中内容
        const reader = new FileReader()
        // 固定用法,用来获取文件中的内容
        reader.onload = e => {
          // 获取文件中的内容
          const data = e.target.result
          // 固定用法,以二进制方式读取
          this.wb = XLSX.read(data, {
            type: 'binary'
          })
          // console.log(this.wb)
          // 用来存抽取出来的excel数据
          const result = []
          this.wb.SheetNames.forEach(SheetName => {
            result.push({
              // 这个相当于excel里面的sheet的名字
              sheetName: SheetName,
              // 将excel转换为json格式
              sheet: XLSX.utils.sheet_to_json(this.wb.Sheets[SheetName])
            })
          })
          resolve(result)
        }
        // 以二进制方式打开文件,readAsBinaryString值能读取blob和file对象,而file.ra就是file对线,如果是原生js这就是file[0]
        reader.readAsBinaryString(file.raw)
      })
    }
  1. 在handleChange方法中调用读取方法
handleChange (file) {
      // console.log(file)
      // 对上传文件的name以.进行分割成两部分,取第二部分进行文件类型验证
      const types = file.name.split('.')[1]
      const fileType = ['xlsx', 'xlc', 'xlm', 'xls', 'xlt', 'xlw', 'csv'].some(item => item === types)
      // 判断文件类型是否正确
      if (!fileType) {
        this.$message('格式错误!请重新选择')
        return
      }
      // 调用封装好的readExcel方法
      this.readExcel(file).then(tabJson => {
        if (tabJson && tabJson.length > 0) {
          // const xlsxJson = tabJson
          // console.log('数据:', tabJson)
          // 抽离数据
          tabJson.forEach(valid => {
            valid.sheet.forEach(v => {
              // 将数据保存到excel数组
              this.excel.push(v)
            })
          })
          // console.log(this.excel)
          // 将事件发送出去
          this.$emit('excelList', this.excel)
        }
      })
      // console.log(this.$refs.uploadRef)
      this.$refs.uploadRef.clearFiles()
    }
  1. 在另外一个组件中使用上面的excel组件
// 比如在student.vue中使用
<excel @excelList="importExcel"
                 ref="excelRef"></excel>

// script中的data
data (){
    // excel数据
      excelList: []
}

// methods中的方法
async importExcel (e) {
      // console.log(e)
      // 这里的e是excel组件发送过来的数据,也就是抽离后的excel数据
      e.forEach(valid => {
        // console.log(valid)
        // excel中对应的数据字段
        const obj = {
          studentNumber: valid.学号,
          name: valid.姓名,
          sex: valid.性别,
          college: valid.学院,
          class: valid.班级,
          tower: valid.宿舍,
          dorm: valid.宿舍号,
          tel: valid.电话
        }
        // 保存数据到excelList
        this.excelList.push(obj)
      })
      // console.log(this.excelList)
      // 发送网络请求
      const { data: res } = await this.$axios.get('/student/addExcelData', {
        params: {
          // 将保存在excelList的excel数据转换成json字符串,因为这是要将一个数组上传到koa
          excelList: JSON.stringify(this.excelList)
        }
      })
      // console.log(res)
      if (res.code !== 0) {
        this.$message.warning('添加失败,请确认学号有没有重复或之前是否已经添加过该学生')
        this.$refs.excelRef.removeFile()
        this.excelList = []
        return false
      } else {
        this.$message.success('添加成功,新增内容在最后一页呦!')
        // 移除上传的文件,为了防止后续上传数据的时候造成二次上传
        this.$refs.excelRef.removeFile()
        // 重新获取最新的数据,包括上传的exce展示到前端页面
        this.getStudentList()
        // 清空excelList里面保存有的excel数据,防止二次上传不同excel的数据时造成数据重复
        this.excelList = []
      }
    }
         
  1. koa后端数据处理,进行数据保存到mongoose
// 导入excel的接口
router.get('/addExcelData', async (ctx, next) => {
  // console.log('数组为:', ctx.query.excelList, '-------')
  // 将json字符串解析回json对象
  var obj = eval('(' + ctx.query.excelList + ')')
  console.log(obj.length)
  let code
  try {
    await StudentModel.insertMany(obj)
    code = 0
  } catch (error) {
    console.log(error)
    code = -1
  }
  ctx.body = {
    meg: code === 0 ? '添加成功' : '添加失败',
    code: code
  }
})

你可能感兴趣的:(笔记)