React 前端如何通过组件完成 “下载 Excel模板” 和 “上传 Excel 文件并读取内容生成可使用的对象数组”

news/2024/11/5 20:53:09 标签: 前端, react.js, excel

文章目录

  • 一、Excel 模板下载
    • 01、代码示例
  • 二、Excel 文件上传
    • 01、文件展示
    • 02、示例代码
    • 03、前端样式展示
    • 04、数据结果展示
  • 三、完整代码

本文的业务需求是建立在批量导入数据的情况下,普通组件只能少量导入,数据较多的情况都会选择 Excel 数据导入,这就涉及到下载 Excel 模板和上传带有数据的Excel 文件,读取数据进行后一步的存储操作。

本文讲解了两部分内容:

  • 如何在 React 前端使用 UI 组件(这里使用button 按钮 和 input 输入框的组合样式)上传一个 Excel 文件,并读取文件内容转成可使用的 json 对象数组的数据格式。
  • 如何在 React 前端使用 UI 组件(这里使用button 按钮)下载一个 Excel 文件模板,用于对上传 Excel 做准备。

一、Excel 模板下载

先准备好模板文件,放在了 React 项目的 public 文件夹下,通过按钮的方式让用户点击并下载该文件。

01、代码示例

这里有两个很容易出错的问题:

  • 模板名字,const templateUrl = '/template.xlsx'; 路径引用中名字出错会出现找不到资源的问题,表现结果是刷新界面。
  • 路径问题,const templateUrl = '/template.xlsx'; 这个路径是正确的。下面两个示例在运行时不会工作,因为 public 文件夹的内容在构建时被复制到根目录。
    • const templateUrl = './public/template.xlsx';
    • const templateUrl = '../../public/template.xlsx';

只要你的 template.xlsx 文件位于 public 文件夹中,并且你使用 /template.xlsx 这个绝对路径来引用它,你就可以在 React 项目的任何组件中通过点击事件来触发下载,而无需担心组件文件的位置。

import React from 'react';

const downExcelTemplate: React.FC = () => {
	// 模板文件的URL(由于放在public文件夹中,所以可以直接通过/来访问)  
	const templateUrl = '/template.xlsx';  
	
	// 处理下载的函数  
	const handleDownload = () => {  
		// 创建一个隐藏的<a>标签并触发点击事件来下载文件  
    	const link = document.createElement('a');  
    	link.href = templateUrl;  
    	link.download = '测试.xlsx'; // 可以设置下载时的文件名  
    	document.body.appendChild(link);  
    	link.click();  
    	document.body.removeChild(link); // 下载后移除<a>标签  
	};  
  
	return (<div>  
		<button onClick={handleDownload} className="download-button">  
			模板下载
		</button>  
	</div>);  
}  
  
export default downExcelTemplate;

现在就可以点击模板下载弹出下载文件的界面了。
样式

二、Excel 文件上传

01、文件展示

下图是用模板文件填写的数据文件图片。

Excel 文件

02、示例代码

完整代码包装成了一个组件。需要注意,React 本身不支持读取 Excel 文件,需要导入依赖,在项目的 package.json 中引入依赖,我的引入的 xlsx 依赖版本如下:

"xlsx": "^0.18.5",

使用的是 button 按钮点击上传的方式,这样可以减少样式调整,重点是 input 输入框的 style 属性设置一个 display: "none"

import React from 'react';
import * as XLSX from 'xlsx';

const ReadExcelWord: React.FC = () => {

    const handleFileChange = (event: any) => {
        const inputFile = event.target.files[0];
        if (inputFile){
            const reader = new FileReader();
            reader.onload = (e: any) => {
                const data = new Uint8Array(e.target?.result);
                const workbook = XLSX.read(data, {type: 'array'});
                // 只读取第一个sheet
                const firstSheetName = workbook.SheetNames[0];
                const workSheet = workbook.Sheets[firstSheetName];
                const jsonData = XLSX.utils.sheet_to_json(workSheet, { header: 1});
                console.log("jsonData", jsonData);
            };
            reader.readAsArrayBuffer(inputFile); 
        }
    }

	// input 输入框的 id = "upfile" 很重要
    const handleButtonClick = () => {
    	let upExcel = document.getElementById("upfile");
    	upExcel?.click();
    }
    
	return (<div>
		<button onClick={handleButtonClick}>上传</button>
		<input 
			id="upfile" 
			type="file" 
			style={{ display: "none" }} 
			accept=".xlsx" 
			onChange={handleFileChange} 
		/>
	</div>);
};

export default ReadExcelWord;

03、前端样式展示

在这里插入图片描述

04、数据结果展示

json对象结果

三、完整代码

import React from 'react';
import * as XLSX from 'xlsx';

const ReadExcelWord: React.FC = () => {

    const handleFileChange = (event: any) => {
        const inputFile = event.target.files[0];
        if (inputFile) {
            const reader = new FileReader();
            reader.onload = (e: any) => {
                const data = new Uint8Array(e.target?.result);
                const workbook = XLSX.read(data, {type: 'array'});
                // 只读取第一个sheet
                const firstSheetName = workbook.SheetNames[0];
                const workSheet = workbook.Sheets[firstSheetName];
                const jsonData = XLSX.utils.sheet_to_json(workSheet, { header: 1});
                console.log("jsonData", jsonData);
            };
            reader.readAsArrayBuffer(inputFile); 
        }
    }

	// input 输入框的 id = "upfile" 很重要
    const handleButtonClick = () => {
    	let upExcel = document.getElementById("upfile");
    	upExcel?.click();
    }
    
	// 模板文件的URL(由于放在public文件夹中,所以可以直接通过/来访问)  
	const templateUrl = '/template.xlsx';  
	
	// 处理下载的函数  
	const handleDownload = () => {  
		// 创建一个隐藏的<a>标签并触发点击事件来下载文件  
    	const link = document.createElement('a');  
    	link.href = templateUrl;  
    	link.download = '测试.xlsx'; // 可以设置下载时的文件名  
    	document.body.appendChild(link);  
    	link.click();  
    	document.body.removeChild(link); // 下载后移除<a>标签  
	};  
  
	return (<div>
		<button onClick={handleButtonClick}>上传</button>
		<input 
			id="upfile" 
			type="file" 
			style={{ display: "none" }} 
			accept=".xlsx" 
			onChange={handleFileChange} 
		/>
		<button onClick={handleDownload} className="download-button">  
			模板下载
		</button> 
	</div>);
};

export default ReadExcelWord;

http://www.niftyadmin.cn/n/5739851.html

相关文章

区块链技术与应用-PKU 学习笔记

课程地址 资料&#xff1a; ETH-Security 区块链学习记录_比特币 BTC 密码学原理 比特币&#xff0c;又称加密货币(crypto-currency)&#xff0c;它主要利用了密码学中的哈希函数(cryptographic hash function)的抗碰撞特性(collision resistance)和单向散列特性(hiding) …

北京交通大学机器学习实验

机器学习课程概要 &#x1f427;数学基础 &#x1f36c;评估 &#x1f355;线性模型 &#x1f382;神经网络 &#x1f99e;支持向量机 &#x1f402;贝叶斯分类 &#x1f40f;决策树 &#x1f47f;集成学习 ❤️聚类 &#x1f36c;降维与度量学习 &#x1f438;特征选择预稀疏表…

Claude 3.5 Sonnet模型新增了PDF支持功能

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

【深度学习基础】深入理解 卷积与卷积核

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;深度学习_十二月的猫的博客-CSDN博客 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目录 1. 卷积 1.1 …

论文阅读-用于点云分析的自组织网络

目前存在的问题&#xff1a; 原始的SOM&#xff08;1&#xff09;训练结果与初始节点高度相关&#xff08;2&#xff09;样本更新规则取决于输入点的顺序3D 卷积神经网络&#xff08;需要将数据转换为体素&#xff0c;存在分辨率损失和计算成本上涨的问题&#xff09;、PointN…

AIGC学习笔记(4)——AI大模型开发工程师

文章目录 AI大模型开发工程师003 GPT大模型API实战1 Completion API和Chat Completion API学习OpenAI API的意义Completion API和Chat Completion API代码实践2 Chat Completion API详细参数messages可以包含多条信息messages角色设定message之Few-shot效果演示message之Zero-s…

【Java多线程】:理解线程创建、特性及后台进程

&#x1f4c3;个人主页&#xff1a;island1314 ⛺️ 欢迎关注&#xff1a;&#x1f44d;点赞 &#x1f442;&#x1f3fd;留言 &#x1f60d;收藏 &#x1f49e; &#x1f49e; &#x1f49e; 一、背景 -- 进程与线程&#x1f680; &#x1f525; 多线程是提升程序性能非常…

Chromium Mojo(IPC)进程通信演示 c++(1)

网上搜索关于mojo教程 多数都是理论 加上翻译谷歌mojo文档的&#xff0c;但是如何自定义两个进程使用mojo通信呢&#xff1f;看下面的完整例子介绍&#xff1a;&#xff08;本人也是参考谷歌代码例子改编而成&#xff09; 本文演示了client.exe和service.exe 通过mojo::Incomin…