
从零手写一个电子表格引擎cmx-megasheet 核心功能全解析零运行时依赖、纯 Web Components 的 TypeScript 电子表格引擎 —— 一个cmx-megasheet自定义元素自带画布渲染、公式引擎与 IO。本文用真机截图逐块拆解它的核心能力。前言cmx-megasheet是一套自研的电子表格引擎几个硬指标先摆出来零运行时依赖dependencies: {}。ZIP、DEFLATE、XLSX、PDF、图表、公式引擎全部手写。纯 Web Components一个cmx-megasheet自定义元素Shadow DOM 隔离零框架可渐进嵌入任意宿主页面。335 个内置函数覆盖 Excel 数学/统计/财务/文本/查找/日期/工程/数据库各族。945 单元测试常绿26 个里程碑演示页每页真机自检。下面每张截图都是真实cmx-megasheet元素铺真数据跑出来的右侧「自检」面板是在真浏览器里跑的断言绿灯代表该功能此刻真实生效配上对应的技术说明。一、core 数据模型坐标系 稀疏矩阵一切从数据模型开始。层级是Workbook → Worksheet[] → 稀疏单元格矩阵坐标系A1 地址 ↔ 0-based 行列索引双向互转支持相对/绝对$A$1、跨表Sheet1!A1、整列A:A、整行1:1。稀疏矩阵SparseMatrix只存非空单元格百万行表也不撑内存。样式级联每个 Worksheet 自持命名样式表StyleSheet单元格可内联样式或引用命名样式。单元格记录值 / 公式 / 样式 / 富文本四者稀疏并存。import{Workbook,Worksheet}fromcmx/megasheetconstwbnewWorkbook({sheetCount:0})constwsnewWorksheet(Sheet1,{rowCount:100,colCount:26,styleSheet:wb.styleSheet})wb.appendSheet(ws)ws.setValue(0,0,销售)ws.setValue(1,0,100)二、公式引擎Pratt 解析 依赖图重算公式求值管线公式串 → 词法分析 → Pratt 语法分析(AST) → 求值 → 结果。Pratt 解析手写 Tokenizer Pratt Parser输出 AST。依赖图从 AST 抽取依赖拓扑排序后按序重算三色标记环检测循环引用返回#CIRC!。增量重算编辑单格只重算受影响的闭包大表从 O(全簿) 降到 O(受影响)。整列/整行钳制SUM(A:A)钳到 sheet 实际维度不遍历百万空格。import{FormulaEngine}fromcmx/megasheetws.setFormula(1,0,SUM(A1:A1)*2)newFormulaEngine(wb).recalcAll()// A2 → 84// 也可不落格直接求值el.evaluateFormula(SUM(A1:A5),row,col)一个设计约束值得说明引擎的FormulaValue是标量类型number | string | boolean | error | null单元格返回单值因此依赖动态数组溢出的函数FILTER/SORT/UNIQUE/SEQUENCE 等不在实现范围内 —— 这是刻意的取舍聚焦财务报表类场景。三、数字格式引擎Excel 格式串编译执行TEXT()函数和单元格显示值共用同一套数字格式引擎numFmt/compile.tsapply.ts格式串编译为最多4 区段正 / 负 / 零 / 文本。数字缩放、百分号、千分位、科学计数、分数、补零。日期yyyy-mm-dd、mmm、dddd、[h]经过时间、AM/PM基于 1900 日期序列号。颜色段[Red]等条件段[100]等。el.evaluateFormula(TEXT(1234.5, #,##0.00))// 1,234.50el.evaluateFormula(TEXT(0.85, 0.0%))// 85.0%四、函数库335 个内置函数按族组织覆盖 Excel 常用面族示例数学/三角SINCOSLNLOGFACTCOMBINCEILING.MATHROMAN财务PMTFVPVNPVIRRXIRRMIRRSLNDDB统计GEOMEANCORRELSLOPEQUARTILENORM.DISTPERCENTRANK查找引用VLOOKUPHLOOKUPINDEXMATCHXLOOKUPADDRESSINDIRECT文本TEXTLEFTMIDSUBSTITUTETEXTJOINTEXTBEFORE数据库 D 函数DSUMDGETDCOUNTDAVERAGE日期时间DATEEOMONTHNETWORKDAYSYEARFRACWEEKNUMWORKDAY.INTL工程进制转换BIN2DEC/DEC2HEX、位运算BITAND/BITXOR、ERF、贝塞尔BESSELJ、CONVERT、复数COMPLEX/IMSUM/IMSQRT还支持命名区域SUM(SALES)、数组字面量SUM({1,2;3,4})、多条件聚合SUMIFS/COUNTIFS通配符*?。el.evaluateFormula(VLOOKUP(40, A1:B5, 2, FALSE))el.evaluateFormula(SUMIFS(A1:A5, B1:B5, x))el.defineName(SALES,A1:A5)el.evaluateFormula(SUM(SALES))五、冻结窗格四象限 / 尾冻结 / 拆分窗格布局PaneLayout.ts基于一条几何不变式getCellRect(r,c)行列 → 像素与hitTest(x,y)像素 → 行列严格互逆跨冻结、拆分、滚动、缩放恒成立。冻结窗格钉顶部行 / 左侧列滚动时表头不动。尾冻结钉底部行 / 右侧列合计行不随滚动象限从 4 扩到 9。拆分窗格可拖动分隔条上下共享 scrollTop、左右共享 scrollLeft。el.freezePanes(1,1)// 冻结首行首列el.freezeTrailing(1,0)// 尾冻结底部 1 行el.splitPanes(3,2)// 在 3 行 2 列处拆分六、查找 / 排序 / 筛选查找findAll支持正则、大小写、全字匹配、限定区域。排序多关键字、类型感知空值末位、数字先于文本稳定排列。自动筛选列头下拉值白名单 条件等于/大于/包含/介于/topN筛选隐藏与大纲隐藏、手动隐藏三向分账。el.sortRange(A1:C10,[{col:1,asc:false}])el.setAutoFilter(A1:C10)el.applyFilter(1,{values:[x,y]})el.replaceAll(旧值,新值)七、富文本与条件格式富文本单个格内混合字体、字号、颜色RichText/RichRun。条件格式4 类规则求值后叠加显示不改数据本身cellValue比较规则大于/介于/重复/唯一/top-bottomcolorScale2/3 色阶插值dataBar数据条iconSet图标集el.addConditionalRule(B2:B10,{type:colorScale,colors:[#f00,#ff0,#0f0]})el.addConditionalRule(C2:C10,{type:dataBar,barColor:#4f8cff})el.setRichText(0,0,{runs:[{text:红,font:{foreColor:#e00,bold:true}},{text:黑},]})八、图表11 类手写零依赖 主题自适应浮动对象层floatingObjects承载图表 / 图片 / 形状 / 批注双格锚点经getCellRect换算滚动、缩放、冻结象限自动跟随。图表drawChart.ts支持11 类column / bar / line / area / pie / doughnut / scatter / bubble / radar / stock(OHLC) / combo含图例、数据标签、趋势线、双轴。配色分离设计系列数据色固定不变对齐 Excel只有背景 / 边框 / 坐标轴 / 网格 / 标签 / 图例文字跟随 light/dark 主题切换 —— 深色模式下图表不再是刺眼的白框。el.insertChart(A1,B2:C6,{type:column,title:季度销量,legend:true})el.insertShape(D14,{kind:ellipse})el.addComment(0,0,{text:此季度需复核,author:admin})九、迷你图Sparkline格内 7 型微图drawSparkline.ts在单元格内绘制 7 型微图line/area/column/winloss/bar/pie/bullet支持高低点、首末点、标记。复用图表绘制原语随快照往返。el.setSparkline(0,3,{type:line,dataRange:A1:C1,highLow:true})el.setSparkline(1,3,{type:winloss,dataRange:A2:F2})十、IOXLSX 全保真 CSV PDF 中性快照全部零依赖手写XLSXZIP 容器 DEFLATE 压缩 手写 OOXML。值/公式/样式/合并/行列尺寸/多表/冻结/筛选/验证/多级分组/页面设置全保真openpyxl 可互通读。CSVRFC-4180 引号转义分隔符可选可选 BOM。HTML / PDFHTML 带条件格式底色零依赖手写 PDF真浏览器可解析PDF 内置字体覆盖 ASCII/拉丁CJK 走外部 TrueType 字体。中性快照format: cmx-megasheet的稀疏 JSON不含视图态是数据的单一事实源。constbytesel.exportXlsx()// → Uint8Arrayel.importXlsx(bytes)constcsvel.exportCsv()constpdfel.exportPdf()constjsonel.getWorkbookJson()// 中性快照一个导入细节Excel/SpreadJS 序列化公式会给函数名加_xlfn./_xlws.伪前缀或前导引擎在导入边界统一清洗sanitizeImportedFormula避免ROW()-3这类公式因伪前缀被误判为未知函数而报#NAME?。十一、综合演示六场景一页跑M99 把六种能力放在一个工作簿的六个 sheet 里页签切换迷你图 7 型 / 行三级分组 / 列三级分组 / 行列双三级 / 全样式字体·背景·边框·旋转/ 图表 11 类全部随快照无损往返。组件接入作为自定义元素cmx-megasheetidsheetstylewidth:100%;height:500px/cmx-megasheetscripttypemoduleimport./dist/index.js// 导入即注册 cmx-megasheetconsteldocument.getElementById(sheet)el.setTheme(light)// light | dark | autoel.loadWorkbook((wb){wb.clearSheets()constsnewCmxMegaSheet.Worksheet(Sheet1,{rowCount:100,colCount:26,styleSheet:wb.styleSheet})s.getCell(0,0).value(销售)s.getCell(1,0).value(100)s.getCell(2,0).formula(A2*1.1)wb.appendSheet(s)})el.recalc()/script事件el.addEventListener(cmx-cell-selected,econsole.log(e.detail.addr))el.addEventListener(cmx-cell-edited,econsole.log(e.detail.addr,e.detail.value))支持事件cmx-cell-selected/cmx-cell-edited/cmx-sheet-changed/cmx-col-resized/cmx-row-resized/cmx-edit-rejected/cmx-structural-changed。逃生舱getWorkbook()返回底层Workbook宿主可直接调Worksheet原生方法getValue/setValue/getFormula/getCellRect/hitTest等无缝对接既有代码。小结cmx-megasheet用一个自定义元素封装了完整的电子表格能力坐标系与稀疏矩阵打底Pratt 公式引擎 依赖图重算算数画布渲染层保证「画点」几何不变式IO 层零依赖手写 XLSX/CSV/PDF。335 个内置函数、11 类图表、7 型迷你图、条件格式、多级分组、冻结/拆分窗格 —— Excel 常用面基本覆盖且全程零运行时依赖、纯 Web 标准。对「想读懂电子表格每一个齿轮」或「需要一个可嵌入、无框架锁定、可离线出 XLSX/PDF 的表格组件」的场景这套引擎提供了一条 clean-room 的实现路径。