一款纯前端的excel控件,XuY_Sheet 电子表格组件教程

XuY_Sheet 电子表格组件教程,吊打luckysheet

版本 : v1.0.0 | 核心: 基于Canvas的高性能Web电子表格引擎

XuY_Sheet是一个纯原生JavaScript实现的电子表格组件,采用Canvas 5层分层渲染,提供完整的电子表格功能,包括数据管理、22种公式函数、样式控制、事件系统和多工作表支持。所有核心功能均挂载在 window.XuY_Sheet 命名空间下。

目录


快速开始

1. 引入依赖与核心文件

html 复制代码
<!-- 引入依赖库 -->
<script src="./vendor/xlsx.full.min.js"></script>
<script src="./vendor/fflate.min.js"></script>
<script src="./vendor/echarts.min.js"></script>

<!-- 引入核心JS与CSS -->
<script src="./assets/XuY_Sheet.js"></script>
<link rel="stylesheet" href="./assets/XuY_Sheet.css">

2. 初始化控件

在目标容器中调用 window.XuY_Sheet.setOption(obj) 快速构建并初始化控件。

html 复制代码
<div id="demo"></div>
<script>
    // 方式一:传入CSS选择器字符串(推荐)
    const api = window.XuY_Sheet.setOption({ 
        id: '#demo' 
    });

    // 方式二:传入DOM节点
    // const api = window.XuY_Sheet.setOption({ 
    //     id: document.getElementById('demo') 
    // });

    // 可选:指定默认高度(容器无固定高度时生效,默认560px)
    // const api = window.XuY_Sheet.setOption({ 
    //     id: '#demo', 
    //     height: 720 
    // });

    // 初始化后使用API
    api.setCellValue(0, 0, 'Hello XuY_Sheet');
</script>

参数说明:

参数 类型 必填 说明
obj.id `HTMLElement string`
obj.height number 控件默认高度(px),默认560
obj.options object 扩展配置保留位

兼容入口 : init(config)(旧{ container }写法)与 setXuY_Sheet(obj) 均等价于 setOption

3. 访问实例与写入数据

javascript 复制代码
// 通过公共API写入数据(推荐)
window.XuY_Sheet.setCellValue(0, 0, 'Hello XuY_Sheet');

// 或通过内部实例
const { tableStore, canvasRender } = window.ExcelApp.Instance;
tableStore.setCellValue(0, 1, 100);
tableStore.setCellValue(0, 2, 0, '=B1*1.2');
canvasRender.markDirty('text');

4. 监听事件

javascript 复制代码
// 监听单元格值变化
window.XuY_Sheet.on('cellChanged', (data) => {
    console.log(`单元格 (${data.row}, ${data.col}) 变化:`, data.cell);
});

// 监听工作表切换
window.XuY_Sheet.on('sheetActivate', (data) => {
    console.log('切换到:', data.sheetName);
});

// 拦截编辑操作(可取消)
window.XuY_Sheet.on('cellEditBefore', (data) => {
    if (data.row === 0) return false; // 阻止编辑第一行
});

核心API

全局访问入口

入口 类型 说明
window.XuY_Sheet 公共API 推荐的外部调用入口
window.ExcelApp.Instance 内部实例 包含所有核心模块,适合高级定制

核心模块

模块 类名 职责
数据仓库 TableStore 管理数据、样式、边框、合并区域,提供事件系统
选区管理 Selection 管理活动单元格和选区范围
渲染引擎 CanvasRender 5层Canvas分层渲染
公式引擎 Formula 支持22种内置函数
剪贴板 Clipboard 复制/剪切/粘贴
合并管理 MergeCell 合并/拆分单元格
历史记录 History 撤销/重做

单元格操作

javascript 复制代码
// 获取/设置单元格值
tableStore.getCell(row, col);
tableStore.setCellValue(row, col, value, formula);

// 清除单元格
tableStore.clearCell(row, col);      // 清除内容,保留格式
tableStore.clearCellAll(row, col);   // 清除全部
tableStore.clearCellFormat(row, col); // 清除格式,保留内容

// 引用转换
tableStore.colIndexToLabel(27);      // "AB"
tableStore.labelToColIndex('AB');    // 27
tableStore.getCellByRef('A1');       // { row: 0, col: 0 }

样式操作

样式属性一览:

属性 类型 默认值 说明
bgColor string #ffffff 背景颜色
font string Microsoft YaHei 字体族
fontSize number 12 字体大小
bold boolean false 粗体
italic boolean false 斜体
underline string "none" 下划线
strikethrough boolean false 删除线
fontColor string #000000 字体颜色
hAlign string "left" 水平对齐 (left/center/right)
vAlign string "middle" 垂直对齐 (top/middle/bottom)
wrapText boolean false 自动换行
javascript 复制代码
// 设置单元格样式
tableStore.setCellStyle(0, 0, {
    bold: true,
    fontSize: 14,
    fontColor: '#3b82f6',
    bgColor: '#dbeafe',
    hAlign: 'center'
});

// 设置边框
tableStore.setCellBorder(0, 0, {
    top:    { width: 2, color: '#000000', type: 'solid' },
    bottom: { width: 1, color: '#666666', type: 'dashed' }
});

行列操作

javascript 复制代码
// 插入/删除
tableStore.insertRow(1);      // 在第2行前插入
tableStore.deleteRow(1);      // 删除第2行
tableStore.insertCol(1);      // 在B列前插入
tableStore.deleteCol(1);      // 删除B列

// 隐藏/显示
tableStore.hideCol(1);
tableStore.showCol(1);

// 尺寸设置
tableStore.setColWidth(0, 120);
tableStore.setRowHeight(0, 30);

// 合并操作
tableStore.setMergeRange(0, 0, 2, 2);  // 合并A1:C3
tableStore.removeMerge(0, 0);           // 拆分
tableStore.isMerged(0, 0);             // 判断是否在合并区域内

事件系统

javascript 复制代码
// 注册/移除监听
tableStore.on('cellChanged', callback);
tableStore.off('cellChanged', callback);

// 触发事件
tableStore.emit('customEvent', data);
const allowed = tableStore.emitCancelable('customAction', data);
if (!allowed) console.log('操作被阻止');

序列化存储

javascript 复制代码
// 导出为JSON
const json = tableStore.toJSON();

// 从JSON恢复
tableStore.fromJSON(data);

// 导出到服务端(Excel文件)
await tableStore.exportToServer('mySpreadsheet.xlsx');

文件导入

通过 importFile 方法导入 .xls / .xlsx / .csv 文件。

javascript 复制代码
// 相对路径导入
const res = await window.XuY_Sheet.importFile('test-fixtures/data.xlsx');

// 绝对路径导入
await window.XuY_Sheet.importFile('C:\\Users\\data.xls');
await window.XuY_Sheet.importFile('/home/user/report.csv');

// 返回值示例
console.log(res.sheetCount, res.totalRows, res.totalCols);
/* 返回:
{
  success: true,
  fileName: 'data.xlsx',
  format: 'xlsx',
  sheetCount: 3,
  totalRows: 100,
  totalCols: 10,
  sheets: [{ name: 'Sheet1', rows: 50, cols: 5 }, ...]
}
*/

// 错误处理
try {
    await window.XuY_Sheet.importFile('not_exists.xlsx');
} catch (e) {
    console.error('导入失败:', e.message);
}

支持格式与限制:

格式 扩展名 说明
Excel 2007+ .xlsx 完整还原样式、合并区域、多工作表
Excel 97-2003 .xls 还原字体、边框、对齐等
CSV .csv 自动识别编码(UTF-8/GBK/GB18030)

控制API

顶部菜单显隐

javascript 复制代码
// 显示/隐藏/切换
XuY_Sheet.showTopMenu();          // true
XuY_Sheet.hideTopMenu();          // false
XuY_Sheet.toggleTopMenu();        // 返回切换后的状态
XuY_Sheet.isTopMenuVisible();     // 查询状态
XuY_Sheet.setTopMenuVisible(false);

单元格编辑权限

javascript 复制代码
// 锁定/解锁单元格
XuY_Sheet.lockCell(2, 0);              // 锁定A3
XuY_Sheet.unlockCell(2, 0);            // 解锁A3
XuY_Sheet.isCellLocked(2, 0);          // true/false
XuY_Sheet.isCellEditable(2, 0);        // 综合判断
XuY_Sheet.getLockedCells();            // 获取所有锁定单元格

行列尺寸冻结

javascript 复制代码
// 冻结行高/列宽
XuY_Sheet.freezeRowHeight(0);          // 冻结第1行行高
XuY_Sheet.unfreezeRowHeight(0);        // 解除
XuY_Sheet.isRowHeightFrozen(0);        // true/false

XuY_Sheet.freezeColWidth(1);           // 冻结B列列宽
XuY_Sheet.unfreezeColWidth(1);
XuY_Sheet.isColWidthFrozen(1);

全局只读开关

javascript 复制代码
XuY_Sheet.setGlobalReadonly(true);     // 全表只读
XuY_Sheet.isGlobalReadonly();          // true
XuY_Sheet.setGlobalReadonly(false);    // 恢复(单元格锁仍生效)

优先级:单元格可编辑 = 全局只读未开启 && 单元格未被单独锁定

内容查询与替换

javascript 复制代码
// 搜索(不区分大小写)
XuY_Sheet.searchCells('A1:C3', 'XuY_Sheet');
// => ["A1", "B2"]

// 替换(跳过锁定与只读单元格)
XuY_Sheet.replaceCells('A1:C3', '旧文本', '新文本');
// => 返回实际被替换的坐标数组

生命周期钩子

数据事件

事件名 参数 说明
cellChanged { row, col, cell } 单元格值改变后触发
cellUpdated { row, col, oldValue, newValue, oldFormula, newFormula } 包含新旧值对比
styleChanged { row, col, style, border } 样式/边框改变后触发
dataLoadBefore { fileName, fileType, fileSize } 文件解析开始前触发
dataLoadAfter { fileName, sheetCount, duration, success, error } 加载完成后触发

编辑事件

事件名 参数 可取消
cellEditBefore { row, col, cellRef, source }
cellMousedownBefore { row, col, cellRef, button, ctrlKey, shiftKey }
cellClick { row, col, cellRef }
cellDblClick { row, col, cellRef }

工作表事件

事件名 参数 说明
sheetActivate { activeSheetIndex, previousIndex, sheetName } 工作表切换
sheetChanged { action, activeSheetIndex, removedIndex, fromIndex, toIndex } 结构变化
sheetRenamed { index, name } 重命名
dataReset {} 数据整体重置

结构事件

事件名 参数 说明
rowInserted { beforeRow } 插入行
rowDeleted { row } 删除行
colInserted { beforeCol } 插入列
colDeleted { col } 删除列
sizeChanged { type, index, size } 行高/列宽变化
mergeChanged { startRow, startCol, endRow, endCol, action } 合并/拆分

粘贴事件

事件名 参数 可取消
rangePasteBefore { startRow, startCol, endRow, endCol, clipboardData, dataPreview }

公式函数

聚合函数

函数 语法示例 说明
SUM =SUM(A1:A10) 求和
AVERAGE =AVERAGE(A1:A10) 平均值
MAX =MAX(A1:A10) 最大值
MIN =MIN(A1:A10) 最小值
COUNT =COUNT(A1:A10) 数值个数
COUNTA =COUNTA(A1:A10) 非空个数

逻辑函数

函数 语法示例 说明
IF =IF(B1>=60,"及格","不及格") 条件判断,支持嵌套

数学函数

函数 语法示例 说明
ROUND =ROUND(A1, 2) 四舍五入
ABS =ABS(A1) 绝对值
INT =INT(A1) 向下取整
MOD =MOD(A1, 2) 取余
POWER =POWER(A1, 2) 幂运算
SQRT =SQRT(A1) 平方根

文本函数

函数 语法示例 说明
CONCATENATE =CONCATENATE(A1, " ", B1) 拼接文本
LEFT =LEFT(A1, 6) 左侧提取
RIGHT =RIGHT(A1, 6) 右侧提取
LEN =LEN(A1) 字符长度
TRIM =TRIM(A1) 去除首尾空格
UPPER =UPPER(A1) 转大写
LOWER =LOWER(A1) 转小写

日期时间函数

函数 语法示例 说明
NOW =NOW() 当前日期时间
TODAY =TODAY() 当前日期

常见问题

Q: 如何保护某些单元格不被编辑?

方法一: 监听 cellEditBefore 事件

javascript 复制代码
window.XuY_Sheet.on('cellEditBefore', (data) => {
    if (data.row === 0) return false; // 禁止编辑第一行
});

方法二: 使用便捷方法

javascript 复制代码
XuY_Sheet.setCellReadonly(0, 0, true);

Q: 数据是否会自动保存?

XuY_Sheet已移除localStorage自动缓存机制,每次加载均为默认空表。如需持久化:

javascript 复制代码
// 获取数据快照
const json = tableStore.toJSON();

// 或导出到服务端
await tableStore.exportToServer('myFile.xlsx');

Q: 如何在自定义容器中初始化?

javascript 复制代码
// 方式一:CSS选择器字符串
window.XuY_Sheet.setOption({ id: '#myContainer' });

// 方式二:DOM节点
window.XuY_Sheet.setOption({ id: document.getElementById('myContainer') });

Q: 支持哪些公式?

内置22种公式函数,支持四则运算、比较运算、单元格与区域引用、函数嵌套。

Q: 公共API和内部实例有什么区别?

window.XuY_Sheet window.ExcelApp.Instance
定位 推荐的外部调用入口 内部实例对象
包含 常用封装方法 所有核心模块(tableStore, selection, canvasRender...)
适用 日常操作 深度定制场景

Q: 界面不刷新/数据更新后无变化?

在修改数据或样式后,需要标记脏层并触发重绘:

javascript 复制代码
tableStore.setCellStyle(0, 0, { bold: true });
canvasRender.markDirty('text');
canvasRender.markDirty('background');
canvasRender.forceRenderAll();

完整API文档: 如需查看所有详细信息和示例,请参考原HTML文档。

Gitee、Github搜索 XuY_Sheet

相关推荐
不爱说话郭德纲1 小时前
零基础,学做KMP项目,TRAE Work手把手带你月薪.....
前端·后端·app
敲代码的玉米C2 小时前
Agent 做 IDE
前端·人工智能·开源
鹏北海2 小时前
AI 全栈时代的多语言 SDK 版本管理:认识 mise
前端·后端
下山2 小时前
别再手切终端管 Agent 了!1 个 Skill 监督多个主流 CLI,默认每 15 秒读屏(建议收藏)🚀
前端·ai编程
飘逸啊2 小时前
分而治之:关注点分离在Android与React中的架构实践与对比
前端
算法解题那些事2 小时前
前端暑期实习面经(网上收集)
前端
敲代码的玉米C2 小时前
补 322 个测试,挖出 19 个 bug
前端·人工智能·架构
敲代码的玉米C2 小时前
怎么让 Agent 没法假装自己成功了
前端·人工智能·架构
涛涛ing2 小时前
狂揽2.4万星标:一行命令,AI会自己找技能了
前端