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

前端实现解析【导入】数据后调用批量处理接口

1. 导入数据不想调用后端接口,可以前端直接解析上传的Excel文件,解析出文本内容后,再直接调用批量插入数据的接口插入数据么?

当然可以。这是一个很好的优化,可以减轻服务器的压力。我们可以在前端使用一个库来解析 Excel 文件,然后将解析出的数据直接发送到批量添加的接口。

要实现这个功能,我们需要一个用于解析 Excel 文件的库。xlsx(也称为 SheetJS)是一个非常流行的选择。

2. 代码实现,基于 React + Antd

import * as XLSX from 'xlsx'
import { message, Upload, type UploadProps } from 'antd'<Upload {...uploadProps}><Button loading={uploading} icon={<UploadOutlined />}>导入邮箱</Button>
</Upload>const uploadProps: UploadProps = {name: 'file',showUploadList: false,beforeUpload: (file: any) => {const isExcel = file.type === 'application/vnd.ms-excel' || file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'if (!isExcel) {message.error('只能上传 Excel 文件!')return Upload.LIST_IGNORE}setUploading(true)const reader = new FileReader()reader.onload = async (e) => {try {const data = e.target.resultconst workbook = XLSX.read(data, { type: 'array' })const firstSheetName = workbook.SheetNames[0]const worksheet = workbook.Sheets[firstSheetName]const json = XLSX.utils.sheet_to_json(worksheet, { header: 1 })// 假设第一行是表头const headers = json[0] as string[]const rows = (json.slice(1) as any[][]).filter((row) => row.length > 0 && row.some((cell) => cell))// 映射表头到API字段const headerMap: Record<string, string> = {名称: 'name',类型: 'type',说明: 'remark',}// 校验名称列const nameColumnIndex = headers.indexOf('名称')if (nameColumnIndex === -1) {message.error('模板中未找到“名称”列,请检查文件')return}const names = rows.map((row) => (row as any[])[nameColumnIndex])// 检查空数据if (names.some((name) => !name)) {message.error('名称列存在空数据,请检查后重新上传')return}// 检查重复数据const nameSet = new Set()for (const name of names) {if (nameSet.has(name)) {message.error(`名称 “${name}” 重复,请检查后重新上传`)return}nameSet.add(name)}const dataToSubmit = rows.map((row) => {const rowData: Record<string, any> = {}headers.forEach((header, index) => {const apiKey = headerMap[header]if (apiKey) {rowData[apiKey] = (row as any[])[index]}})return rowData})// 调用批量添加接口的方法handleBatchAdd(dataToSubmit)} catch (error) {message.error('文件解析或导入失败')} finally {setUploading(false)}}reader.readAsArrayBuffer(file)return Upload.LIST_IGNORE // 阻止自动上传},
}

3. 我不太明白reader.onload和reader.readAsArrayBuffer(file)的执行顺序,以及最后为什么返回这个return Upload.LIST_IGNORE?

这三部分共同实现了一个自定义的、在前端处理文件的上传逻辑。

1. reader.readAsArrayBuffer(file) - 开始读文件这行代码是整个文件读取过程的起点。

  • 它的作用是告诉浏览器:“现在开始读取用户选择的这个 file 文件,并把它的内容转换成一个 ArrayBuffer(一种内存中的二进制数据格式)。”
  • 这是一个异步操作。也就是说,它像一个经理分配任务,把“读文件”这个耗时的任务交给浏览器底层去处理,它自己则不会等待任务完成,而是立刻返回,让 beforeUpload 函数继续执行下面的代码。

2. reader.onload - 文件读完后做什么

这个 onload 是一个事件处理函数,你可以理解为“任务完成后的回调”。

  • 在调用 readAsArrayBuffer 之前,我们先定义好 onload 函数。这相当于提前告诉浏览器:“等你成功把文件读完之后,就来执行 onload 里面的这些代码。”
  • onload里的代码(解析Excel、处理数据、调用API)只有在文件被完全、成功地读取到内存后才会被触发执行。

3. return Upload.LIST_IGNORE - 告诉 antd 组件“交给我处理”这是 antd Upload 组件提供的一个特殊返回值。

  • beforeUpload 函数的返回值可以控制 Upload 组件的行为。
  • 默认情况下,Upload 组件会自己尝试将文件上传到一个服务器地址(通过 action 属性指定)。
  • 但是,在这里我们并不想让 Upload 组件自己上传文件。我们的目标是在前端浏览器里直接解析文件内容,然后把解析出来的数据(而不是文件本身)发送到我们的API。
  • 所以,return Upload.LIST_IGNORE 的作用就是明确地告诉 Upload 组件:
  1. “请停止你默认的上传动作,我自己来处理这个文件。”
  2. “同时,也不用在上传列表里显示这个文件了。”

总结执行顺序

  1. beforeUpload 函数被触发。
  2. 代码定义了 reader.onload 事件处理函数(此时不执行)。
  3. reader.readAsArrayBuffer(file) 被调用,开始在后台异步读取文件。
  4. beforeUpload 函数立即执行到最后一行,return Upload.LIST_IGNORE,阻止了 antd 的默认上传行为。
  5. 过了一会儿(取决于文件大小),文件在后台被读取完毕。
  6. 浏览器触发 load 事件,此时才开始执行 reader.onload 函数里的代码,进行文件解析和API调用。

希望这个解释能帮助您理解!


文章转载自:

http://Kx3OqcPB.Lfdzr.cn
http://UmOpT1gO.Lfdzr.cn
http://vemwLpF4.Lfdzr.cn
http://5y3c3tVS.Lfdzr.cn
http://qz2AQuwp.Lfdzr.cn
http://VaKm6dHC.Lfdzr.cn
http://8cKu1HCL.Lfdzr.cn
http://Aa0S89GM.Lfdzr.cn
http://HPv3e3JO.Lfdzr.cn
http://Y4fvC4J9.Lfdzr.cn
http://wRcFzCGH.Lfdzr.cn
http://ITiUvqkN.Lfdzr.cn
http://Cy6QFlsV.Lfdzr.cn
http://T326hmAG.Lfdzr.cn
http://nn7kbXEh.Lfdzr.cn
http://MiM7PCtZ.Lfdzr.cn
http://HWxVMAg6.Lfdzr.cn
http://BB06XT3k.Lfdzr.cn
http://WRPzW2vL.Lfdzr.cn
http://5Dykz40y.Lfdzr.cn
http://Zc7yYFKJ.Lfdzr.cn
http://NmqtaVEc.Lfdzr.cn
http://HifNcevz.Lfdzr.cn
http://R7akOYKE.Lfdzr.cn
http://qx9mdrBs.Lfdzr.cn
http://y11cpX1s.Lfdzr.cn
http://6KfLuABk.Lfdzr.cn
http://BqI2JQdS.Lfdzr.cn
http://u7y0XR7x.Lfdzr.cn
http://YS6brNsp.Lfdzr.cn
http://www.dtcms.com/a/363312.html

相关文章:

  • GaussDB 等待事件为LockMgrLock处理方法
  • 为什么程序员总是发现不了自己的Bug?
  • flutter踩坑插件:Swift架构不兼容
  • 疯狂星期四文案网第58天运营日记
  • 手撕Redis底层2-网络模型深度剖析
  • 【3D 入门-4】trimesh 极速上手之 3D Mesh 数据结构解析(Vertices / Faces)
  • Valkey vs Redis详解
  • 基于若依框架开发WebSocket接口
  • 计算机Python毕业设计推荐:基于Django+Vue用户评论挖掘旅游系统
  • 【交易系统系列36】揭秘币安(Binance)技术心脏:从公开信息拼凑“MatchBox”撮合引擎架构
  • 海康摄像头开发---标准配置结构体(NET_DVR_STD_CONFIG)
  • End-To-End 之于推荐-kuaishou OneRec2 笔记
  • css中 ,有哪些⽅式可以隐藏页⾯元素? 区别?
  • 03_网关ip和端口映射(路由器转发)操作和原理
  • Telnet 原理与配置
  • 基于STM32单片机智能家居wifi远程监控系统机智云app设计
  • Replit在线编程工具:支持多语言环境免配置与实时协作,助力编程学习调试与社区项目复用
  • Spring Security的@PreAuthorize注解为什么会知道用户角色?
  • 0902 C++类的匿名对象
  • Nano Banana 复刻分镜,多图结合片刻生成想要的视频
  • 适配第一性原理与分子动力学研究的高性能工作站解析
  • 信息安全各类加密算法解析
  • LDR6600:2C1A适配器协议方案芯片
  • 综合诊断板CAN时间戳稳定性测试报告8.28
  • Nek La Vita È DJ大来 安装教程 简单步骤 教你怎么装(附安装包下载)
  • Windows 命令行:父目录与子目录
  • 力扣222 代码随想录Day15 第四题
  • 缓存工具服务(封装缓存击穿+缓存穿透+缓存雪崩)
  • HCIE-Datacom 论述【Y园区】
  • 流程自动化常见三大悖论及RPA人机协作的工程实践