重要代码已标红
用到的插件组件
npm i element
npm i xlsx
vue3 引入写法有差异 具体自行百度
html:
 <div class="crenter">
        <div>
          <el-card class="box-card">
            <el-upload ref="upload" accept=".xls,.xlsx"  action="#"  :auto-upload="false"
         :multiple="false" :file-list="fileList"  :before-upload="beforeUpload" 
  :on-change="fileChange"
           drag   >
              <img class="upImg" src="../../style/img/up.png" alt="" />
              <el-button class="buttonUp" type="primary">上传excel</el-button>
              <div class="el-upload__text">或者拖放一个文件</div>
            </el-upload>
          </el-card>
          <div class="el-upload__tip">只能上传excel文件,且不超过500kb</div>
        </div>
        <div>
          <el-button style="width: 450px; margin: 20px auto; padding: 15px" type="primary"         @click="submitUpload">确认上传</el-button>
          </div>
      </div>
js:
引入组件
import XLSX from '../../../node_modules/xlsx'
export default {
  data() {
    return {
      options: [
        {
          value: 1,
          label: '整包',
        },
        {
          value: 2,
          label: '散包',
        },
        {
          value: 3,
          label: '单一来源',
        },
      ],
      is_type: '',
      action: process.env.VUE_APP_BASE_API + '/business/BizMaterialSum/importData',
      // 用户导入参数
      fileList: [],
      // 读取
      defaultIndex: 0, // 默认显示第一个工作表
      wb: null, // 工作表对象
      formData: {},
    }
  },
  created() {},
  methods: {
    beforeUpload(file) {
      //文件类型
      const isType = file.type === 'application/vnd.ms-excel'
      const isTypeComputer = file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
      const fileType = isType || isTypeComputer
      if (!fileType) {
        this.$message.error('上传文件只能是xls/xlsx格式!')
      }
      // 文件大小限制为10M
      const fileLimit = file.size / 1024 / 1024 < 10
      if (!fileLimit) {
        this.$message.error('上传文件大小不超过10M!')
      }
      return fileType && fileLimit
    },
    // 自定义上传方法,param是默认参数,可以取得file文件信息,具体信息如下图
    uploadHttpRequest(param) {
      // const formData = new FormData() //FormData对象,添加参数只能通过append('key', value)的形式添加
      // formData.append('file', param.file) //添加文件对象
      // formData.append('uploadType', this.is_type) //接口要传的参数
      // // 调用接口api
      // importData(formData).then((data) => {
      //   if (data.code == 200) {
      //     this.msgSuccess('成功')
      //     param.onSuccess() // 上传成功的文件显示绿色的对勾
      //     this.fileList = []
      //     this.is_type = ''
      //   } else {
      //     this.msgError(data.msg)
      //   }
      // })
    },
    // 点击上传:手动上传到服务器,此时会触发组件的http-request
 submitUpload() {
      if (this.is_type && this.fileList) {
        // this.$refs.upload.submit()
        // console.log(this.formData)
        importData(this.formData).then((data) => {
          if (data.code == 200) {
            this.msgSuccess('成功')
            this.fileList = []//清空上传的文件展示列表
            this.is_type = ''
          this.$refs.upload.clearFiles()//清空已上传的文件列表(该方法不支持在 before-upload 中调用)
          } else {
            this.msgError(data.msg)
          }
        })
      } else if (this.is_type && this.fileList.length == 0) {
        this.msgError('请选择上传文件')
      } else if (!this.is_type && this.fileList.length != 0) {
        this.msgError('请选择导入模式')
      } else if (!this.is_type && this.fileList.length == 0) {
        this.msgError('请选择导入模式和上传文件')
      }
    },
    // 移除选择的文件
    fileRemove(file, fileList) {
      if (fileList.length < 1) {
        this.uploadDisabled = true //未选择文件则禁用上传按钮
      }
    },
    // 取消
    closeDialog() {
      this.$refs.upload.clearFiles() //清除上传文件对象
      this.fileList = [] //清空选择的文件列表
      this.$emit('close', false)
    },
    // 文件发生改变
    fileChange(file, fileList) {
      // if (fileList.length > 0) {
      //   this.fileList = [fileList[fileList.length - 1]] // 展示最后一次选择的文件
      // }
      // console.log(file)
      this.formData = {
        Name: ,
        IsType: this.is_type,
      }
      let files = { 0: file.raw }
      this.readExcel(files)
    },
    // 导入用XLSX读取文档
    readExcel(files) {
      var that = this
      // 如果没有⽂件名
      if (files.length <= 0) {
        return false
      } else if (!/\.(xls|xlsx)$/.test(files[0].name.toLowerCase())) {
        this.$Message.error('上传格式不正确,请上传xls或者xlsx格式')
        return false
      }
      const fileReader = new FileReader()
      fileReader.onload = (ev) => {
        try {
          const data = ev.target.result
          const workbook = XLSX.read(data, {
            type: 'binary',
          })
          // 取第⼀张表
          const wsname = workbook.SheetNames[0] //
          // ⽣成
          // 表格内容
          const ws = XLSX.utils.sheet_to_json(workbook.Sheets[wsname])
          console.log(ws, 'ws是表格⾥的数据,且是json格式')
          let list = ws.map((item) => {
            return {
              Coding: (item.物料编码)+'',
              Name: (item.物料名称)+'',
              Specification: (item.规格型号)+'',
              Units: (item.计量单位)+'',
              AllName: (item.全名)+'',
              ApplyNumber: (item.申请数量),
              AdjustNumber: (item.调剂后数量),
              Remark: (item.备注)+'',
            }
          })
          this.formData.BizMaterialSon = list
          // 重写数据
          this.$refs.upload.value = ''
        } catch (e) {
          return false
        }
      }
      fileReader.readAsBinaryString(files[0])
    },
  },
}
</script>
css:掺杂了一些其他的代码
<style scoped lang="scss">
.title {
  text-align: center;
  font-size: 70px;
  font-weight: 600;
}
.crenter {
  width: 450px;
  margin: 20px auto;
}
.select {
  position: relative;
}
.selectright {
  width: 450px;
  margin: 20px auto;
}
.selectLeft {
  width: 410px;
  position: absolute;
  left: 54%;
  top: 0;
}
.upload-demo {
  width: 100%;
}
.upImg {
  width: 150px;
  // height: 100px;
  margin: 10px auto;
}
</style>
<style scoped>
.upload-demo >>> .el-upload-dragger {
  border: none;
  height: 250px !important;
  width: 100%;
}
.box-card >>> .el-upload-dragger {
  border: none;
  height: 208px !important;
  width: 100%;
}
.-always-shadow {
  -webkit-box-shadow: 0 2px 12px 0 #f0f0f0;
  box-shadow: 0px -6px 20px 0 #f0f0f0;
  border: none;
}
.box-card >>> .el-upload {
  display: block !important;
}
.buttonUp {
  display: block;
  width: 140px;
  padding: 15px;
  border-radius: 5px;
  margin: 0px auto;
  margin-bottom: 10px;
}
.el-upload__tip {
  text-align: center;
  color: #a7a3a2;
  padding: 20px;
  box-shadow: 0px 4px 14px 0px #f0f0f0;
  margin-top: 0px;
}
</style>
整合:一整个页面里的代码,可以复制过去自己修改
<template>
  <div class="app-container home">
    <div style="padding-top: 30px">
      <div class="title">上传excel导入物料采购单</div>
      <div class="select">
        <div class="selectright">
          <el-form>
            <el-form-item label="导入模式">
              <el-select v-model="is_type" placeholder="请输入导入模式">
                <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"> </el-option>
              </el-select>
            </el-form-item>
          </el-form>
        </div>
        <div class="selectLeft">
          <span style="color: red">*</span>
          打包为整包、散包、单一来源;为整包时,填写价格时不可填写0,且每个都必填;为散包时,价格可填写为0。
        </div>
      </div>
      <div class="crenter">
        <div>
          <el-card class="box-card">
            <el-upload
              ref="upload"
              accept=".xls,.xlsx"
              action="#"
              :auto-upload="false"
              :multiple="false"
              :file-list="fileList"
              :before-upload="beforeUpload"
              :http-request="uploadHttpRequest"
              :on-remove="fileRemove"
              :on-change="fileChange"
              drag
            >
              <img class="upImg" src="../../style/img/up.png" alt="" />
              <el-button class="buttonUp" type="primary">上传excel</el-button>
              <div class="el-upload__text">或者拖放一个文件</div>
            </el-upload>
          </el-card>
          <div class="el-upload__tip">只能上传excel文件,且不超过500kb</div>
        </div>
        <div><el-button style="width: 450px; margin: 20px auto; padding: 15px" type="primary" @click="submitUpload">确认上传</el-button></div>
      </div>
    </div>
  </div>
</template>
<script>
import request from '@/utils/request'
import { getToken } from '@/utils/auth'
import { importData } from '@/api/purchase/purchase'
import XLSX from '../../../node_modules/xlsx'
export default {
  data() {
    return {
      options: [
        {
          value: 1,
          label: '整包',
        },
        {
          value: 2,
          label: '散包',
        },
        {
          value: 3,
          label: '单一来源',
        },
      ],
      is_type: '',
      action: process.env.VUE_APP_BASE_API + '/business/BizMaterialSum/importData',
      // 用户导入参数
      fileList: [],
      // 读取
      defaultIndex: 0, // 默认显示第一个工作表
      wb: null, // 工作表对象
      formData: {},
    }
  },
  created() {},
  methods: {
    beforeUpload(file) {
      //文件类型
      const isType = file.type === 'application/vnd.ms-excel'
      const isTypeComputer = file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
      const fileType = isType || isTypeComputer
      if (!fileType) {
        this.$message.error('上传文件只能是xls/xlsx格式!')
      }
      // 文件大小限制为10M
      const fileLimit = file.size / 1024 / 1024 < 10
      if (!fileLimit) {
        this.$message.error('上传文件大小不超过10M!')
      }
      return fileType && fileLimit
    },
    // 自定义上传方法,param是默认参数,可以取得file文件信息,具体信息如下图
    uploadHttpRequest(param) {
      // const formData = new FormData() //FormData对象,添加参数只能通过append('key', value)的形式添加
      // formData.append('file', param.file) //添加文件对象
      // formData.append('uploadType', this.is_type) //接口要传的参数
      // // 调用接口api
      // importData(formData).then((data) => {
      //   if (data.code == 200) {
      //     this.msgSuccess('成功')
      //     param.onSuccess() // 上传成功的文件显示绿色的对勾
      //     this.fileList = []
      //     this.is_type = ''
      //   } else {
      //     this.msgError(data.msg)
      //   }
      // })
    },
    // 点击上传:手动上传到服务器,此时会触发组件的http-request
    submitUpload() {
      if (this.is_type && this.fileList) {
        // this.$refs.upload.submit()
        // console.log(this.formData)
        importData(this.formData).then((data) => {
          if (data.code == 200) {
            this.msgSuccess('成功')
            this.fileList = []//清空上传的文件展示列表
            this.is_type = ''
          this.$refs.upload.clearFiles()//清空已上传的文件列表(该方法不支持在 before-upload 中调用)
          } else {
            this.msgError(data.msg)
          }
        })
      } else if (this.is_type && this.fileList.length == 0) {
        this.msgError('请选择上传文件')
      } else if (!this.is_type && this.fileList.length != 0) {
        this.msgError('请选择导入模式')
      } else if (!this.is_type && this.fileList.length == 0) {
        this.msgError('请选择导入模式和上传文件')
      }
    },
    // 移除选择的文件
    fileRemove(file, fileList) {
      if (fileList.length < 1) {
        this.uploadDisabled = true //未选择文件则禁用上传按钮
      }
    },
    // 取消
    closeDialog() {
      this.$refs.upload.clearFiles() //清除上传文件对象
      this.fileList = [] //清空选择的文件列表
      this.$emit('close', false)
    },
    // 文件发生改变
    fileChange(file, fileList) {
      // if (fileList.length > 0) {
      //   this.fileList = [fileList[fileList.length - 1]] // 展示最后一次选择的文件
      // }
      // console.log(file)
      this.formData = {
        Name: ,
        IsType: this.is_type,
      }
      let files = { 0: file.raw }
      this.readExcel(files)
    },
    // 导入用XLSX读取文档
    readExcel(files) {
      var that = this
      // 如果没有⽂件名
      if (files.length <= 0) {
        return false
      } else if (!/\.(xls|xlsx)$/.test(files[0].name.toLowerCase())) {
        this.$Message.error('上传格式不正确,请上传xls或者xlsx格式')
        return false
      }
      const fileReader = new FileReader()
      fileReader.onload = (ev) => {
        try {
          const data = ev.target.result
          const workbook = XLSX.read(data, {
            type: 'binary',
          })
          // 取第⼀张表
          const wsname = workbook.SheetNames[0] //
          // ⽣成
          // 表格内容
          const ws = XLSX.utils.sheet_to_json(workbook.Sheets[wsname])
          console.log(ws, 'ws是表格⾥的数据,且是json格式')
          let list = ws.map((item) => {
            return {
              Coding: (item.物料编码)+'',
              Name: (item.物料名称)+'',
              Specification: (item.规格型号)+'',
              Units: (item.计量单位)+'',
              AllName: (item.全名)+'',
              ApplyNumber: (item.申请数量),
              AdjustNumber: (item.调剂后数量),
              Remark: (item.备注)+'',
            }
          })
          this.formData.BizMaterialSon = list
          // 重写数据
          this.$refs.upload.value = ''
        } catch (e) {
          return false
        }
      }
      fileReader.readAsBinaryString(files[0])
    },
  },
}
</script>
<style scoped lang="scss">
.title {
  text-align: center;
  font-size: 70px;
  font-weight: 600;
}
.crenter {
  width: 450px;
  margin: 20px auto;
}
.select {
  position: relative;
}
.selectright {
  width: 450px;
  margin: 20px auto;
}
.selectLeft {
  width: 410px;
  position: absolute;
  left: 54%;
  top: 0;
}
.upload-demo {
  width: 100%;
}
.upImg {
  width: 150px;
  // height: 100px;
  margin: 10px auto;
}
</style>
<style scoped>
.upload-demo >>> .el-upload-dragger {
  border: none;
  height: 250px !important;
  width: 100%;
}
.box-card >>> .el-upload-dragger {
  border: none;
  height: 208px !important;
  width: 100%;
}
.-always-shadow {
  -webkit-box-shadow: 0 2px 12px 0 #f0f0f0;
  box-shadow: 0px -6px 20px 0 #f0f0f0;
  border: none;
}
.box-card >>> .el-upload {
  display: block !important;
}
.buttonUp {
  display: block;
  width: 140px;
  padding: 15px;
  border-radius: 5px;
  margin: 0px auto;
  margin-bottom: 10px;
}
.el-upload__tip {
  text-align: center;
  color: #a7a3a2;
  padding: 20px;
  box-shadow: 0px 4px 14px 0px #f0f0f0;
  margin-top: 0px;
}
</style>

页面图片:

vue element 下载表格数据函数_上传