前端 读取/导入 Excel文档

情况: 需要通过Excel表,将数据导入到数据库,但是后台人员出差了,我又只会PHP,没用过node,所以只能前端导入Excel文件,然后循环调用后台的单条添加接口了。

库: Excel.js(版本4.3.0)

CDN地址:

<script src="https://cdn.bootcdn.net/ajax/libs/exceljs/4.3.0/exceljs.min.js"></script>

Excel.js 中文文档:https://gitee.com/alan_scut/exceljs

下面是动态Excel表单

在这里插入图片描述

下面是file文件(Excel文件)获取到的对象:

在这里插入图片描述

下面是代码中输出的需要插入的数据:

在这里插入图片描述

代码:

使用方法: importExcal()

// 全局函数执行完成后执行组件的钩子函数、组件事件、自定义事件

// 导入Excel表
async function importExcal() {
  // 文件内容 (这里是从input file里面获取到的内容)
  var file = input_file;
  // 提交后端数据的整体数组
  var data_arr = [];
  // 行程的最大列数(包含前面不变的)
  var stay_col_num = 0;

  if (file) {
    // 判断文件类型
    let filetype = file.name.split('.')[file.name.split('.').length - 1]
    let filetypes = '.xlsx,.xls'
    if (filetypes.indexOf(filetype) === -1) {
	    this.$message({
			message: '请上传 .xlsx 或 .xls 文件。',
			type: 'warning'
		})
      return;
    }
    // 读取文件文件
    const reader = new FileReader();

    // file.raw是具体的文件内容,需要看一下你获取到的是file.raw,还是file[0]即可 将文件转为 ArrayBuffer 格式
    console.log("这里是获取到的file文件内容:", file)
    // 这里要用 readAsArrayBuffer 转成buffer,因为下面读取要用到 buffer 才可以
    reader.readAsArrayBuffer(file.raw);
    reader.onload = function (event) {
      try {
        const result = event.target.result;
        var workbook = new ExcelJS.Workbook();
        // 读取 buffer 内容
        workbook.xlsx.load(result)
          .then(async function () {
            // 迭代所有sheet (如果只有一个,可以通过名称获取 var worksheet = workbook.getWorksheet('My Sheet');)
            workbook.eachSheet(async function (worksheet, sheetId) {
              // 清空数据数组
              data_arr = [];
              // 获取 形成安排 的列数(从第8列开始的), 总不会超过100天,所以写个100
              // 在这里获取 形成列的长度,是因为这里是表头,不会像内容一样出现空白单元格,造成无法获取到最终列的情况
              for (let j = 8; j <= 100; j++) {
                // 当列到 行程安排 且,j+1 不是 行程安排的时候,就是行程安排的列宽
                if (worksheet.getCell(`${getLetter(j)}2`).value == '行程安排' && worksheet.getCell(`${getLetter(j + 1)}2`).value !== '行程安排') {
                  stay_col_num = j;
                  // 如果两个都有值的话,就跳出循环
                  break;
                }
              }
              // 迭代工作表中具有值的所有行
              worksheet.eachRow(function (row, rowNumber) {
                // 数据是从第四行开始
                if (rowNumber >= 4) {
                  // data_arr.push(row.values)
                  // 每行的数据
                  let row_data = row.values;
                  // 传给后端的对象
                  let data_obj = {
                    "guest": "",
                    "name": "",
                    "sex": "",
                    "company": "",
                    "job": "",
                    "phone": "",
                    "stay": []
                  }

                  // 循环每行的数据
                  row_data.map(function (item, index, arr) {
                    // 如果是前7列,则是固定列的值,直接复制即可,否则的话则是 动态的行程安排
                    if (index <= 7) {
                      switch (index) {
                        case 2:
                          // 嘉宾类别
                          data_obj.guest = item ? item : "";
                          break;
                        case 3:
                          // 姓名
                          data_obj.name = item ? item : "";
                          break;
                        case 4:
                          // 性别
                          data_obj.sex = item ? item : "";
                          break;
                        case 5:
                          // 单位
                          data_obj.company = item ? item : "";
                          break;
                        case 6:
                          // 职务
                          data_obj.job = item ? item : "";
                          break;
                        case 7:
                          // 手机号
                          data_obj.phone = item ? item : "";
                          break;
                      }
                    } else {
                      // 行程安排(从第八列开始到形成的最后一列结束)
                      if (index >= 8 && index <= stay_col_num) {
                        if (worksheet.getCell(`${getLetter(index)}${rowNumber}`).value == '是') data_obj.stay.push(worksheet.getCell(`${getLetter(index)}3`).value);
                      }
                    }
                  })
                  // 将插入后台的数据添加进数组
                  data_arr.push(data_obj);
                }
              });
              console.log("全部需要插入数据库的数据的数组:", data_arr)
              // 这里使用了 Promise 解决在for循环内,使异步接口,进行同步提交的问题;文章后面有详细说明
              for (let i = 0; i < data_arr.length; i++) {
                let result_data = await createUser(data_arr[i]);
                if (!result_data.result) {
					// 如果出错,就跳出循环
					this.$message({
						message: `${i + 1} 行数据 ${data_arr[i].name}(${data_arr[i].phone}),由于 ${result_data.msg} 导入失败`,
						type: 'error'
					})
					// 跳出循环
                	break;
                }
              }
            });
          });
      } catch (err) {
      	this.$message({
			message: '读取文件错误',
			type: 'error'
		})
        console.log('err', err);
      }
    };
  } else {
  	this.$message({
		message: '请选择文件',
		type: 'error'
	})
  }
}

// 添加用户信息接口
async function createUser(data) {
  return await new Promise(function (resolve, reject) {
    // 处理异步逻辑时候调用resolve和reject函数
    axios({
      method: 'POST',
      url: `${base_url}/api/add`,
      headers: {
        // 没有可以不要token
        // authorization: `bearer ${token}`
      },
      // 数据
      data: data
    }).then(res => {
      let resp = res.data;
      if (resp.code == 1) {
        if (resp.data.code == 200) {
          resolve({
            "result": true
          });
        }
      } else {
        resolve({
          "result": false,
          "msg": resp.msg
        });
      }
    }).catch(req => {
      reject({
        "result": false,
        "msg": ""
      });
    });
  });
}

// 获取第N个字母
function getLetter(num) {
  return String.fromCharCode(64 + num);
}

代码中用到的方法总结:

新建工作簿

var workbook = new ExcelJS.Workbook();

读取 buffer 内容

workbook.xlsx.load(data).then(function() {
// 其他代码
});

迭代所有sheet

workbook.eachSheet(function(worksheet, sheetId) {
// 其他代码
});

按名称获取表格

var worksheet = workbook.getWorksheet(‘My Sheet’);

按ID获取表格

var worksheet = workbook.getWorksheet(1);

迭代工作表中具有值的所有行

worksheet.eachRow(function(row, rowNumber) {
console.log(‘Row:’ + rowNumber + ’ = ’ + JSON.stringify(row.values));
});

获取单元格(A2)

var collectcell = worksheet.getCell(‘A2’);

for循环内,使异步接口变成同步提交
我文章的地址:前端JS for循环内异步接口变成同步提交(JavaScript for循环异步变同步)

遇见的一些问题:
1. Excel.JS 支持的数据读取方式不同,获取的数据类型不同。例如:filestreambuffer

另外说一下
有兴趣的朋友也可以试试 SheetJS ,感觉好像功能更多一些,下次我再需要用到excel的时候也会尝试一下的。
SheetJS中文文档:https://github.com/rockboom/SheetJS-docs-zh-CN

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/108190.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MySQL 约束条件,关键字练习,其他语句

创建表的完整语法 create table t1( id int, name varchar(43), age int ); create table 库名.表名( 字段名1 数据类型 约束条件 约束条件 约束条件 约束条件, 字段名2 数据类型 约束条件 约束条件 约束条件 约束条件, 字段名3 数据类型 约束条件 约束…

NPM【问题 01】npm i node-sass@4.14.1报错not found: python2及Cannot download问题处理

node-sass安装问题处理 1.问题2.处理2.1 方案一【我的环境失败】2.2 方案二【成功】2.3 方案三【成功】 1.问题 gyp verb which failed Error: not found: python2 # 1.添加Python27的安装路径到环境变量 gyp verb check python checking for Python executable "python…

Unity C#中LuaTable、LuaArrayTable、LuaDictTable中数据的增删改查

LuaTable、LuaArrayTable、LuaDictTable中数据的增删改查 介绍Lua表lua表初始化lua移除引用lua中向表中添加数据lua中表中移除数据lua表中连接数据lua表中数据排序获取lua表长度获取表中最大值 UnityC#中LuaTableUnityC#中LuaArrayTable、LuaDictTable、LuaDictTable<K,V>…

SpringCloud复习:(3)LoadBalancerInterceptor

使用Ribbon时&#xff0c;execute方法会由RibbonLoadBalancerClient类来实现 它会调用重载的execute方法 getLoadBalancer默认会返回ZoneAwareLoadBalancer&#xff08;基类是BaseLoadBalancer).此处调用的getServer方法就会根据负载均衡策略选择适当的服务器来为下一步的htt…

【Unity】RenderFeature应用(简单场景扫描效果)

【Unity】RenderFeature应用&#xff08;简单场景扫描效果&#xff09; RenderFeature 是一个用于渲染图形的概念&#xff0c;通常在图形引擎或游戏引擎中使用。它是一个模块化的组件&#xff0c;负责处理特定的渲染功能&#xff0c;例如阴影、光照、粒子效果等。 点击地面生成…

【网络】序列化反序列化

序列化反序列化 一、序列化反序列化1、概念2、序列化作用3、序列化框架的选择 二、Json1、介绍2、简单使用 一、序列化反序列化 1、概念 在前文《网络编程套接字》中&#xff0c;我们实现了服务器与客户端之间的字符串通信&#xff0c;这是非常简单的通信&#xff0c;在实际使…

p5.js 到底怎么设置背景图?

本文简介 点赞 关注 收藏 学会了 在 《p5.js 光速入门》 里我们学过加载图片元素&#xff0c;学过过背景色的用法&#xff0c;但当时没提到背景图要怎么使用。 本文就把背景图这部分内容补充完整&#xff0c;并且会提到在 p5.js 里使用背景图的一些注意点。 背景图的用法…

pgsql 分组查询,每组取10条

需求&#xff1a; 按照表的字段分组&#xff0c;然后每组取10条结果&#xff0c;返回即可 sql 如下&#xff1a; SELECT* FROM (SELECT chk_id,feature_id,task_id, ROW_NUMBER () OVER (PARTITION BY chk_id ORDER BY chk_id) AS row_num FROM ics_check_report WHERE task…

中微爱芯74逻辑兼容替代TI/ON/NXP工规品质型号全

这里写自定义目录标题 工业级型号全产品线概述![在这里插入图片描述](https://img-blog.csdnimg.cn/097ef810b2234f07b0c0c1e962a73761.png)批量应用行业头部客户兼容替代封装对照逻辑参数对比电平转换系列型号对照HC/HCT 系列型号对照AHC/AHCT 系列型号对照LV/LVC 系列型号对照…

我是如何快速从python小白达到20k?

前言 首先说一下我自己的情况&#xff0c;我之前是学JAVA的&#xff0c;JAVA亡了只好转行python 很多新手就在好奇自己明明都认认真真的学习了python&#xff0c;但就是感觉很杂很乱&#xff0c;按照我这个流程&#xff0c;至少可以省一大半时间&#xff0c;完整的知识体系很重…

数据可视化报表分享:区域管理驾驶舱

在零售数据分析中&#xff0c;区域管理驾驶舱报表是用来分析企业运营数据&#xff0c;以制定销售策略和提高利润。因此这张报表需要整合大量数据&#xff0c;数据整合、分析、指标计算的工作量极大&#xff0c;在讲究高效率、高度及时性的大数据时代&#xff0c;BI数据可视化分…

Vue 3.3.6 发布,得益于WeakMap,它更快了

性能改进和DOM节点的附加属性的类型检查使新的Vue值得更新。Vue团队确实做了很多工作。实际上&#xff0c;他们在同一天发布了两个子版本。Vue 3.3.5 和 3.3.6 都在2023年10月20日发布。 WeakMaps 其中一个得到改进的是在可能的情况下从 Maps 和 Sets 转移到WeakMaps 和WeakSet…

centos服务器搭建安装Gitlab教程使用教程

1、更新服务器&#xff1a; sudo yum update -y && sudo yum upgrade -y 2、下载Gitlab的RPM包 https://packages.gitlab.com/gitlab/gitlab-cece表示开源el表示centos 选64位el8对应CentOS8 本教程以centos8为例&#xff0c;在服务器中&#xff0c;下载centos8的…

计算机网络【CN】TCP报文段格式【20B】

序号&#xff1a;本报文段所发送的数据的第一个字节的序号确认号&#xff1a;期望收到对方下一个报文段的第一个数据字节的序号。 重要控制位&#xff1a; 紧急位URG&#xff1a;URG1时&#xff0c;标明此报文段中有紧急数据&#xff0c;是高优先级的数据&#xff0c;应尽快传送…

MediaPlayer

1、概念 MediaPlayer是Android原生的多媒体播放器&#xff0c;可以用它来实现本地或者在线音视频的播放。 2、MediaPlayer的状态 下面的图是官方给出的状态转换图&#xff0c;也可易理解为MediaPlayer的生命周期。 椭圆形&#xff1a;表示MediaPlayer的状态&#xff1b;弧形…

Python环境下LaTeX数学公式转图像方案调研与探讨

目录 引言方案一&#xff1a;基于LaTeX环境方案二&#xff1a;基于KaTeX(推荐) 方案三&#xff1a;基于Matplotlib写在最后 引言 近来&#xff0c;涉及到一些公式识别的项目&#xff0c;输入是公式的图像&#xff0c;输出是LaTeX格式的数学公式字符串。 这类项目一般都采用深…

基于Pytorch的驾驶员分心行为实时检测

本文使用深度学习和Pytorch(PyTorch 2.0.1\Torchvision 0.15.2)实时检测驾驶员的分心行为,并附录完整代码。 检测分心驾驶是现代汽车中最重要的功能之一。无论是自动驾驶汽车还是其它高端汽车,都配备了驾驶员监控系统,以持续跟踪驾驶员的行为。这对确保驾驶员保持目光在道路…

前端技术知识(含八股)总结 - 持续更新中

前端技术知识&#xff08;含八股&#xff09;总结 - 持续更新中 参考文献1.HTML和CSS1.1 语义化标签1.2 CSS 选择器及优先级 / position 定位 / box-sizing 属性 / transition / 继承属性&#xff08;如字体文字类的属性大部分有继承&#xff09;/ 行内元素和块级元素 / html的…

【git】git使用教程

1、版本管理工具 如果有一个软件能记录我们对文档的所有修改&#xff0c;所有版本&#xff0c;这类软件我们一般叫做版本控制工具。 特性“ 能够记录历史版本&#xff0c;回退历史版本团队开发&#xff0c;方便代码合并 2、版本管理工具介绍 svn、git svn是集中式版本控制…