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

本地读取Excel文件并进行数据压缩传递到服务器

        在项目开发过程中,读取excel文件,可能存在几百或几百万条数据内容,那么对于大型文件来说,我们应该如何思考对于大型文件的读取操作以及性能的注意事项。

 类库:Papa Parse - Powerful CSV Parser for JavaScript

第一步:安装

npm install papaparse

第二步:内容的引入

import Papa from 'papaparse';
import { useState } from "react";export default function App() {const [results,setResults] = useState([]); //保留解析后的数据const handleFile = (e) => {const file = e.target.files[0];Papa.parse(file,{header:true, //指定第一行为标题行skipEmptyLines:true, //跳过空行complete:(parsedResult) => {const data = parsedResult.data;console.log(data) // 在控制台打印解析后的数据}})};return (<div><h1>本地读取Excel文件并进行数据压缩传递到服务器</h1><input type="file" onChange={handleFile} accept='.csv' /></div>)
}

当我们上传的数据为百万条数据的时候,数据量是非常的庞大的,那么如果将数据传输到服务器上,将会对http的请求资源产生极大的浪费。所以我们考虑使用第三方类库pako进行数据的压缩。

对于pako,可以查看以下文章进行一个了解:https://github.com/nodeca/pako

pako是什么以及它的的使用_如何使用pako库-CSDN博客文章浏览阅读62次。ws推送的gzip压缩能减少大量的传输数据,减少传输数据消耗,但是需要在收到数据之后解压。解压就可以用到pako了。_如何使用pako库https://blog.csdn.net/mantou_riji/article/details/135001065

第三步:pako安装

npm install pako

第四步:在组件中进行pako引入且对数据进行gzip的压缩

import pako from "pako";

引入之后,将我们获取到的数据进行gzip的压缩

// gzip压缩
const gzip = pako.gzip(JSON.stringify(data),{to:"string"});
console.log(JSON.stringify(data).length,gzip.length); //打印的则是压缩后的数据信息
//原先的长度为41万,压缩后的长度为4万

且发送到后端(以下是改事件的全部代码,gzip的压缩数据也在其内)

 const handleFile = (e) => {const file = e.target.files[0];Papa.parse(file,{header:true, //指定第一行为标题行skipEmptyLines:true, //跳过空行complete:async (parsedResult) => {const data = parsedResult.data;console.log(data) // 在控制台打印解析后的数据// gzip压缩const gzip = pako.gzip(JSON.stringify(data),{to:"string"});console.log(JSON.stringify(data).length,gzip.length); //打印的则是压缩后的数据信息const response = await fetch("http://localhost:3000",{method:"POST",body:gzip,headers:{"Content-Type":"application/octet-stream", //数据流的方式进行上传处理}});console.log(response)}})};

第五步:后端,后端也需要下载pako进行解压缩处理

const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
const pako = require("pako");const app = express();// 使用 cors 中间件处理跨域请求
app.use(cors());// 使用 bodyParser 中间件解析请求体
app.use(bodyParser.raw({ type: "application/octet-stream", limit: "100mb" }));// 处理 POST 请求
app.post("/", (req, res) => {// 获取压缩后的数据const compressedData = req.body;// 解压缩数据const uncompressedData = pako.ungzip(compressedData, { to: "string" });// 将解压缩后的数据解析为 JSON 对象const jsonData = JSON.parse(uncompressedData);// 打印压缩前数据长度,解压缩后数据长度和 JSON 对象长度console.log(compressedData.length,uncompressedData.length,jsonData.length);// 构造响应消息const msg =compressedData.length +" " +uncompressedData.length +" " +jsonData.length;// 发送响应res.status(200).send(msg);
});// 启动服务器,监听端口 3000
app.listen(3000, () => {console.log("Server started on port 3000");
});

执行以上操作后,我们运行项目选择文件,后端返回三条数据

已压缩的长度   未压缩的长度   最终记录的条数

前端也已经返回了response的一个相应数据

第六步:对打印的response进行进一步的处理 

console.log(response)
const result = {success:response.ok.toString(),status:response.status,message:response.statusText,
};
setResults(result)

第七步:展示到页面上

<h2>结果显示</h2>
<ul>{results && Object.keys(results).map((key) => {<li key={key}>{key}:{results[key]}</li>})}
</ul>

第八步:添加一个点击按钮事件切换背景颜色

const toggleBodyBackground = () => {if(document.body.style.background === "red"){document.body.style.background = "white";}else{document.body.style.background = "red"}
}<button onClick={toggleBodyBackground}>change body background</button>

 当我进行大文件读取的时候会造成主线程的阻塞,那么后续我们可以进行功能的强化,在强化过程中,我们可以去考虑,是不是可以对现有的数据进行拆分,如果是一百多万条数据的时候,我们可以将一百多万条数据进行五万条,五万条的切片处理,然后不断的在后端进行压缩后数据的请求处理,最终可以在服务器端进行对数据的操作,减轻服务器的压力。

第九步:是否可以减轻服务器的压力,以下操作可以进行一个测试

使用console.time('test')开始时间设置console.timeEnd("test")结束时间设置

const handleFile = (e) => {console.time('test') //开始时间const file = e.target.files[0];Papa.parse(file,{...............};setResults(result)console.timeEnd("test"); //结束时间}})
};

当前的测试时间为18秒左右,耗费时常比较久,那么随后我们会对其进行功能优化处理。

此内容已结束,希望对您有所帮助。 

http://www.lryc.cn/news/285951.html

相关文章:

  • 【开源】基于JAVA的停车场收费系统
  • 基于java+Springboot操作系统教学交流平台详细设计实现
  • Nginx 基础使用
  • JavaEE:多线程(2):线程状态,线程安全
  • Flutter 自定义AppBar实现滚动渐变
  • 编程语言MoonBit新增矩阵函数的语法糖
  • Angular:跨域请求携带 cookie
  • 【C++】list容器迭代器的模拟实现
  • Docker镜像操作
  • 【Java-框架-SpringSecurity】单点登录(认证和授权)- 随笔
  • 大数据开发之Scala
  • 数字时代的大对决
  • 网络防御保护1
  • 解决Windows下Goland的Terminal设置为Git Bash失败
  • x-cmd pkg | jq - 命令行 JSON 处理器
  • 网络安全笔记
  • php基础学习之代码框架
  • LCD-LMD-PSO-ELM的电能质量分类,LCD特征提取,LMD特征提取,粒子群算法优化极限学习机
  • 【ARMv8M Cortex-M33 系列 7 -- RA4M2 移植 RT-Thread 问题总结】
  • 分享 GitHub 上的敏感词汇工具类:sensitive-word
  • 洛谷P1319 压缩技术(C语言)
  • HQL,SQL刷题简单查询,基础,尚硅谷
  • MSG3D
  • kafka(二)——常用命令
  • 使用Flink处理Kafka中的数据
  • 跟着pink老师前端入门教程-day07
  • Pixelmator Pro Mac版 v3.5 图像处理软件 兼容 M1/M2
  • 《吐血整理》进阶系列教程-拿捏Fiddler抓包教程(15)-Fiddler弱网测试,知否知否,应是必知必会
  • 【vscode】远程资源管理器自动登录服务器保姆级教程
  • 写点东西《Javascript switch 语句的替代方法》