前言
最近项目需要做个Excel导入功能,网上找了一圈发现要么太复杂要么不能用,干脆自己写一个。这篇文章就是记录整个开发过程,代码可以直接复制粘贴到你的项目里用。
先看看效果
这个组件能干啥:
- 上传Excel文件(.xlsx和.xls都支持)
- 自动识别表格内容,第一行当表头
- 支持多个工作表切换
- 数据预览,还能编辑
- 一键导入到系统
开始写代码
第一步:安装依赖
npm install xlsx antd
第二步:创建组件
ini
import { Button, Select, Table, Upload, Modal } from "antd";
import { useState } from "react";
import * as XLSX from "xlsx";
const TableDataImport = () => {
// 这些状态用来存数据
const [tableData, setTableData] = useState([]); // 表格数据
const [columns, setColumns] = useState([]); // 表格列
const [tableLoading, setTableLoading] = useState(false); // 加载状态
const [tableFile, setTableFile] = useState(); // 上传的文件
const [sheetNames, setSheetNames] = useState([]); // 工作表列表
const [isModalOpen, setIsModalOpen] = useState(false); // 弹窗显示
// 核心方法:处理文件上传
const handleUpload = (file, sheetName) => {
// 清空之前的数据
setColumns([]);
setTableData([]);
setTableLoading(true);
// 用FileReader读文件
const reader = new FileReader();
reader.onload = (e) => {
// 把文件转成数组
const data = new Uint8Array(e.target.result);
// 用xlsx库读Excel
const workbook = XLSX.read(data, { type: "array" });
// 获取工作表(如果指定了就用指定的,否则用第一个)
const worksheet = sheetName
? workbook.Sheets[sheetName]
: workbook.Sheets[workbook.SheetNames[0]];
// 转成JSON数据
const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1 });
// 处理数据:第一行当表头,后面的当数据
if (jsonData.length > 0) {
const newData = [];
jsonData.slice(1).forEach((item, itemIndex) => {
if (item.length === 0) return;
const obj = { key: itemIndex };
// 把表头和数据对应起来
jsonData[0].forEach((header, index) => {
obj[header] = item[index];
});
newData.push(obj);
});
// 生成表格列配置
const columns = jsonData[0].map(header => ({
title: header,
dataIndex: header,
key: header,
align: "center",
}));
setColumns(columns);
setTableData(newData);
}
setTableLoading(false);
};
reader.readAsArrayBuffer(file);
};
// 切换工作表
const handleChange = (value) => {
if (tableFile) handleUpload(tableFile, value);
};
// 确定导入
const handleOk = () => {
// 这里调用你的导入接口
console.log('要导入的数据:', tableData);
setIsModalOpen(false);
// 清空数据
setTableData([]);
setColumns([]);
};
return (
<div>
{/* 弹窗 */}
<Modal
title="Excel导入"
open={isModalOpen}
onOk={handleOk}
onCancel={() => setIsModalOpen(false)}
width={800}
okText="导入"
cancelText="取消"
>
<div style={{ margin: "20px 0" }}>
{/* 文件上传 */}
<Upload
beforeUpload={(file) => {
// 检查文件类型
const isExcel = /.(xlsx|xls)$/.test(file.name.toLowerCase());
if (!isExcel) {
alert("请上传Excel文件(.xlsx 或 .xls)");
return false;
}
setTableFile(file);
handleUpload(file);
return false; // 阻止自动上传
}}
>
<Button>上传Excel文件</Button>
</Upload>
{/* 工作表选择 */}
{sheetNames.length > 0 && (
<div style={{ marginTop: 20 }}>
<span>选择工作表:</span>
<Select
style={{ width: 200, marginLeft: 10 }}
onChange={handleChange}
options={sheetNames.map(name => ({
label: name,
value: name
}))}
/>
</div>
)}
</div>
{/* 数据预览表格 */}
<Table
loading={tableLoading}
dataSource={tableData}
columns={columns}
scroll={{ y: 400 }}
size="small"
/>
</Modal>
{/* 触发按钮 */}
<Button onClick={() => setIsModalOpen(true)} type="primary">
导入Excel
</Button>
</div>
);
};
export default TableDataImport;
关键点解释
1. 文件读取流程
javascript
用户上传文件 → FileReader读取 → xlsx库解析 → 转成JSON → 显示在表格里
2. 数据转换逻辑
Excel的第一行自动变成表格的表头,下面的行变成数据行。比如:
css
Excel内容:
姓名 年龄 城市
张三 25 北京
李四 30 上海
转换后:
columns: [{title: '姓名', dataIndex: '姓名'}, {title: '年龄', dataIndex: '年龄'}, {title: '城市', dataIndex: '城市'}]
data: [{姓名: '张三', 年龄: 25, 城市: '北京'}, {姓名: '李四', 年龄: 30, 城市: '上海'}]
3. 工作表切换
如果你的Excel有多个工作表,组件会自动识别并让你选择用哪个。
怎么用
1. 复制代码到你的项目
把上面的代码复制到一个新文件,比如 ExcelImport.tsx
2. 在需要的地方引入
javascript
import ExcelImport from './ExcelImport';
// 在你的页面里
<ExcelImport />
3. 修改导入逻辑
在 handleOk 方法里,把 console.log 改成你的实际导入逻辑:
scss
const handleOk = () => {
// 调用你的API
api.importData(tableData).then(() => {
message.success('导入成功!');
setIsModalOpen(false);
});
};
常见问题
Q: 为什么上传文件后没反应?
A: 检查浏览器控制台有没有报错,通常是文件格式不对或者xlsx库没装好。
Q: 数据格式不对怎么办?
A: 确保Excel第一行是表头,数据从第二行开始。空行会被自动过滤掉。
Q: 想支持更多文件格式?
A: 在 beforeUpload 里加文件类型判断就行。
总结
这个组件其实不难,核心就是:
- 用FileReader读文件
- 用xlsx库解析Excel
- 把数据转成表格能用的格式
本期内容就到这里,各位大佬觉得有用可以收藏+关注,另外主页有火柴能点着的干货哦!!