ant-vue实现上传excel文件并解析内容

安装依赖

npm install xlsx --save

引入

笔者使用vue2, 引入import xlsx from ‘xlsx’ 写法,笔者使用xlsx.read和xlsx.utils.sheet_to_json报xlsx is not define,使用如下写法成功

import * as XLSX from 'xlsx/xlsx.mjs'

使用场景

笔者使用a-upload组件, 其自带的:beforeUpload=“beforeUpload”、@change=“uploadChange” 无法解析excel文件内容,自定义请求customRequest,上传时调用

<a-upload :showUploadList="false"
                    accept=".xls, .xlsx"
                    :customRequest="fileUpload">
                    <a-button type="primary">
                      <a-icon type="upload" />
                      导入Excel
                    </a-button>
                  </a-upload>

封装上传, FileReader是一种异步文件读取机制,结合input:file可以很方便的读取本地文件,本场景也可用实现

upload(file) {
      return new Promise(resolve => {
        let reader = new FileReader()
        reader.readAsBinaryString(file)// 读取文件的原始二进制数据
        reader.onload = ev => {
          resolve(ev.target.result)
        }
      })
    }

重点:
1、文件放在new FormData中传给后端
2、表格中的中文是否需要转换为后端对应的字段code
3、
const workbook = read(data, {
type: ‘binary’
});
// 取第一张表
const wsname = workbook.SheetNames[0];
// 生成json表格内容
const ws = utils.sheet_to_json(workbook.Sheets[wsname]);
后续可根据需求对ws数据处理

async fileUpload(info) {
      let file = info.file // info是组件为你解析好的数据
      if (!file) return

      let reader = await this.upload(file)
      const worker = XLSX.read(reader, { type: 'binary' }) // 设置数据类型为binary二进制
      // 这个是将数据进行一步拼接
      // 将返回的数据转换为json对象的数据
      let arr = []
      worker.SheetNames.forEach((el) => {
        let temp = XLSX.utils.sheet_to_json(worker.Sheets[el])
        temp.forEach((item) => {
          Object.keys(item).forEach((el) => {
            item[el] = String(item[el])
          })
        })
        arr.push(temp)
      })

      info.file.status = 'done'// 将文件上传状态改为‘done’,
      info.onSuccess() // 结束上传
      let data = {
        list: arr // 按照后端要求格式上传
      }
      // 后续为自己对arr数据的处理
      // 取第一个sheet表数据
      if (arr.length > 0 && arr[0] && arr[0].length > 0) {
        debugger
        let self = this
        // const files = new window.File([data], this.fileList.name, { type: this.fileList.type })
        const formData = new FormData()
        formData.append('file', file)
        jghglService.importExcel(formData).then((res) => {
          debugger
          let title = file.name.substring(0, file.name.indexOf('.'))
          let kind = file.name.substring(file.name.indexOf('.') + 1, file.name.length)
          this.mineFormInfo = {
            title: title,
            name: title,
            kind: kind,
            catalogId: this.curCatalog.id
          }
          jghglService.saveMineInfo(this.mineFormInfo)
            .then((res) => {
              if (res.success) {
                // 给前端对象赋值id,再次点保存时执行更新(未调用create此处必须赋值,调用create不用赋值)
                this.mineFormInfo.id = res.data.id
                this.mineFormInfo.version = res.data.version

                let schemaObj = {
                  dataId: this.mineFormInfo.id
                }
                jghglService.saveSchemaVersion(schemaObj).then(res => {
                  if (res.success) {
                    self.reloadTable()
                    self.mineFormInfo.schemaVersionID = res.data.id
                    // 表格中文转换为后端字段对应
                    let newArr = arr[0].map(item => {
                      return {
                        xh: item['序号'],
                        name: item['属性名称'],
                        title: item['属性标题'],
                        dataType: item['数据类型'],
                        schemaId: self.mineFormInfo.schemaVersionID
                      }
                    })
                    newArr.map(item => {
                      jghglService.savemSchemaVersionAttr(item)
                    })
                    self.$message.success('导入成功!')
                  }
                })
              } else {
                this.$message.error('导入失败:' + res.message)
              }
            })
        })
      } else {
        this.$message.info('excel表格sheet中没有数据,请重新导入!')
      }
    }

你可能感兴趣的:(前端,vue,vue.js,excel,前端)