前端 读取/导入 Excel文档

news2024/11/18 9:33:02

情况: 需要通过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循环内,使异步接口变成同步提交
我文章的地址:

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于Java的宠物商店管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09; 代码参考数据库参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者&am…

03_Flutter自定义下拉菜单

03_Flutter自定义下拉菜单 在Flutter的内置api中&#xff0c;可以使用showMenu实现类似下拉菜单的效果&#xff0c;或者使用PopupMenuButton组件&#xff0c;PopupMenuButton内部也是使用了showMenu这个api&#xff0c;但是使用showMenu时&#xff0c;下拉面板的显示已经被约定…

MedNeXt: Transformer-driven Scaling ofConvNets for Medical Image Segmentation

论文标题;MedNeXt: Transformer-driven Scaling of ConvNets for Medical Image Segmentation 论文链接&#xff1a;2303.09975.pdf (arxiv.org)https://arxiv.org/pdf/2303.09975.pdf 论文&#xff1a; MedNeXt&#xff1a;用于医学图像分割的转换器驱动的ConvNets缩放 项目…

echart绘制环形进度条

原型: <template><div class="chart"><div ref="chartRef" class="chart-bar" :style="{ width, height }"></div><div class="num">{{ sideText }}</div></div> </templa…

一文教你如何将Eclipse项目导入到IDEA运行

&#x1f4d6;本篇超级详细案例截图教学 Eclipse web项目如何导入到Intellij IDEA中&#xff0c;图片点击可放大仔细看 工具版本说明&#xff1a; 工具 版本 Intellij IDEA 2022.3 tomcat 8.5 JDK 1.8 步骤一 .导入一个已存在的工程 1.1 File–>New–>Proj…

损失函数总结(八):MultiMarginLoss、MultiLabelMarginLoss

损失函数总结&#xff08;八&#xff09;&#xff1a;MultiMarginLoss、MultiLabelMarginLoss 1 引言2 损失函数2.1 MultiMarginLoss2.2 MultiLabelMarginLoss 3 总结 1 引言 在前面的文章中已经介绍了介绍了一系列损失函数 (L1Loss、MSELoss、BCELoss、CrossEntropyLoss、NLL…

LIS系统-实现检验报告集中管理

LIS系统即实验室信息管理系统。LIS系统能实现临床检验信息化&#xff0c;检验科信息管理自动化。其主要功能是将检验科的实验仪器传出的检验数据经数据分析后&#xff0c;自动生成打印报告&#xff0c;通过网络存储在数据库中&#xff0c;使医生能够通过医生工作站方便、及时地…

基于springboot实现网吧管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现网吧管理系统演示 摘要 随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的管理系统应运而生&#x…

JDK11下载、安装与配置、运行第一个Java程序教程

JDK已经更新到20.0.2了&#xff0c;JDK11是相对比较稳定的版本&#xff0c;网上的JDK11安装配置教程一大堆&#xff0c;但是很多都过时了&#xff0c;自己整理了一篇JDK11下载安装的详细步骤&#xff0c;带有每一步的完整的图文教程&#xff0c;大家可以根据自己的需要下载。 …

pytorch 入门 (五)案例三:乳腺癌识别识别-VGG16实现

本文为&#x1f517;小白入门Pytorch内部限免文章 &#x1f368; 本文为&#x1f517;小白入门Pytorch中的学习记录博客&#x1f366; 参考文章&#xff1a;【小白入门Pytorch】乳腺癌识别&#x1f356; 原作者&#xff1a;K同学啊 在本案例中&#xff0c;我将带大家探索一下深…

pytorch深度学习实践(二):梯度下降算法详解和代码实现(梯度下降、随机梯度下降、小批量梯度下降的对比)

目录 一、梯度下降1.1 公式与原理1.1.1 cost(w)1.1.2 梯度1.1.3 w的更新 1.2 训练过程可视化1.3 代码实现 二、随机梯度下降&#xff08;stochastic gradient descent&#xff0c;SDG&#xff09;2.1 公式与原理2.1.1 w的更新 2.2 代码实现2.3 梯度下降和随机梯度下降的优缺点对…

漏洞复现-jquery-picture-cut 任意文件上传_(CVE-2018-9208)

jquery-picture-cut 任意文件上传_&#xff08;CVE-2018-9208&#xff09; 漏洞信息 jQuery Picture Cut v1.1以下版本中存在安全漏洞CVE-2018-9208文件上传漏洞 描述 ​ picture cut是一个jquery插件&#xff0c;以友好和简单的方式处理图像&#xff0c;具有基于bootstrap…

Vue3-小兔鲜项目

1.初始化项目 npm init vuelatest src目录调整 Git项目管理 基于create-vue创建出来的项目默认没有初始化git仓库&#xff0c;需要我们手动初始化 执行命令并完成首次提交 1.git init 2.git add 3.git commit -m "init" 别名路径联想提示 什么是别名路径联想…

通过requests库使用HTTP编写的爬虫程序

使用Python的requests库可以方便地编写HTTP爬虫程序。以下是一个使用requests库的示例&#xff1a; import requests# 发送HTTP GET请求 response requests.get("http://example.com")# 检查响应状态码 if response.status_code 200:# 获取响应内容html response.…

推荐5款助你高效工作的小软件

现在&#xff0c;有很多实用的工具和软件可以帮助我们更高效地完成各种任务。以下是5款值得推荐的工具软件&#xff0c;能够极大地提高我们的工作效率。 1.电子书阅读器——Koodo Reader ​ Koodo Reader 是一款开源免费的电子书阅读器&#xff0c;支持多达15种主流电子书格式…

laravel+vue2 element 一套项目级医院手术麻醉信息系统源码

手术麻醉临床信息系统源码&#xff0c;PHPmysqllaravelvue2 手术麻醉临床信息系统&#xff0c;采用计算机和通信技术&#xff0c;实现监护仪、麻醉机、输液泵等设备输出数据的自动采集&#xff0c;采集的数据能够如实准确地反映患者生命体征参数的变化&#xff0c;并实现信息高…

搜维尔科技:【应用】配备MTi-3的轻便型ROV,在水下进行地理标记视觉检测

部署潜水员进行水下摄像&#xff0c;不仅难度高而且费用昂贵&#xff0c;需要受过潜水和摄像两方面培训的专业人员来进行。但有些水下作业任务例如拍摄海底管道内部的照片&#xff0c;由于人员无法进入或危险度高的原因&#xff0c;无法由潜水员完成。 如今&#xff0c;俄罗…

看谷歌浏览器源码,为什么p标签和div标签为块元素

看谷歌浏览器源码 谷歌源码路径&#xff1a;third_party/blink/renderer/core/html/resources/html.css 为什么块级元素独占一行&#xff1f; 是谷歌浏览器设置div的默认样式 display:block 它才独占一行 p标签和div标签为块元素 strong,b,i,em等等标签为行内元素

如何在Excel中实现三联类模板?

本文由葡萄城技术团队原创并首发。转载请注明出处&#xff1a;葡萄城官网&#xff0c;葡萄城为开发者提供专业的开发工具、解决方案和服务&#xff0c;赋能开发者。 前言 在一些报表打印应用场景中&#xff0c;会有类似于如下图所示的排版格式&#xff1a; 一般情况下将这种类…

k8s statefulSet 学习笔记

缩写: sts 通过 kubectl api-resources 可以查到&#xff1a; NAMESHORTNAMESAPIVERSIONNAMESPACEDKINDstatefulsetsstsapps/v1trueStatefulSet web-sts.yaml apiVersion: v1 kind: Service metadata:name: nginxlabels:app: nginx spec:ports:- port: 80name: web-sts-svc…