Vue中使用el-upload+XLSX实现解析excel文件为json数据

场景

业务要求为实现每天上报各部门计划人数,需要通过excel导入数据。

前端可以解析excel数据并进行初步的格式校验。

导入成功之后解析的数据

excel里的数据为

注:

博客:
https://blog.csdn.net/badao_liumang_qizhi 
关注公众号
霸道的程序猿
获取编程相关电子书、教程推送与免费下载。

实现

npm安装以及注意事项

npm i xlsx@0.16.8

这里是指定版本安装的,一开始未指定版本,安装之后提示如下两个问题

Failed to execute 'readAsBinaryString' on 'FileReader': parameter 1 is not of type 'Blob'

 Cannot read property 'read' of undefined
    at FileReader.reader

代码实现流程

首先在页面中引入

import XLSX from "xlsx";

然后页面添加el-upload

    <el-upload
      ref="upload"
      :limit="1"
      accept=".xlsx, .xls"
      :headers="headers"
      :action="upLoadUrl + '?planDateString=' + this.planDate"
      :disabled="isUploading"
      :on-progress="handleFileUploadProgress"
      :on-success="handleFileSuccess"
      :auto-upload="false"
      :before-upload="beforeUpload"
      drag
    >
      <i class="el-icon-upload"></i>
      <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
      <div class="el-upload__tip text-center" slot="tip">
        <span>仅允许导入xls、xlsx格式文件。</span>
      </div>
    </el-upload>

设置其before-upload属性,上传文件之前的钩子,参数为上传的文件,若返回false或者

返回Promise且被reject则停止上传。

实现其bofore-upload

    //上传文件之前的钩子
    beforeUpload(file) {
      //解析excel
      this.analysisExcel(file).then((tableJson) => {
        if (tableJson && tableJson.length > 0) {
          //成功解析出数据
          //只取第一个sheet的数据
          let dataExcel = tableJson[0];
          console.log("数据", dataExcel);
          console.log(JSON.stringify(dataExcel.sheet));
        }
      });
    },
    //解析excel
    analysisExcel(file) {
      return new Promise(function (resolve, reject) {
        const reader = new FileReader();
        reader.onload = function (e) {
          const data = e.target.result;
          let datajson = XLSX.read(data, {
            type: "binary",
          });
          const result = [];
          datajson.SheetNames.forEach((sheetName) => {
            result.push({
              sheetName: sheetName,
              sheet: XLSX.utils.sheet_to_json(datajson.Sheets[sheetName]),
            });
          });
          resolve(result);
        };
        reader.readAsBinaryString(file);
      });
    },

完整示例代码

<template>
  <!-- 用户导入对话框 -->
  <el-dialog :title="title" :visible.sync="open" width="400px" append-to-body>
    <div class="block">
      <span class="demonstration">计划日期: </span>
      <el-date-picker
        v-model="planDate"
        type="date"
        placeholder="选择计划日期"
        size="small"
        value-format="yyyy-MM-dd"
      >
      </el-date-picker>
    </div>
    <br />
    <el-upload
      ref="upload"
      :limit="1"
      accept=".xlsx, .xls"
      :headers="headers"
      :action="upLoadUrl + '?planDateString=' + this.planDate"
      :disabled="isUploading"
      :on-progress="handleFileUploadProgress"
      :on-success="handleFileSuccess"
      :auto-upload="false"
      :before-upload="beforeUpload"
      drag
    >
      <i class="el-icon-upload"></i>
      <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
      <div class="el-upload__tip text-center" slot="tip">
        <span>仅允许导入xls、xlsx格式文件。</span>
      </div>
    </el-upload>
    <div slot="footer" class="dialog-footer">
      <el-button type="primary" @click="submitFileForm">确 定</el-button>
      <el-button @click="open = false">取 消</el-button>
    </div>
  </el-dialog>
</template>

<script>
import { getToken } from "@/utils/auth";
import XLSX from "xlsx";
import moment from "moment";

export default {
  data() {
    return {
      // 是否显示弹出层(用户导入)
      open: false,
      // 弹出层标题(用户导入)
      title: "",
      // 是否禁用上传
      isUploading: false,
      //计划日期
      planDate: new Date(),
      // 设置上传的请求头部
      headers: { Authorization: "Bearer " + getToken() },
      // 上传的地址
      upLoadUrl: "",
    };
  },
  mounted() {
    //默认计划日期为明天
    this.planDate = moment().subtract(-1, "days").format("YYYY-MM-DD");
  },
  methods: {
    /** 导入按钮操作 */
    handleImport(data) {
      this.title = data.title;
      this.upLoadUrl = process.env.VUE_APP_BASE_API + data.upLoadUrl;
      this.open = true;
    },
    // 提交上传文件
    submitFileForm() {
      this.$refs.upload.submit();
    },
    // 文件上传中处理
    handleFileUploadProgress() {
      this.isUploading = true;
    },
    // 文件上传成功处理
    handleFileSuccess(response) {
      this.open = false;
      this.isUploading = false;
      this.$refs.upload.clearFiles();
      this.$alert(
        "<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" +
          response.msg +
          "</div>",
        "导入结果",
        { dangerouslyUseHTMLString: true }
      );
      //上传数据成功后重新请求数据
      this.$emit("getList");
    },
    //上传文件之前的钩子
    beforeUpload(file) {
      //解析excel
      this.analysisExcel(file).then((tableJson) => {
        if (tableJson && tableJson.length > 0) {
          //成功解析出数据
          //只取第一个sheet的数据
          let dataExcel = tableJson[0];
          console.log("数据", dataExcel);
          console.log(JSON.stringify(dataExcel.sheet));
        }
      });
    },
    //解析excel
    analysisExcel(file) {
      return new Promise(function (resolve, reject) {
        const reader = new FileReader();
        reader.onload = function (e) {
          const data = e.target.result;
          let datajson = XLSX.read(data, {
            type: "binary",
          });
          const result = [];
          datajson.SheetNames.forEach((sheetName) => {
            result.push({
              sheetName: sheetName,
              sheet: XLSX.utils.sheet_to_json(datajson.Sheets[sheetName]),
            });
          });
          resolve(result);
        };
        reader.readAsBinaryString(file);
      });
    },
  },
};
</script>

<style>
</style>

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
使用Element UI的el-upload组件上传Excel文件并预览可以分为以下几个步骤: 1. 安装Element UI和xlsx依赖。在命令行执行以下命令: ``` npm install element-ui xlsx --save ``` 2. 在Vue组件引入Element UI和xlsx。例如: ```javascript import { ElUpload, ElButton } from 'element-ui'; import XLSX from 'xlsx'; ``` 3. 在Vue组件使用el-upload组件创建文件上传并预览的功能。例如: ```html <template> <el-upload class="upload-demo" action="" :on-change="handleFileUpload" :before-upload="beforeUpload" :file-list="fileList" :auto-upload="false" :accept=".xlsx, .xls" :show-file-list="false"> <el-button size="small" type="primary">点击上传</el-button> <div slot="tip" class="el-upload__tip">只能上传Excel文件</div> </el-upload> <table> <thead> <tr> <th v-for="header in headers" :key="header">{{ header }}</th> </tr> </thead> <tbody> <tr v-for="(row, index) in data" :key="index"> <td v-for="(value, key) in row" :key="key">{{ value }}</td> </tr> </tbody> </table> </template> ``` 4. 在Vue组件定义beforeUpload方法,用于限制只能上传Excel文件。例如: ```javascript beforeUpload(file) { const fileType = file.name.split('.').pop(); if (fileType !== 'xlsx' && fileType !== 'xls') { this.$message.error('只能上传Excel文件'); return false; } } ``` 5. 在Vue组件定义handleFileUpload方法,用于处理上传Excel文件。例如: ```javascript handleFileUpload(file) { const reader = new FileReader(); reader.onload = (e) => { const data = e.target.result; const workbook = XLSX.read(data, { type: 'binary' }); const sheetName = workbook.SheetNames[0]; const sheet = workbook.Sheets[sheetName]; const jsonData = XLSX.utils.sheet_to_json(sheet, { header: 1 }); this.headers = jsonData[0]; this.data = jsonData.slice(1); }; reader.readAsBinaryString(file.raw); } ``` 6. 在Vue组件定义fileList、headers和data变量,用于存储上传Excel文件信息和解析后的数据。例如: ```javascript data() { return { fileList: [], headers: [], data: [] }; } ``` 7. 根据需要自定义样式和其他功能。例如: ```css .upload-demo { margin-top: 20px; width: 100%; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

霸道流氓气质

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值