前端 读取/导入 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 支持的数据读取方式不同,获取的数据类型不同。例如:file
,stream
,buffer
另外说一下
有兴趣的朋友也可以试试 SheetJS
,感觉好像功能更多一些,下次我再需要用到excel的时候也会尝试一下的。
SheetJS
中文文档:https://github.com/rockboom/SheetJS-docs-zh-CN
相关文章:

前端 读取/导入 Excel文档
情况: 需要通过Excel表,将数据导入到数据库,但是后台人员出差了,我又只会PHP,没用过node,所以只能前端导入Excel文件,然后循环调用后台的单条添加接口了。 库: Excel.js(…...
聊聊springboot的TomcatMetricsBinder
序 本文主要研究一下springboot的TomcatMetricsBinder TomcatMetricsAutoConfiguration org/springframework/boot/actuate/autoconfigure/metrics/web/tomcat/TomcatMetricsAutoConfiguration.java Configuration(proxyBeanMethods false) ConditionalOnWebApplication C…...

《动手学深度学习 Pytorch版》 10.6 自注意力和位置编码
在注意力机制中,每个查询都会关注所有的键-值对并生成一个注意力输出。由于查询、键和值来自同一组输入,因此被称为 自注意力(self-attention),也被称为内部注意力(intra-attention)…...
2023年第四届MathorCup高校数学建模挑战赛——大数据竞赛B题 实现代码
根据之前发布的思路 第一步 进行数据合并 import pandas as pd# 读取所有附件的数据 data1 pd.read_excel(附件一.xlsx) data2 pd.read_excel(附件二.xlsx) data3 pd.read_excel(附件三.xlsx) data4 pd.read_excel(附件四.xlsx)# 根据商品编码将附件一和附件二连接 combi…...
larvel 中的api.php_Laravel 开发 API
Laravel10中提示了Target *classController does not exist,为什么呢? 原因是:laravel8开始写法变了。换成了新的写法了 解决方法一: 在路由数组加入App\Http\Controllers\即可。 <?phpuse Illuminate\Support\Facades\Route;…...

虚拟机构建部署单体项目及前后端分离项目
目录 一.部署单体项目 1.远程数据库 1.1远程连接数据库 1.2 新建数据库运行sql文件 2.部署项目到服务器中 3.启动服务器运行 二.部署前后端分离项目 1.远程数据库和部署到服务器 2.利用node环境启动前端项目 3.解决主机无法解析服务器localhost问题 方法一 编辑 方法二 一.部…...

C++之特殊类的设计
目录 一、单例模式 1、设计模式 2、单例模式 1、饿汉模式 2、懒汉模式 3、单例对象的释放问题 二、设计一个不能被拷贝的类 三、设计一个只能在堆上创建对象的类 四、设计一个只能在栈上创建对象的类 五、设计一个不能被继承的类 一、单例模式 1、设计模式 概念&am…...

Java练习题2020 -1
统计1到N的整数中,被A除余A-1的偶数的个数 输入说明:整数 N(N<10000), A, (A 输出说明:符合条件的数的个数 输入样例:10 3 输出样例:2 (说明:样例中符合条件的2个数是 2、8) import java.util.Scanner;p…...

LuaTable转C#的列表List和字典Dictionary
LuaTable转C#的列表List和字典Dictionaty 介绍lua中创建表测试lua中list表表转成List表转成Dictionary 键值对表表转成Dictionary 多类型键值对表表转成Dictionary 总结 介绍 之前基本都是从C#中的List或者Dictionary转成luaTable,很少会把LuaTable转成C#的List或者…...
Redis快速上手篇七(集群)
在赶工了..... Redis集群 主从复制的场景无法吗满足主机单点故障时需要引入集群配置 一般数据库要处理的读请求远大于写请求 ,针对这种情况,我们优化数据库可以采用读写分离的策略。我们可以部 署一台主服务器主要用来处理写请求,部署多台从…...

Mac 安装nvm
安装方案: 1. 从github下载nvm仓库到 ~/目录 地址:https://github.com/nvm-sh/nvm.git git clone https://github.com/nvm-sh/nvm.git 2. 进入nvm目录中执行install.sh等待执行完成,执行的操作方法就是直接将文件拖入到终端然后回车。 3.…...

python 从mssql取出datetime2类型之后格式化
我mssql是datetime2类型,用df取出之后发现是个纳秒的int(1698419713000000000 这种) 所以格式化的话就需要变成秒为单位,他们之间是10的9次方倍。所以先除以1e9之后用datetime.datetime.fromtimestamp()转换之后再format就行了 l…...

18.2 使用NPCAP库抓取数据包
NPCAP 库是一种用于在Windows平台上进行网络数据包捕获和分析的库。它是WinPcap库的一个分支,由Nmap开发团队开发,并在Nmap软件中使用。与WinPcap一样,NPCAP库提供了一些API,使开发人员可以轻松地在其应用程序中捕获和处理网络数据…...

pytest-yaml 测试平台-3.创建执行任务定时执行用例
前言 当项目用例编写完成后,需设置执行策略,可以用到定时任务设置每天几点执行。或者间隔几个小时执行一次。 创建定时任务 创建任务 勾选需要执行的项目以及运行环境 触发器可以支持2种方式:interval 间隔多久触发和 cron 表达式定时执行…...
安卓文件资源中,一个字串包含引用其他字串的写法
具体范例: <string name"product_name" translatable"false">Miscope</string><string name"app_name">string/product_name for USB Camera</string> 注意要先定义再引用。...

解决:谷歌浏览器访问http时,自动转https访问的问题
问题背景:某个系统网站,之前一直用https域名访问,现在改成http域名后,用http访问,谷歌浏览器会自动跳转到https。 解决方法: 在浏览器中输入网址:chrome://net-internals/#hsts -》 在“Delete…...

MQTT协议和边缘计算
1.基本概念 MQTT是基于TCP/IP协议栈构建的异步通信消息协议,是一种轻量级的发布、订阅信息传输协议。可以在不可靠的网络环境中进行扩展,适用于设备硬件存储空间或网络带宽有限的场景。使用MQTT协议,消息发送者与接收者不受时间和空间的限制…...

Redis(04)| 数据结构-压缩列表
压缩列表的最大特点,就是它被设计成一种内存紧凑型的数据结构,占用一块连续的内存空间,不仅可以利用 CPU 缓存,而且会针对不同长度的数据,进行相应编码,这种方法可以有效地节省内存开销。 但是,…...
516 最长回文子序列(区间DP)(灵神笔记)
题目 最长回文子序列 给你一个字符串 s ,找出其中最长的回文子序列,并返回该序列的长度。 子序列定义为:不改变剩余字符顺序的情况下,删除某些字符或者不删除任何字符形成的一个序列。 示例 1: 输入:s …...

Kafka - 异步/同步发送API
文章目录 异步发送普通异步发送异步发送流程Code 带回调函数的异步发送带回调函数的异步发送流程Code 同步发送API 异步发送 普通异步发送 需求:创建Kafka生产者,采用异步的方式发送到Kafka broker 异步发送流程 Code <!-- https://mvnrepository…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...

python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互
引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...
Xen Server服务器释放磁盘空间
disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...

C++ 设计模式 《小明的奶茶加料风波》
👨🎓 模式名称:装饰器模式(Decorator Pattern) 👦 小明最近上线了校园奶茶配送功能,业务火爆,大家都在加料: 有的同学要加波霸 🟤,有的要加椰果…...
WebRTC从入门到实践 - 零基础教程
WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC? WebRTC(Web Real-Time Communication)是一个支持网页浏览器进行实时语音…...