• 使用antd的上传组件做上传附件数据校验踩坑


    我这里需求是上传文件前先校验附件是否符合要求,原本使用的是antd的上传组件a-uploud,然后在beforeUpload方法里读取文件,符合要求的附件添加到fileList中。

    正常上传的附件格式是这样的:
    在这里插入图片描述
    但是,我这里要读区文件,需要加以下操作,加完读取文件的操作后,上传的附件就会多了error等参数,导致a-uploud组件一直报上传错误
    在这里插入图片描述

    // 我这里对上传的主要是表格数据,只要判断表头是否一样,上传的文件第一栏要是表头
    const beforeUpload = (file, val) => {
      let fileSize = val.options.rules.fileSize || 50
      if (file.size > fileSize * 1024 * 1024) {
        $message.error(`文件不能大于${fileSize}M`);
        return false;
      };
    
      const reader = new FileReader()
      reader.onload = e => {
        const data = e.target.result
        const workbook = XLSX.read(data, {
          cellDates: true
        })
        const firstSheetName = workbook.SheetNames[0]
        const worksheet = workbook.Sheets[firstSheetName]
        const header = getHeaderRow(worksheet)
        const results: any[] = XLSX.utils.sheet_to_json(worksheet, { defval: '' });
        const isMatch = header.join() === val.tHeaders.map(x => x.label).join();
        if (!isMatch) {
          $message.error('上传模版不匹配,无法导入,请基于设计的表格上传模版');
        } else {
          val.fileList = []
          val.fileList.push(file)
        }
      }
      reader.readAsArrayBuffer(file)
      return false;
    }
    const getHeaderRow = (sheet) => {
      const headers = []
      const range = XLSX.utils.decode_range(sheet['!ref'])
      let C
      const R = range.s.r
      for (C = range.s.c; C <= range.e.c; ++C) {
        const cell = sheet[XLSX.utils.encode_cell({ c: C, r: R })]
        let hdr = 'UNKNOWN ' + C
        if (cell && cell.t) hdr = XLSX.utils.format_cell(cell)
        headers.push(hdr)
      }
      return headers
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    各种尝试无果后只能手撸上传组件了

    template部分:

    <div style="display: inline-block">
      <input
        ref="tableUplad"
        class="excel-upload-input"
        type="file"
        :accept="data.options.accept"
        style="display: none;"
        @change="e => handleClick(e, data)"
      />
      <a-button @click="handleUpload">
        <SvgIcon iconClass="fileupload" style="margin-right: 10px;" />
        点击上传
      </a-button>
    </div>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    ts部分

    // tableUplad是我给上传模版这里设置的ref值,我这里用的是vue3,所以实际操作时要用tableUplad.value操作
    const tableUplad = ref(null as any)
    const handleUpload = () => {
      tableUplad.value.click();
    }
    const handleClick = (e, val) => {
      const files = e.target.files
      const rawFile = files[0] // only use files[0]
      if (!rawFile) return
      upload(rawFile, val)
    }
    const upload = (rawFile, val) => {
      tableUplad.value.value = null // fix can't select the same excel
      readerData(rawFile, val)
    }
    const readerData = (rawFile, val) => {
      return new Promise((resolve, reject) => {
        const reader = new FileReader()
        reader.onload = e => {
          const data = e.target.result
          const workbook = XLSX.read(data, {
            cellDates: true
          })
          const firstSheetName = workbook.SheetNames[0]
          const worksheet = workbook.Sheets[firstSheetName]
          const header = getHeaderRow(worksheet)
          const results: any[] = XLSX.utils.sheet_to_json(worksheet, { defval: '' });
          const isMatch = header.join() === val.tHeaders.map(x => x.label).join();
          if (!isMatch) {
            $message.error('上传模版不匹配,无法导入,请基于设计的表格上传模版');
          } else {
            val.fileList = []
            val.fileList.push(rawFile)
          }
        }
        reader.readAsArrayBuffer(rawFile)
      })
    }
    const getHeaderRow = (sheet) => {
      const headers = []
      const range = XLSX.utils.decode_range(sheet['!ref'])
      let C
      const R = range.s.r
      for (C = range.s.c; C <= range.e.c; ++C) {
        const cell = sheet[XLSX.utils.encode_cell({ c: C, r: R })]
        let hdr = 'UNKNOWN ' + C
        if (cell && cell.t) hdr = XLSX.utils.format_cell(cell)
        headers.push(hdr)
      }
      return headers
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    OK,主要逻辑就这些了,剩下的就是仿照antd的上传组件添加上传附件列表就搞定了,我就不贴了,总体来说已经满足我的要求了,搞定收工!

  • 相关阅读:
    关于雅思听力答案限定字数的解释。
    探画系统探画系统开发源码分享
    【luogu CF1427F】Boring Card Game(贪心)(性质)
    Identity Server 4客户端认证控制访问API
    Spring事务和事务的传播机制(JavaEE进阶系列7)
    GIT 使用
    STM32输出SPWM波,HAL库,cubeMX配置,滤波后输出1KHz正弦波
    Python数据分析--Numpy常用函数介绍(2)
    Antv/G2 分组柱状图+折线图双轴图表
    Spring.NET使用Oracle.DataAccess.Client访问数据库
  • 原文地址:https://blog.csdn.net/qq_42527726/article/details/128048791