自己做的网站加载慢的原因delphi 做直播网站
在 Web 应用中,处理表格数据并提供 Excel 级的功能(如公式计算、数据导入导出)一直是个挑战。今天,我将带你使用 React + Handsontable 搭建一个强大的 Excel 风格表格,支持 公式计算、Excel 文件导入导出,并实现 动态单元格样式。
🎯 项目目标
-  ✅ 创建一个可编辑的 Excel 风格表格 
-  ✅ 支持 Excel 公式解析(如 =B1+10)
-  ✅ 支持 Excel 文件导入/导出(.xlsx/.xls) 
-  ✅ 实现 单元格动态渲染(如公式高亮) 
📦 依赖安装
首先,确保你的 React 项目已创建(若没有,可用 npx create-react-app my-app 创建)。然后,安装必要的依赖项:
npm install @handsontable/react handsontable mathjs xlsx react-i18next
📌 核心代码解析
1️⃣ 创建 Excel 风格的 Handsontable 表格
import React, { useState } from 'react';
import { HotTable } from '@handsontable/react';
import { useTranslation } from 'react-i18next';
import * as math from 'mathjs';
import * as XLSX from 'xlsx';
import 'handsontable/dist/handsontable.full.min.css';const ExcelTable = () => {const { t } = useTranslation();const [data, setData] = useState([[t('name'), t('age'), t('city'), 'Total'],['John', 30, 'New York', '=B1+10'],['Alice', 25, 'London', '=B2*2'],]);
-  useState初始化数据,支持 公式输入(如=B1+10)
-  Handsontable 是一个轻量级但功能强大的表格库,支持 Excel 风格的操作 
2️⃣ 实现公式计算功能
const calculateFormula = (value, row, col, dataArray) => {if (typeof value === 'string' && value.startsWith('=')) {try {const formula = value.slice(1).replace(/[A-Z]\d+/g, (cell) => {const colLetter = cell.match(/[A-Z]/)[0];const rowNum = parseInt(cell.match(/\d+/)[0], 10) - 1;const colNum = colLetter.charCodeAt(0) - 65;return dataArray[rowNum][colNum];});return math.evaluate(formula);} catch (e) {return '#ERROR';}}return value;
};
-  解析 Excel 格式的公式( =B1+10)
-  将公式转换为 数学计算表达式 并使用 math.evaluate()计算结果
-  错误处理:如果解析失败,返回 #ERROR
3️⃣ 实现 Excel 文件导入功能
const handleImport = (event) => {const file = event.target.files[0];const reader = new FileReader();reader.onload = (e) => {const binaryStr = e.target.result;const workbook = XLSX.read(binaryStr, { type: 'binary' });const sheetName = workbook.SheetNames[0];const sheet = workbook.Sheets[sheetName];const importedData = XLSX.utils.sheet_to_json(sheet, { header: 1 });setData(importedData);};reader.readAsBinaryString(file);
};
-  用户选择 Excel 文件 
-  解析 Excel 数据 并转换为 JavaScript 数组 
-  更新 Handsontable 的 data以渲染新数据
4️⃣ 实现 Excel 文件导出功能
const handleExport = () => {const ws = XLSX.utils.aoa_to_sheet(data);const wb = XLSX.utils.book_new();XLSX.utils.book_append_sheet(wb, ws, 'Sheet1');XLSX.writeFile(wb, 'exported_excel.xlsx');
};
-  将 Handsontable 数据 转换为 Excel sheet 
-  创建新的 Excel 工作簿 
-  下载 Excel 文件,实现 导出功能 
5️⃣ 动态单元格渲染(公式高亮)
<HotTabledata={data}rowHeaders={true}colHeaders={true}contextMenu={true}stretchH="all"beforeChange={(changes) => {changes.forEach(([row, col, , newValue]) => {data[row][col] = newValue;});setData([...data]);}}afterGetCellMeta={(row, col, cellProperties) => {const value = data[row][col];if (typeof value === 'string' && value.startsWith('=')) {cellProperties.readOnly = false;cellProperties.renderer = (instance, td, r, c, prop, val) => {const result = calculateFormula(val, r, c, data);td.innerHTML = result;td.style.backgroundColor = '#e0f7fa'; // 公式单元格高亮};} else {cellProperties.renderer = (instance, td, r, c, prop, val) => {td.innerHTML = val;td.style.backgroundColor = '#ffffff'; // 普通单元格白色背景};}}}cells={(row, col) => {const cellProperties = {};if (row === 0) {cellProperties.className = 'header-cell'; // 表头样式}return cellProperties;}}licenseKey="non-commercial-and-evaluation"
/>
-  检测单元格是否包含公式 
-  动态渲染公式计算结果 
-  高亮公式单元格 以增强用户体验 
完整代码
// src/components/ExcelTable.jsx
import React, { useState } from 'react';
import { HotTable } from '@handsontable/react';
import { useTranslation } from 'react-i18next';
import * as math from 'mathjs';
import * as XLSX from 'xlsx';
import 'handsontable/dist/handsontable.full.min.css';const ExcelTable = () => {const { t } = useTranslation();const [data, setData] = useState([[t('name'), t('age'), t('city'), 'Total'],['John', 30, 'New York', '=B1+10'],['Alice', 25, 'London', '=B2*2'],]);// 计算公式const calculateFormula = (value, row, col, dataArray) => {if (typeof value === 'string' && value.startsWith('=')) {try {const formula = value.slice(1).replace(/[A-Z]\d+/g, (cell) => {const colLetter = cell.match(/[A-Z]/)[0];const rowNum = parseInt(cell.match(/\d+/)[0], 10) - 1;const colNum = colLetter.charCodeAt(0) - 65;return dataArray[rowNum][colNum];});return math.evaluate(formula);} catch (e) {return '#ERROR';}}return value;};// 导入 Excel 文件const handleImport = (event) => {const file = event.target.files[0];const reader = new FileReader();reader.onload = (e) => {const binaryStr = e.target.result;const workbook = XLSX.read(binaryStr, { type: 'binary' });const sheetName = workbook.SheetNames[0];const sheet = workbook.Sheets[sheetName];const importedData = XLSX.utils.sheet_to_json(sheet, { header: 1 });setData(importedData);};reader.readAsBinaryString(file);};// 导出 Excel 文件const handleExport = () => {const ws = XLSX.utils.aoa_to_sheet(data);const wb = XLSX.utils.book_new();XLSX.utils.book_append_sheet(wb, ws, 'Sheet1');XLSX.writeFile(wb, 'exported_excel.xlsx');};return (<div><div style={{ marginBottom: '10px' }}><input type="file" accept=".xlsx, .xls" onChange={handleImport} /><button onClick={handleExport}>Export to Excel</button></div><HotTabledata={data}rowHeaders={true}colHeaders={true}contextMenu={true}stretchH="all"beforeChange={(changes) => {changes.forEach(([row, col, , newValue]) => {data[row][col] = newValue;});setData([...data]);}}afterGetCellMeta={(row, col, cellProperties) => {const value = data[row][col];if (typeof value === 'string' && value.startsWith('=')) {cellProperties.readOnly = false;cellProperties.renderer = (instance, td, r, c, prop, val) => {const result = calculateFormula(val, r, c, data);td.innerHTML = result;td.style.backgroundColor = '#e0f7fa'; // 公式单元格高亮};} else {cellProperties.renderer = (instance, td, r, c, prop, val) => {td.innerHTML = val;td.style.backgroundColor = '#ffffff'; // 普通单元格白色背景};}}}cells={(row, col) => {const cellProperties = {};if (row === 0) {cellProperties.className = 'header-cell'; // 表头样式}return cellProperties;}}licenseKey="non-commercial-and-evaluation"/><style jsx>{.header-cell {background-color: #f0f0f0;font-weight: bold;}}</style></div>);
};export default ExcelTable; 🎉 运行效果
🚀 你现在拥有了一个 功能强大的 Excel 风格表格,支持:
 ✅ 公式计算(自动计算 =B1+10)
 ✅ Excel 文件导入/导出
 ✅ 动态高亮公式单元格
 ✅ 行列可编辑 & 右键菜单操作
💡 总结
通过 Handsontable + mathjs + xlsx,我们轻松构建了一个 Excel 风格的动态表格。这一方案适用于 财务管理、数据分析、在线表单应用 等场景,提升了数据处理的灵活性!
🔹 完整代码已上传 GitHub(可在评论区留言获取)
 🔹 你对这个 Excel 组件有什么优化建议?欢迎评论交流!
🔥 如果觉得有帮助,别忘了点赞 + 收藏! 🎯
