前端上传文件前检测文件数据🔍

海军本部大佐-利刃队员-克比

前言

项目中的一个批量导入数据的需求,批量导入数据是用的 excel,需要前端上传 excel 文件时先将文件中的数据解析一下,然后根据业务需求对每一列的字段进行一些基础校验,如字段是否非空,字符串长度是否超出范围等等,接下来就来梳理一下这个需求的基本实现

思路分析

根据需求分析得到批量导入数据使用的 excel,上传前对 excel 文件中的数据做一些基础校验,可以上传前先将 excel 解析成 json,得到 json 数据后再根据 json 中的格式,进行按需校验

实战操作

准备导入文件

这里模拟了一个基本的 excel 数据,第一行是表头,下面是表体数据,模拟了三条数据,假设每列数据都是必填

构建上传组件

这里使用 elementel-upload 组件,设置组件的 change 事件 :on-change="handleChange" ,使文件发生变化时获取对应的 file 对象

html 复制代码
<el-upload
  class="upload-demo"
  drag
  action="https://jsonplaceholder.typicode.com/posts/"
  :file-list="fileList"
  :auto-upload="false"
  :on-change="handleChange"
>
  <i class="el-icon-upload"></i>
  <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
  <div class="el-upload__tip" slot="tip">只能上传excel文件</div>
</el-upload>

获取excel文件内容

通过 handleChange 事件得到 file 对象,根据 FileReader 读取文件内容

js 复制代码
handleChange(file) {
  if (file) {
    const reader = new FileReader();
    reader.onload = (e) => {
      // 读取 Excel 文件内容
      const data = e.target.result;
      // 处理 Excel 文件内容,获取表格数据
      this.processExcelData(data);
    };

    reader.readAsArrayBuffer(file.raw);
  }
}

注意!

reader.readAsArrayBuffer(file.raw); 里面传的参数是 file.rawfile.raw 才是 readAsArrayBuffer 需要的 blob 对象

处理excel获取json数据

这里使用 processExcelData() 函数解析 excel 表格数据,解析表格数据使用 xlsx 库,解析 excel 文件数据这里分为以下几个步骤

  1. 使用 String.fromCharCode.apply(null, new Uint8Array(data)) 得到文件二进制字符串
  2. 使用 XLSX.read(binaryString, { type: "binary" }) 将二进制字符串转成 workbook 对象
  3. 通过 worksheet 获取 worksheet
  4. 使用 XLSX.utils.sheet_to_json(worksheet, { header: 1 });worksheet 转为 json 对象
  5. 得到的 json 对象后进行数据解析,从第二行开始验证数据,判断每一行的每列数据是否为空,如果有数据,则进下一步,如果为空,则打印错误日志(需求场景中是如果出现校验错误应该限制上传操作)
js 复制代码
processExcelData(data) {
  const binaryString = String.fromCharCode.apply(
    null,
    new Uint8Array(data)
  );

  // 将二进制字符串转为workbook
  const workbook = XLSX.read(binaryString, { type: "binary" });

  // 获取第一个sheet
  const sheetName = workbook.SheetNames[0];
  const worksheet = workbook.Sheets[sheetName];

  // 将sheet转为json对象·
  const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1 });

  // 获取表头
  const titleList = jsonData[0];
  jsonData.forEach((item, index) => {
    if (index > 0) {
      for (let i = 0; i < titleList.length; i++) {
        if (item[i]) {
        } else {
          console.error("第 " + (index + 1) + " 行的第 " + (i + 1) + " 列 " + titleList[i] + " 为空");
        }
      }
    }
  });
},

到这里整个需求的最核心的部分在 Demo 中都已经实现了,剩下的就是业务场景中按需调整部分代码逻辑就行了

提示!

  1. 这里面的获取 sheet 时要基于实际业务情况, Demo 中默认是只有一个 sheet
  2. Demo 中的表头数据默认也是只有第一行

演示效果

简单说明一下这里面的操作逻辑,页面刷新后,打开控制台,选择 test.xlsx 文件,文件变化后查看控制台解析校验结果

技术栈

  • vue: 2.6.14
  • element ui: 2.15.14
  • xlsx: 0.17.0

Demo地址

完整代码

github.com/gywgithub/F...

Excel测试文件

github.com/gywgithub/F...

写在最后

关于这种比较通用的文件上传或者文件解析功能,在项目里适合基于业务封装成通用的组件或函数,在未来类似的需求中可以相对快速完成相关功能

关于文件解析校验,还有更优雅的实现思路吗?

欢迎大家讨论交流,如果喜欢本文章或感觉文章有用,用你那发财的小手点赞、收藏再走呗 ^_^

微信公众号:草帽Lufei

相关推荐
Boilermaker199227 分钟前
【Java EE】SpringIoC
前端·数据库·spring
中微子39 分钟前
JavaScript 防抖与节流:从原理到实践的完整指南
前端·javascript
天天向上10241 小时前
Vue 配置打包后可编辑的变量
前端·javascript·vue.js
芬兰y1 小时前
VUE 带有搜索功能的穿梭框(简单demo)
前端·javascript·vue.js
好果不榨汁1 小时前
qiankun 路由选择不同模式如何书写不同的配置
前端·vue.js
小蜜蜂dry1 小时前
Fetch 笔记
前端·javascript
拾光拾趣录1 小时前
列表分页中的快速翻页竞态问题
前端·javascript
小old弟1 小时前
vue3,你看setup设计详解,也是个人才
前端
Lefan1 小时前
一文了解什么是Dart
前端·flutter·dart
Patrick_Wilson1 小时前
青苔漫染待客迟
前端·设计模式·架构