Vue+Element项目的批量导入组件封装.md 4.29 KB
Newer Older
liyan's avatar
liyan committed
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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
---
title: Vue+Element项目的批量导入组件封装           
date: 2022/6/30 18:42:20
tags:                    
- 前端
- 批量导入
- JavaScript             
author: 李燕         
---

Excel导入、Excel导出是一对好兄弟,经常成双成对出现。所以,在封装了Excel导出方法 —— 《用xlsx-style玩转Excel导出——拿走即用的Excel导出方法封装》后,今天我们来封装一下Excel导入。

Excel导入的封装和Excel导出的封装不太一样,Excel导出是纯js封装的,但是Excel导入的封装可能是组件级别的封装。

<!-- more -->

**一、 安装依赖**
 
 
在正式开始封装之前,我们需要先安装xlsx。这个插件,能够方面我们将导入的文件,处理成我们需要的数据。

```js
npm install -S xlsx
```
安装后,在需要使用的地方引入即可。

```js
import XLSX from 'xlsx'
```

**二、上传文件**

因所做的涉及到Excel批量导入的项目,都是基于Vue+Element的,所以直接选用了Element的el-upload组件实现文件上传功能,如下:

```js
// BatchImport.vue

<template>

  <el-upload
  action="#"
  accept=".xls,.xlsx"
  :show-file-list="false"
  :auto-upload="true"
  :multiple="false"
  :http-request="handleBatchImport"
>
  <el-button size="small" type="primary">批量导入</el-button>
 </el-upload>

</template>

```

**三、处理文件**

文件上传后,我们获取到导入的Excel文件,然后进行如下处理:
+  通过new FileReader()读取文件
+ 将读取结果通过XLSX.read()方法转换成工作簿对象
+ 处理工作簿对象,获取有效的目标数据

```js
// BatchImport.vue

<script>
import XLSX from 'xlsx'
  export default { 
    name: 'BatchImport',
    methods: {
      handleBatchImport(file) {
        const that = this
        // 通过FileReader对象读取文件
        const fileReader = new FileReader();
        fileReader.onload = (event) => { 
          try {
            const { result } = event.target;
            // 以二进制流方式读取得到整份excel表格对象
            const workbook = XLSX.read(result, { type: "binary" });
            // 存储获取到的数据
            const excelData = {};
            // 遍历获取每张工作表 除去隐藏表
            const allSheets = workbook.Workbook.Sheets;
            allSheets.forEach( item => {
              const name = item.name;
              if (workbook.Sheets.hasOwnProperty(name) && item.Hidden === 0) {
                // 利用 sheet_to_json 方法将 excel 转成 json 数据
                const data = [].concat(
                  XLSX.utils.sheet_to_json(workbook.Sheets[name])
                ); 
                // 处理表格有效内容后面的空格行,获得有效数据  
                excelData[name] = that.handleEmptyRow(data)
              }
            })
            //将excelData暴露出去
            that.$emit('importExcel', excelData)
          } catch(e) {
            that.$message.error('文件上传错误!')
            that.$emit('importExcel', null)
            return false
          }
        }
        //以二进制方式打开文件
        fileReader.readAsBinaryString(file.file);
      },
    
      // 处理表格空行问题
      handleEmptyRow(data) {
        // 去除最后的空格行
        for (let i = data.length - 1; i >= 0; i--) {
          // 判断数组是否全为空
          const flag = Object.values(data[i]).find((item) => {
            return String(item).replace(/(^s*)|(s*$)/g, '').length
          })
          if (!flag) {
            data.splice(i, 1)
          } else {
            break
          }
        }
        return data
      },
    }
  }
</script>
```

**四、处理数据**

经过上述步骤,我们获取到目标数据,接下来,在父组件里对数据进行进一步处理和操作。


```js
// Father.vue

<template>
  <batch-import @importExcel="importExcel"></batch-import>
</template>

<script>
import BatchImport from './BatchImport.vue'
  export default { 
    components: {
      BatchImport,
    },
    methods: {
      importExcel(excelData) {
        ...
    
      }
    }
  }
</script>

```
因数据具体如何处理,需要根据项目需求和后端要求而定,所以未将数据在BatchImport组件内进行处理,而是选择暴露出来在父组件内处理。