vue上传excel

这是一个关于如何在Vue.js应用中实现Excel文件上传并预览的示例。代码使用了xlsx库来解析Excel文件,限制了上传文件的数量和大小,并在上传后显示数据到表格中。此外,还提供了取消和确认操作。

参考https://blog.youkuaiyun.com/qq_34462220/article/details/108741345

在原基础上进行了改进

npm install xlsx -s
<!--
 * @Author: zhang_gen_yuan
 * @Date: 2021-01-24 14:32:25
 * @LastEditTime: 2021-01-24 19:25:28
 * @Descripttion: 
-->
<template>
  <div>
    <!--  excel表格上传  -->
    <el-upload
      class="upload-demo"
      drag
      action="https://jsonplaceholder.typicode.com/posts/"
      multiple
      accept=".xlsx"
      :on-exceed="exceed"
      :limit="1"
      :on-remove="remove"
      :http-request="uploadFile"
    >
      <i class="el-icon-upload"></i>
      <div class="el-upload__text">
        将文件拖到此处,或
        <em>点击上传</em>
      </div>
      <div class="el-upload__tip" slot="tip">
        1次只能上传1个xls文件,且不超过500kb
      </div>
    </el-upload>
    <!--  上传的excel表格预览  -->
    <div class="preview-excel">
      <el-table
        class="listTable_ele"
        v-show="listTable.length != 0"
        :data="listTable"
        stripe
        height="250"
        style="width: 100%"
      >
        <el-table-column
          prop="name"
          label="姓名"
          width="200"
          align="center"
        ></el-table-column>
        <el-table-column
          prop="age"
          label="年龄"
          width="200"
          align="center"
        ></el-table-column>
        <el-table-column
          prop="city"
          label="城市"
          width="200"
          align="center"
        ></el-table-column>
        <el-table-column
          prop="sno"
          label="学号"
          width="200"
          align="center"
        ></el-table-column>
      </el-table>
    </div>
  </div>
</template>
 
<script>
import XLSX from "xlsx"; //引入xlsx
export default {
  data() {
    return {
      listTable: [],
    };
  },
  methods: {
    //解析excel
    async uploadFile(params) {
      const _file = params.file;
      const fileReader = new FileReader();
      fileReader.onload = (ev) => {
        try {
          const data = ev.target.result;
          const workbook = XLSX.read(data, {
            type: "binary",
          });
          for (let sheet in workbook.Sheets) {
            //循环读取每个文件
            const sheetArray = XLSX.utils.sheet_to_json(workbook.Sheets[sheet]);
            //若当前sheet没有数据,则continue
            if (sheetArray.length == 0) {
              continue;
            }
            console.log("读取文件");
            console.log(sheetArray);
            for (let item in sheetArray) {
              let rowTable = Object.assign(
                {},
                {
                  name: sheetArray[item].姓名,
                  age: sheetArray[item].年龄,
                  city: sheetArray[item].城市,
                  sno: sheetArray[item].学号,
                }
              );
              this.listTable.push(rowTable);
            }
            this.listTable = this.listTable.filter((item) => item.name);
            console.log(this.listTable, "1sacsdjbcjsd");
          }
        } catch (e) {
          this.$message.warning("文件类型不正确!");
        }
      };
      fileReader.readAsBinaryString(_file);
    },
    //上传1个以上文件时弹窗提示错误
    exceed: function () {
      this.$message.error("最多只能上传1个xls文件");
    },
    //删除文件
    remove() {
      this.listTable = [];
    },
  },
};
</script>

在这里插入图片描述

ts版本

<!--
 * @Author: zhang_gen_yuan
 * @Date: 2021-01-24 14:32:25
 * @LastEditTime: 2021-01-25 17:54:31
 * @Descripttion: 
-->
<template>
  <div>
    <!--  excel表格上传  -->
    <el-upload
      class="upload-demo"
      drag
      action="https://jsonplaceholder.typicode.com/posts/"
      multiple
      accept=".xlsx"
      :on-exceed="exceed"
      :limit="1"
      :on-remove="remove"
      :http-request="uploadFile"
    >
      <i class="el-icon-upload"></i>
      <div class="el-upload__text">
        将文件拖到此处,或
        <em>点击上传</em>
      </div>
      <div class="el-upload__tip">1次只能上传1个xls文件,且不超过500kb</div>
    </el-upload>
    <!--  上传的excel表格预览  -->
    <div class="preview-excel">
      <el-table
        class="listTable_ele"
        v-show="listTable.length != 0"
        :data="listTable.listTable"
        stripe
        height="250"
        style="width: 100%"
      >
        <el-table-column
          prop="name"
          label="姓名"
          width="200"
          align="center"
        ></el-table-column>
        <el-table-column
          prop="age"
          label="年龄"
          width="200"
          align="center"
        ></el-table-column>
        <el-table-column
          prop="city"
          label="城市"
          width="200"
          align="center"
        ></el-table-column>
        <el-table-column
          prop="sno"
          label="学号"
          width="200"
          align="center"
        ></el-table-column>
      </el-table>
    </div>
  </div>
</template>
 
<script lang="ts">
import { defineComponent, reactive } from "vue";
import XLSX from "xlsx"; //引入xlsx
interface ListTable {
  name: string;
  age: number;
  city: string;
  sno: string;
}
interface ListTable2 {
  姓名: string;
  年龄: number;
  城市: string;
  学号: string;
}
export default defineComponent({
  setup() {
    let listTable = reactive({
      listTable: new Array<ListTable>(),
    });
    //解析excel
    let uploadFile = async (params: { file: any }) => {
      const _file = params.file;
      const fileReader = new FileReader();
      fileReader.onload = (ev: any): void => {
        try {
          const data = ev.target.result;
          const workbook = XLSX.read(data, {
            type: "binary",
          });
          for (let sheet in workbook.Sheets) {
            //循环读取每个文件
            const sheetArray: Array<ListTable2> = XLSX.utils.sheet_to_json(
              workbook.Sheets[sheet]
            );
            //若当前sheet没有数据,则continue
            if (sheetArray.length == 0) {
              continue;
            }
            console.log("读取文件");
            console.log(sheetArray);
            for (let item in sheetArray) {
              let rowTable: ListTable = Object.assign(
                {},
                {
                  name: sheetArray[item].姓名,
                  age: sheetArray[item].年龄,
                  city: sheetArray[item].城市,
                  sno: sheetArray[item].学号,
                }
              );
              listTable.listTable.push(rowTable);
            }
            listTable.listTable = listTable.listTable.filter(
              (item) => item.name
            );
            console.log(listTable.listTable, "1sacsdjbcjsd");
          }
        } catch (e) {
          // this.$message.warning("文件类型不正确!");
        }
      };
      fileReader.readAsBinaryString(_file);
    };
    //上传1个以上文件时弹窗提示错误
    let exceed = (): void => {
      // this.$message.error("最多只能上传1个xls文件");
    };
    //删除文件
    let remove = (): void => {
      listTable.listTable = [];
    };
    return {
      listTable,
      uploadFile,
      remove,
      exceed,
    };
  },
});
</script>

做成一个弹框组件

<!--
 * @Author: zhang_gen_yuan
 * @Date: 2021-01-24 14:32:25
 * @LastEditTime: 2021-01-28 15:51:31
 * @Descripttion: 
-->
<template>
  <el-dialog
    title="导入"
    :visible.sync="exportExcelBoolean"
    width="60%"
    center
    :show-close="!exportExcelBoolean"
    :close-on-click-modal="!exportExcelBoolean"
  >
    <div class="export_Excel">
      <!--  excel表格上传  -->
      <el-upload
        v-if="listTable.length == 0"
        class="upload-demo"
        drag
        action="https://jsonplaceholder.typicode.com/posts/"
        multiple
        accept=".xlsx"
        :on-exceed="exceed"
        :limit="1"
        :on-remove="remove"
        :http-request="uploadFile"
      >
        <i class="el-icon-upload"></i>
        <div class="el-upload__text">
          将文件拖到此处,或
          <em>点击上传</em>
        </div>
        <div class="el-upload__tip" slot="tip">
          1次只能上传1个xls文件,且不超过500kb
        </div>
      </el-upload>
    </div>
     <!--  上传的excel表格预览  -->
      <div class="preview-excel">
        <el-table
          class="listTable_ele"
          v-show="listTable.length != 0"
          :data="listTable"
          stripe
          height="300"
          style="width: 100%"
        >
          <el-table-column
            prop="name"
            label="姓名"
            align="center"
          ></el-table-column>
          <el-table-column
            prop="age"
            label="年龄"
            align="center"
          ></el-table-column>
          <el-table-column
            prop="city"
            label="城市"
            align="center"
          ></el-table-column>
          <el-table-column
            prop="sno"
            label="学号"
            align="center"
          ></el-table-column>
        </el-table>
      </div>
    <span slot="footer" class="dialog-footer">
      <el-button @click="exportExcelDialogCancal">取 消</el-button>
      <el-button type="primary" @click="exportExcelDialogConfirm"
        >确 定</el-button
      >
    </span>
  </el-dialog>
</template>
 
<script>
import XLSX from "xlsx"; //引入xlsx
export default {
  props:{exportExcelBoolean:Boolean},
  data() {
    return {
      listTable: [],
    };
  },
  methods: {
    //取消按钮
    exportExcelDialogCancal(){
      this.$emit('exportExcelDialogBool');
      this.listTable = [];
    },

    //确定按钮
    exportExcelDialogConfirm(){
       //此处调接口   把数据  -- this.listTable  --传给后台 ,  返回成功 调用exportExcelDialogCancal()方法 
       alert("此处调接口")
    },
    //解析excel
    async uploadFile(params) {
      const _file = params.file;
      const fileReader = new FileReader();
      fileReader.onload = (ev) => {
        try {
          const data = ev.target.result;
          const workbook = XLSX.read(data, {
            type: "binary",
          });
          for (let sheet in workbook.Sheets) {
            //循环读取每个文件
            const sheetArray = XLSX.utils.sheet_to_json(workbook.Sheets[sheet]);
            //若当前sheet没有数据,则continue
            if (sheetArray.length == 0) {
              continue;
            }
            for (let item in sheetArray) {
              let rowTable = Object.assign(
                {},
                {
                  name: sheetArray[item].姓名,
                  age: sheetArray[item].年龄,
                  city: sheetArray[item].城市,
                  sno: sheetArray[item].学号,
                }
              );
              this.listTable.push(rowTable);
            }
            this.listTable = this.listTable.filter((item) => item.name);
          }
        } catch (e) {
          this.$message.warning("文件类型不正确!");
        }
      };
      fileReader.readAsBinaryString(_file);
    },
    //上传1个以上文件时弹窗提示错误
    exceed: function () {
      this.$message.error("最多只能上传1个xls文件");
    },
    //删除文件
    remove() {
      this.listTable = [];
    },
  },
};
</script>

<style lang="scss" scope>
</style>


<think>好的,我现在需要在Ant Design Vue中实现Excel文件上传功能。首先,我应该查阅相关的文档和示例代码,看看有没有现成的解决方案。根据用户提供的引用内容,特别是引用[3]和引用[4],里面提到了使用a-upload组件以及手动上传的方法。 首先,我需要确认Ant Design Vue上传组件a-upload的基本用法。引用[3]提到,手动上传需要设置customRequest属性,并处理beforeUpload钩子。这可能涉及到阻止自动上传,然后通过自定义函数处理文件。例如,在beforeUpload中返回false可以停止自动上传,转而使用自定义的上传逻辑。 然后,用户需要上传Excel文件,所以在上传组件中应该设置accept属性为.xlsx,.xls,如引用[4]中的示例代码所示。此外,还需要处理文件上传后的解析,可能需要使用xlsx库来读取文件内容。 接下来,我需要考虑如何在Vue组件中实现这一功能。可能需要引入xlsx库,并在上传文件的回调函数中,使用FileReader来读取文件内容,然后解析为JSON数据。引用[4]中的代码展示了如何使用beforeUpload来处理文件,并在那里进行解析。 另外,引用[5]提到了文件上传时的beforeUpload和change事件的处理,可能需要在这些事件中处理文件的状态,比如限制文件类型、大小,或者更新文件列表的显示。 现在,我需要将这些部分整合起来。首先,在模板中使用a-upload组件,设置accept、beforeUpload、customRequest等属性。然后,在beforeUpload中处理文件的读取和解析,可能使用xlsx库将Excel数据转换为JSON。最后,通过customRequest将解析后的数据发送到后端接口。 需要注意的是,可能需要处理上传过程中的各种状态,比如上传成功或失败时的反馈,以及文件列表的更新。引用[2]中提到,当文件作为参数上传到接口时出错,可能需要检查自定义上传函数是否正确处理了文件对象,比如是否将文件转换为FormData或正确的格式。 最后,确保代码中的依赖项正确安装,比如xlsx库,并在组件中正确引入。同时,测试上传功能是否正常工作,包括文件选择、解析和发送到后端的过程。</think>在Ant Design Vue中实现Excel文件上传功能,可通过以下步骤实现: ### 一、基础组件配置 ```vue <template> <a-upload name="excelFile" accept=".xls,.xlsx" :multiple="false" :before-upload="beforeUpload" :showUploadList="false" :customRequest="handleUpload" > <a-button type="primary"> <upload-outlined></upload-outlined> 选择Excel文件 </a-button> </a-upload> </template> ``` ### 二、核心实现逻辑 1. **安装依赖**: ```bash npm install xlsx ``` 2. **文件解析方法**: ```javascript import { read, utils } from 'xlsx' methods: { beforeUpload(file) { const reader = new FileReader() reader.onload = (e) => { const data = new Uint8Array(e.target.result) const workbook = read(data, { type: 'array' }) const firstSheet = workbook.Sheets[workbook.SheetNames[0]] const jsonData = utils.sheet_to_json(firstSheet) this.$emit('parse-success', jsonData) // 触发解析完成事件 } reader.readAsArrayBuffer(file) return false // 阻止自动上传[^3] }, handleUpload({ file }) { const formData = new FormData() formData.append('file', file) // 调用后端接口示例 axios.post('/api/upload', formData) .then(response => { console.log('上传成功:', response) }) .catch(error => { console.error('上传失败:', error) }) } } ``` ### 三、关键功能说明 1. **文件限制**: - `accept=".xls,.xlsx"` 限制只能选择Excel文件[^4] - `:multiple="false"` 禁止多选文件 2. **解析流程**: - 通过`FileReader`读取文件二进制数据 - 使用`xlsx`库将Excel转换为JSON数据 - 触发自定义事件传递解析结果 3. **上传控制**: - `customRequest`覆盖默认上传行为 - 使用FormData封装文件数据[^2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值