zoukankan      html  css  js  c++  java
  • 1 vue-cli解析上传的excel文件

    先安装xls插件

    cnpm install -S file-saver xlsx

    引入解析代码,可以单独放在一个vue文件中,我这里放在了HelloWorld.vue文件中了

    <template>
      <div>
        <input ref="excel-upload-input" class="excel-upload-input" type="file" accept=".xlsx, .xls" @change="handleClick">
        <div class="drop" @drop="handleDrop" @dragover="handleDragover" @dragenter="handleDragover">
          Drop excel file here or
          <el-button :loading="loading" style="margin-left:16px;" size="mini" type="primary" @click="handleUpload">
            Browse
          </el-button>
        </div>
      </div>
    </template>
    
    <script>
    import XLSX from 'xlsx'
    
    export default {
      props: {
        beforeUpload: Function, // eslint-disable-line
        onSuccess: Function// eslint-disable-line
      },
      data() {
        return {
          loading: false,
          excelData: {
            header: null,
            results: null
          }
        }
      },
      methods: {
        generateData({ header, results }) {
          this.excelData.header = header
          this.excelData.results = results
          this.onSuccess && this.onSuccess(this.excelData)
        },
        handleDrop(e) {
          e.stopPropagation()
          e.preventDefault()
          if (this.loading) return
          const files = e.dataTransfer.files
          if (files.length !== 1) {
            this.$message.error('Only support uploading one file!')
            return
          }
          const rawFile = files[0] // only use files[0]
    
          if (!this.isExcel(rawFile)) {
            this.$message.error('Only supports upload .xlsx, .xls, .csv suffix files')
            return false
          }
          this.upload(rawFile)
          e.stopPropagation()
          e.preventDefault()
        },
        handleDragover(e) {
          e.stopPropagation()
          e.preventDefault()
          e.dataTransfer.dropEffect = 'copy'
        },
        handleUpload() {
          this.$refs['excel-upload-input'].click()
        },
        handleClick(e) {
          const files = e.target.files
          const rawFile = files[0] // only use files[0]
          if (!rawFile) return
          this.upload(rawFile)
        },
        upload(rawFile) {
          this.$refs['excel-upload-input'].value = null // fix can't select the same excel
    
          if (!this.beforeUpload) {
            this.readerData(rawFile)
            return
          }
          const before = this.beforeUpload(rawFile)
          if (before) {
            this.readerData(rawFile)
          }
        },
        readerData(rawFile) {
          this.loading = true
          return new Promise((resolve, reject) => {
            const reader = new FileReader()
            reader.onload = e => {
              const data = e.target.result
              const workbook = XLSX.read(data, { type: 'array' })
              const firstSheetName = workbook.SheetNames[0]
              const worksheet = workbook.Sheets[firstSheetName]
              const header = this.getHeaderRow(worksheet)
              const results = XLSX.utils.sheet_to_json(worksheet)
              this.generateData({ header, results })
              this.loading = false
              resolve()
            }
            reader.readAsArrayBuffer(rawFile)
          })
        },
        getHeaderRow(sheet) {
          const headers = []
          const range = XLSX.utils.decode_range(sheet['!ref'])
          let C
          const R = range.s.r
          /* start in the first row */
          for (C = range.s.c; C <= range.e.c; ++C) { /* walk every column in the range */
            const cell = sheet[XLSX.utils.encode_cell({ c: C, r: R })]
            /* find the cell in the first row */
            let hdr = 'UNKNOWN ' + C // <-- replace with your desired default
            if (cell && cell.t) hdr = XLSX.utils.format_cell(cell)
            headers.push(hdr)
          }
          return headers
        },
        isExcel(file) {
          return /.(xlsx|xls|csv)$/.test(file.name)
        }
      }
    }
    </script>
    
    <style scoped>
    .excel-upload-input{
      display: none;
      z-index: -9999;
    }
    .drop{
      border: 2px dashed #bbb;
       600px;
      height: 160px;
      line-height: 160px;
      margin: 0 auto;
      font-size: 24px;
      border-radius: 5px;
      text-align: center;
      color: #bbb;
      position: relative;
    }
    </style>

    在你需要使用上传的地方引用该组件即可

    <template>
        <div>
           <UploadExcelComponent :on-success="handleSuccess" :before-upload="beforeUpload"/>
        </div>
    </template>
    <script>
    import UploadExcelComponent from '@/components/HelloWorld.vue'

    export default {
      name: 'UploadExcel',
      components: { UploadExcelComponent },
      data() {
        return {
          tableData: [],
          tableHeader: []
        }
      },
      methods: {
         
        beforeUpload(file) {
          const isLt1M = file.size / 1024 / 1024 < 1
          if (isLt1M) {
            return true
          }
          this.$message({
            message: 'Please do not upload files larger than 1m in size.',
            type: 'warning'
          })
          return false
        },

        handleSuccess({ results, header }) {
          this.tableData = results
          this.tableHeader = header
        }
      }
    }
    </script>
    <style scoped>
    </style>

    这里我说明几点:

    1、上传子组件里面包含了两个参数;

    2、beforeUpload方法是图片上传之前判断大小是否超过了1M,或者你自己写上传前的方法,这个也可以不写;

    3、handleSuccess方法必须要写,因为上传成功后的数据都在这个里面;

    引入后的界面如下

     我要上传的表的数据

     为了方便演示,我在这里将上传成功后的数据进行打印

     上传后的结果

    至此ok.

    补:

    大家注意解析后的key是中文,不能直接映射到具体的实体类中

     处理办法

     然后后台使用List接收即可,注意有@RequestBody注解(因为我们的前端数据没有对应的user key)

     至此ok

  • 相关阅读:
    java wait方法
    thread join
    AtomicReference 原理
    exchanger java另一种栅栏
    CyclicBarrier 栅栏 原理,应用场景
    信号量Semaphore
    FutureTask 解析
    CountDownLatch
    java 双端队列 Deque
    lockInterruptibly 和lock 原理
  • 原文地址:https://www.cnblogs.com/gfbzs/p/12682589.html
Copyright © 2011-2022 走看看