ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

开源原生Web Component标准的电子表格组件

开源原生Web Component标准的电子表格组件 cmx-megasheet 技术文档包名cmx/megasheet版本7.5.2模块类型ESMtype: module运行时依赖无dependencies: {}开发依赖typescript、vitest交付形态自定义元素cmx-megasheet 可导入的库模块dist/index.js.d.ts目标环境支持 Canvas 2D、Web Components、Shadow DOM 的浏览器内置函数335单元测试1022 通过 / 1 跳过仓库https://gitcode.com/warpdrivelabs/cmx-mega-sheet1. 架构分层源码位于src/分五层。src/ ├── core/ 数据模型无 DOM 依赖 ├── formula/ 公式引擎无 DOM 依赖 ├── render/ 渲染与交互面向抽象 RenderContext2D 接口 ├── io/ 导入导出 ├── element/ cmx-megasheet 自定义元素 └── index.ts 统一导出层间依赖方向element → render → formula → coreio → core。core与formula不引用 DOM 类型。1.1 core文件内容Workbook.ts工作簿sheet 集合、活动 sheet、命名区域、重算钩子、撤销栈Worksheet.ts工作表单元格矩阵、行列尺寸、合并、大纲分组、冻结/拆分视口态、数据验证、条件格式、超链接、迷你图、浮动对象、保护Cell.ts单元格数据记录值/公式/样式/富文本normalizeFormula、sanitizeImportedFormulaSparseMatrix.ts稀疏矩阵存储Range.ts/address.ts区域代数A1 地址 ↔ 行列索引互转Style.ts样式属性集、命名样式表SelectionModel.ts多区选择模型EditCommands.ts快照命令撤销/重做Clipboard.ts内部剪贴板、选择性粘贴FillEngine.ts自动填充序列推断find.ts/sort.ts/validation.ts查找、排序、值校验dateSerial.ts1900 日期序列号换算EventEmitter.ts事件发射器1.2 formula文件内容Tokenizer.ts词法分析数字/字符串/引用/区域/标识符/运算符Parser.tsPratt 语法分析 → ASTEvaluator.tsAST 求值CellAccessor、EvalContext、FunctionImpl接口functions.ts核心内置函数 BuiltinRegistryBUILTIN_NAMESbuiltins/分族函数模块mathfinancialstatisticaldatabasetextrefengineeringhelpersDependencyGraph.ts依赖图、拓扑排序、三色标记环检测FormulaEngine.ts编排层全量重算、增量重算CustomFunction.ts报表取数函数QM/QC/JE/FS/REF查值表refTransform.ts词法级引用平移插删行列时调整公式value.tsFormulaValue、FormulaError类型1.3 render文件内容SheetGeometry.ts单元格几何getCellRect(r,c)与hitTest(x,y)PaneLayout.ts冻结/尾冻结/拆分窗格分带布局Viewport.ts/AxisMetrics.ts视口虚拟化、行列尺寸度量SheetRenderer.ts主渲染器面向RenderContext2D接口InteractionController.ts鼠标/键盘交互、右键菜单、拖拽CellEditor.ts单元格编辑器SheetTabStrip.ts页签栏ScrollbarLayout.ts自绘滚动条OutlineLayout.ts大纲分组按钮布局condFormat.ts条件格式求值叠加numFmt/compile.ts/numFmt/apply.ts数字格式串编译与执行chart/drawChart.ts/chart/drawSparkline.ts图表与迷你图绘制overlay/FloatingLayout.ts浮动对象几何锚定formatValue.ts单元格显示值格式化1.4 io文件内容snapshot.ts中性 JSON 快照xlsx.tsXLSX 读写csv.tsCSV 读写ssjson.tsSSJSON 导入exportHtml.tsHTML 导出exportPdf.ts/pdf.tsPDF 导出zip.ts/deflate.ts/inflate.tsZIP 容器、DEFLATE 压缩/解压paginate.ts分页计算1.5 element文件内容cmx-megasheet.tscmx-megasheet自定义元素约 150 个公共方法ReportModel.ts报表模型输入契约类型2. 数据模型2.1 层级Workbook→Worksheet[]→ 稀疏单元格矩阵。每个Worksheet独立持有单元格矩阵SparseMatrix仅存非空槽行数 / 列数列宽 / 行高含隐藏标记合并区域列表行/列大纲分组summaryBelow/summaryRight方向标视口态冻结行列数、尾冻结行列数、拆分行列数据验证规则列表条件格式规则列表超链接迷你图浮动对象图表/图片/形状/批注工作表保护状态命名样式表StyleSheet值语义2.2 单元格CellDatasrc/core/Cell.ts字段字段类型说明valueCellValue显示值formulastring?公式源串不含前导styleStyle?单元格样式richRichText?富文本格内混合字体/色CellValue string | number | boolean | null。2.3 坐标A1 地址 ↔ 0-based 行列索引parseAddr/formatAddrsrc/core/address.ts区域Rangesrc/core/Range.ts支持区域代数跨表引用Sheet1!A1整列/整行A:A/1:13. 公式引擎3.1 求值管线公式串 → Tokenizer → Parser(AST) → Evaluator → FormulaValueTokenizer.ts词法分析。标识符起始字符含字母/下划线/CJK标识符组成字符含字母/数字/下划线/./CJK。跳过空白与前导隐式交集运算符。Parser.tsPratt 解析输出AstNode。Evaluator.ts面向CellAccessorFunctionRegistry抽象求值。3.2 求值抽象接口interfaceCellAccessor{getCellValue(ref:string):FormulaValuegetRangeValues(start:string,end:string):FormulaValue[][]resolveName?(name:string):FormulaValue|undefinedresolveNameRef?(name:string):string|undefined}interfaceEvalContext{accessor:CellAccessor row:number// 当前公式所在格0-based供 ROW/COLUMN 等col:numbersheetName:string}typeFunctionImpl(args:EvaluatedArg[],ctx:EvalContext)FormulaValuetypeEvaluatedArg|{kind:value;value:FormulaValue}|{kind:range;values:FormulaValue[][]}FormulaValue为标量number | string | boolean | FormulaError | null无数组/溢出返回类型因此依赖动态数组溢出的函数FILTER/SORT/UNIQUE/SEQUENCE/TEXTSPLIT/MMULT/TRANSPOSE 等不在实现范围内。3.3 语法支持特性语法相对引用A1绝对引用$A$1跨表引用Sheet1!A1整列引用A:A整行引用1:1数组字面量{1,2;3,4}命名区域defineName(SALES,A1:A5)→SUM(SALES)3.4 依赖图与重算DependencyGraph.ts从 AST 抽取依赖拓扑排序。三色标记环检测循环引用返回#CIRC!。增量重算recalcCells编辑单格只重算受影响闭包依赖图未建时退化为全量。整列/整行依赖钳到 sheet 维度避免遍历全表。3.5 错误值#DIV/0!#VALUE!#REF!#NAME?#NUM!#N/A#SPILL!#CIRC!FORMULA_ERRORSsrc/formula/value.ts。3.6 内置函数335按族组织functions.ts汇入分族模块族模块示例核心聚合/逻辑/信息functions.tsSUMAVERAGECOUNTIFIFSSWITCHANDORISNUMBERROWCOLUMN数学/三角math.tsSINCOSLNLOGPIFACTCOMBINCEILING.MATHBASEROMAN财务financial.tsPMTFVPVNPVIRRXIRRMIRRSLNSYDDDBEFFECT统计statistical.tsGEOMEANCORRELSLOPEQUARTILEPERCENTRANKNORM.DISTSTANDARDIZE查找引用textref.tsVLOOKUPHLOOKUPINDEXMATCHXLOOKUPADDRESSINDIRECT文本textref.tsTEXTLEFTMIDSUBSTITUTETEXTJOINTEXTBEFOREFIXED数据库 D 函数database.tsDSUMDGETDCOUNTDAVERAGE日期时间functions.tsDATEEOMONTHNETWORKDAYSYEARFRACWEEKNUMISOWEEKNUMWORKDAYWORKDAY.INTLNETWORKDAYS.INTLDAYSDAYS360TIMEVALUE工程engineering.ts进制转换BIN2DEC/DEC2HEX/HEX2OCT等 12位运算BITAND/BITOR/BITXOR/BITLSHIFT/BITRSHIFTDELTA/GESTEPERF/ERFC(.PRECISE)贝塞尔BESSELI/BESSELJ/BESSELK/BESSELYCONVERT复数COMPLEX/IMSUM/IMPRODUCT/IMDIV/IMSQRT/IMABS/IMARGUMENT等abi语义完整名单BUILTIN_NAMESfunctions.ts导出。3.7 报表取数函数CustomFunction.ts注册QM/QC/JE/FS/REF。真值由外部经setReportValueMap下发引擎按键查值不做业务计算。这些函数标记为 volatile。4. 渲染4.1 抽象上下文渲染面向RenderContext2D接口CanvasRenderingContext2D的最小子集可用 mock 在 Node 环境测试几何路径。接口成员fillStyle strokeStyle lineWidth font textAlign textBaseline globalAlpha fillRect strokeRect clearRect fillText measureText beginPath moveTo lineTo stroke closePath fill arc rect save restore translate rotate clip setLineDash4.2 几何不变式getCellRect(r,c)行列索引 → 像素矩形与hitTest(x,y)像素 → 行列索引互为逆运算跨冻结、拆分、滚动、缩放成立。4.3 窗格PaneLayout.ts支持冻结窗格钉顶部行/左侧列尾冻结窗格钉底部行/右侧列拆分窗格可拖动分隔条4.4 数字格式numFmt/compile.tsnumFmt/apply.ts格式串编译为最多 4 区段正/负/零/文本数字缩放、百分号、千分位、科学计数、分数、补零日期yyyy-mm-dd、mmm、dddd、[h]经过时间、AM/PM文本回填颜色段[Red]等条件段[100]等该模块同时是TEXT()函数与单元格显示值的实现来源。4.5 图表drawChart.ts支持 11 类columnbarlineareapiedoughnutscatterbubbleradarstockcombo。选项含图例、数据标签、趋势线线性/移动平均、双轴。配色分离系列数据色用固定调色板不随主题变背景/边框/标题/坐标轴/网格/标签/图例文字/甜甜圈挖孔跟随ChartThemeLIGHT_CHART_THEME/DARK_CHART_THEME随setTheme切换。4.6 迷你图drawSparkline.ts支持 7 型lineareacolumnwinlossbarpiebullet。支持高低点、首末点、标记。4.7 条件格式condFormat.ts求值 4 类规则并叠加显示cellValue比较、colorScale2/3 色阶、dataBar数据条、iconSet图标集。叠加为显示层不改单元格数据。5. IO / 数据格式5.1 中性 JSON 快照格式标识format: cmx-megasheetversion: 1SNAPSHOT_FORMAT/SNAPSHOT_VERSION稀疏、不含视图态函数workbookToJSON/workbookFromJSON/stringifyWorkbook/parseWorkbook5.2 XLSX零依赖ZIP 容器zip.ts DEFLATE 压缩deflate.ts/inflate.ts 手写 OOXML函数exportXlsx/importXlsx/snapshotToXlsx/xlsxToSnapshot覆盖值/公式/样式/合并/行列尺寸/多表/冻结/筛选/验证/多级分组/页面设置导入公式清洗剥_xlfn./_xlws.前缀与前导sanitizeImportedFormula5.3 CSVRFC-4180 引号转义分隔符可选,/;/\t可选 BOM函数serializeCsv/parseCsv5.4 SSJSON函数importSSJSON/ssjsonToSnapshot导入公式经sanitizeImportedFormula清洗5.5 HTML / PDFexportHtmltable 内联样式 条件格式底色 合并 rowspan/colspanexportPdf/buildPdf零依赖手写 PDFpaginate提供分页计算6.cmx-megasheet元素6.1 组件边界组件自身渲染公式栏、画布、页签栏、主题。工具栏由宿主提供。约 150 个公共方法。6.2 方法按域域方法装载loadWorkbooksetReportModelsetCellValuessetReportValueMapgetReportModelgetReportValueMapgetWorkbookrecalcrecalcCells序列化getWorkbookJsonsetWorkbookJsontoJSONfromJSONtoSnapshotfromSnapshotgetWorkbooksetWorkbook样式applySelectionStyleapplySelectionBorderapplySelectionFillcopyFormatpasteFormatsetCellsLocked编辑undoredoundoStepsredoStepscanUndocanRedogetHistoryStaterunUndoablemergeSelectionunmergeSelectioninsertRowsinsertColumnsdeleteRowsdeleteColumns剪贴板copySelectionpasteSpecial数据工具sortRangesetAutoFilterapplyFilterclearFilterfindfindAndSelectreplaceAllshowFindBoxhideFindBoxtextToColumnsremoveDuplicatesconsolidate填充fillTo窗格freezePanesunfreezePanesfreezeTrailingunfreezeTrailingsplitPanesremoveSplitshowCellscrollToPixelsetZoomzoomgetZoom类型/验证setDataValidationgetDataValidationclearDataValidationsetCheckboxsetHyperlinkgetHyperlinkaddConditionalRuleremoveConditionalRulelistConditionalRulesclearConditionalRulessetRichTextgetRichText浮动对象insertChartinsertImageinsertShapeaddCommentgetCommentremoveCommentlistFloatingObjectsremoveFloatingObjectsetSparklinegetSparklineclearSparkline大纲分组groupRowsgroupColumnsungroupRowsungroupColumnssetOutlineLevelcollapseGroupexpandAllsetSummaryBelowsetSummaryRightrefreshOutlines保护protectSheetunprotectSheetisSheetProtectedsetCellsLockedcanEditCellsetEditableisEditable公式evaluateFormuladefineNamedeleteNamelistNamesIOexportXlsximportXlsxexportCsvimportCsvexportHtmlexportPdfimportSSJSONprint页面setPageSetupgetPageSetupsetPrintAreagetPageCount视图/主题setThemegetThemesetColorSchemeshowFormulaBarshowHeadersshowGridlinesshowTabsrefreshsheetgetActiveSheetsetActiveSheetgetActiveSheetIndexgetActiveSheetObjectgetName选择/几何setSelectionclearSelectiongetSelectionStatereadSelectiongetActiveAddrgetCellRecthitTestPointgetScrollTopgetScrollLeftgetScrollbarStategetViewportTopRowgetViewportBottomRowgetViewportLeftColumngetViewportRightColumn6.3 事件CustomEventcmx-cell-selectedcmx-cell-editedcmx-sheet-changedcmx-col-resizedcmx-row-resizedcmx-edit-rejectedcmx-structural-changed。6.4 主题setTheme(mode)mode ∈ light | dark | autoThemeMode。auto跟随宿主prefers-color-scheme。setColorScheme为契约别名。6.5 逃生舱getWorkbook()返回底层Workbook宿主可直接调用Worksheet的原生方法getValue/setValue/getFormula/setFormula/getCellRect/hitTest/rowOutlines/columnOutlines等。7. 报表模型输入契约setReportModel(report)接受ReportModelsrc/element/ReportModel.ts。interfaceReportModel{meta?:Recordstring,unknownmoduleMeta?:Recordstring,unknownsheets?:SheetModel[]grid?:GridModel// 单 sheet 简写cells?:Recordstring,CellModel// 单 sheet 简写fetches?:Recordstring,CellValue// 取数值表fetchKey → 值}interfaceSheetModel{id?;name?;grid?:GridModel;cells?:Recordstring,CellModel}interfaceGridModel{rows?:number;cols?:numbercolWidths?:Recordstring,number// 键为列字母 ArowHeights?:Recordstring,number// 键为 1-based 行号 1merges?:string[]// A1 区域串 A1:C1styleClasses?:Recordstring,StyleProps}interfaceCellModel{value?:CellValue formula?:string// 含或不含前导 归一时剥离style?:StyleProps styleName?:string// 引用 grid.styleClassesfetchKey?:string// 命中 fetches 表则回填值type?:string}坐标语义colWidths键为列字母rowHeights键为 1-based 行号字符串merges为 A1 区域串cells键为 A1 地址。8. 使用8.1 作为自定义元素cmx-megasheetidsheetstylewidth:100%;height:500px/cmx-megasheetscripttypemoduleimport./dist/index.js// 注册 cmx-megasheetconsteldocument.getElementById(sheet)el.setTheme(light)el.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()/script8.2 作为库import{Workbook,Worksheet,FormulaEngine,workbookToJSON}fromcmx/megasheetconstwbnewWorkbook({sheetCount:0})constwsnewWorksheet(Sheet1,{rowCount:20,colCount:10,styleSheet:wb.styleSheet})wb.appendSheet(ws)ws.setValue(0,0,42)ws.setFormula(1,0,SUM(A1:A1)*2)newFormulaEngine(wb).recalcAll()// A2 → 84constjsonworkbookToJSON(wb)// 中性快照8.3 直接求值el.evaluateFormula(SUM(A1:A5),row,col)// 不落格求值9. 库导出src/index.ts导出部分核心WorkbookWorksheetRangeSparseMatrixSelectionModelEventEmitter编辑inferFillfindAllcomputeSortOrdervalidateValue渲染AxisMetricsViewportformatValueformatCellevaluateRulesdrawChartdrawSparklinecompileFormatapplyFormatCellEditorSheetTabStripChartThemeLIGHT_CHART_THEMEDARK_CHART_THEME公式tokenizeparseFormulaBuiltinRegistryBUILTIN_NAMESFormulaEngineIOworkbookToJSONworkbookFromJSONstringifyWorkbookparseWorkbookexportXlsximportXlsxsnapshotToXlsxxlsxToSnapshotserializeCsvparseCsvimportSSJSONssjsonToSnapshotexportHtmlexportPdfbuildPdfpaginatedeflateRawinflateRawzipSyncunzipSync元素CmxMegasheetThemeMode常量VERSION 7.5.210. 构建与测试npminstall# 装 devDepsnpmrun build# tsc -p tsconfig.build.json → dist含 .d.tsnpmrun typecheck# tsc -p tsconfig.json --noEmitnpmtest# vitest runpackage.jsonscriptsbuildtypechecktesttest:watchtest:coverage。产物形态main/module指向./dist/index.js导入即注册cmx-megasheet。11. 约束FormulaValue为标量类型无数组/溢出返回动态数组溢出函数不实现。core与formula层不引用 DOM 类型。运行时零依赖。图表/迷你图在 XLSX 导出时写入 OOXML drawing/chartExcel 可渲染但 XLSX 导入不反解析图表图表数据的无损往返走中性 JSON 快照。PDF 内置字体覆盖 ASCII/拉丁CJK 需外部 TrueType 字体。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进