当前位置: 首页 > news >正文

前端 读取/导入 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

相关文章:

  • uniapp 在 Android Studio 模拟器中运行项目
  • Java基于SpringBoot+Vue的网上图书商城管理系统(附源码,教程)
  • 博客摘录「 TCP/IP网络编程——习题答案」2023年10月29日
  • 《HelloGitHub》第 91 期
  • V3Det大规模词汇视觉检测数据集与LaRS海上全景障碍物检测数据集
  • HTTP协议及Requests库方法
  • 多线程---阻塞队列+生产者消费者模型
  • 软考高项-基础知识
  • Linux学习第26天:异步通知驱动开发: 主动
  • 框架安全-CVE 复现SpringStrutsLaravelThinkPHP漏洞复现
  • vue中electron与vue通信(fs.existsSync is not a function解决方案)
  • C++ 中的仿函数 functor
  • PHP | php入门知识(if、switch、数组、数组排序、超级全局变量)
  • 6G关键新兴技术- 智能超表面(RIS)技术演进
  • DbVisualizer和DBeaver启动不来,启动报错
  • 【Leetcode】101. 对称二叉树
  • 【css3】浏览器内核及其兼容性
  • 【知识碎片】第三方登录弹窗效果
  • CSS 专业技巧
  • Git学习与使用心得(1)—— 初始化
  • HashMap ConcurrentHashMap
  • Java-详解HashMap
  • LeetCode算法系列_0891_子序列宽度之和
  • Netty 4.1 源代码学习:线程模型
  • Nodejs和JavaWeb协助开发
  • React-生命周期杂记
  • SAP云平台里Global Account和Sub Account的关系
  • SpringCloud集成分布式事务LCN (一)
  • vue.js框架原理浅析
  • 从0到1:PostCSS 插件开发最佳实践
  • 大快搜索数据爬虫技术实例安装教学篇
  • 好的网址,关于.net 4.0 ,vs 2010
  • 每天一个设计模式之命令模式
  • 微信开源mars源码分析1—上层samples分析
  • 温故知新之javascript面向对象
  • 一起来学SpringBoot | 第十篇:使用Spring Cache集成Redis
  • 应用生命周期终极 DevOps 工具包
  • 关于Kubernetes Dashboard漏洞CVE-2018-18264的修复公告
  • ​草莓熊python turtle绘图代码(玫瑰花版)附源代码
  • # 飞书APP集成平台-数字化落地
  • #{}和${}的区别?
  • $.type 怎么精确判断对象类型的 --(源码学习2)
  • (C语言)编写程序将一个4×4的数组进行顺时针旋转90度后输出。
  • (delphi11最新学习资料) Object Pascal 学习笔记---第7章第3节(封装和窗体)
  • (附源码)springboot太原学院贫困生申请管理系统 毕业设计 101517
  • (力扣记录)235. 二叉搜索树的最近公共祖先
  • (七)Java对象在Hibernate持久化层的状态
  • (十六)一篇文章学会Java的常用API
  • (一)基于IDEA的JAVA基础1
  • (译) 函数式 JS #1:简介
  • (转)微软牛津计划介绍——屌爆了的自然数据处理解决方案(人脸/语音识别,计算机视觉与语言理解)...
  • * 论文笔记 【Wide Deep Learning for Recommender Systems】
  • ****Linux下Mysql的安装和配置
  • .“空心村”成因分析及解决对策122344
  • .NET Core 控制台程序读 appsettings.json 、注依赖、配日志、设 IOptions