ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

开源在线Excel组件Univer:架构解析与前端集成实战

开源在线Excel组件Univer:架构解析与前端集成实战 写Univer是因为我最近半年真把它当主力工具用了。如果你在找“能嵌进自己系统的在线Excel组件”或者被领导一句“我们也要一个像谷歌表格一样的编辑页面”逼得头大那这篇文章应该能帮你省不少调研时间。Univer是一个开源的、基于TypeScript的Web办公套件最核心的能力是电子表格也叫Sheet。你可以把它理解成一个“表格内核”不需要自己从零写行列模型、公式引擎、Canvas渲染而是通过一套封装好的API把在线Excel能力直接装进自己的前端项目里。这篇文章适合前端工程师、技术选型负责人以及想给自己业务系统加表格能力的产品同学。我会先讲清楚Univer到底是什么、值不值得选然后拆它的核心架构带一个可上手的最小接入示例再走一遍“搭在线Excel编辑器”的完整流程最后把我在真实项目里遇到的坑和排查思路整理出来。尽量做到看完能干活。1. 先搞清楚Univer 是什么不是什么1.1 它解决的问题给 Web 系统装上“表格内核”很多业务系统做到一定阶段免不了要碰表格。最原始的方式是后端生成Excel文件前端做个下载按钮再进一步是在页面上用HTML table做点简单的合计和排序再往后需求就变成“要在浏览器里直接编辑、有公式、有多个Sheet、能导入导出Excel文件”。从HTML table开始自己扛是一件短期能用、长期非常痛苦的事。行列模型、单元格样式、合并单元格、公式依赖链、选区交互、撤销重做每一样都是独立工程。Univer的角色就是把这些东西一次性解决而你只需要把它作为一个组件嵌入。它不是现成的SaaS产品不是打开一个网址就开始编辑文档的那种应用。它是一个偏底层的“表格内核”需要你写代码去集成通常是在自己的前端工程里安装包创建Univer实例再把工具栏和编辑区挂到页面上。我把Univer的实际形态理解为三层数据层负责Workbook、Worksheet、Cell、Range这些对象的存储和变更管理。渲染层用Canvas画表格网格和内容这也是它能在数据量比较大的时候还保持流畅的关键。交互/功能层剪切复制、公式、排序筛选、条件格式、图表、导入导出等都是由插件提供的。这三层解耦得比较彻底意味着你不需要被某一层绑架。举例来说如果默认的工具栏长得不符合产品需求你可以完全不加载它自己写一套UI如果希望数据变化时通知后端可以监听它的事件总线甚至可以只拿它来做Excel文件解析和展示不开启编辑能力。这套设计思路和VSCode很像。VSCode并不把编辑器、文件树、终端写死在一起而是提供一个核心框架各种能力通过插件按需加载。Univer也是这种思路只是把场景从“代码编辑器”换成了“办公文档编辑器”。1.2 和同类开源/商业方案对比在Univer出现之前前端做在线Excel也不是没有选择。我把常见的几个方案放一起比过各有各的特点方案开源许可渲染方式生态/扩展性典型短板UniverApache-2.0核心部分高级能力商业版Canvas插件化架构文档/幻灯片也在规划版本演进快API变动时期较活跃LuckysheetMITCanvas曾经很流行老牌开源表格停更风险高架构偏旧维护活跃度明显下降Handsontable商业双许可DOM成熟稳定社区大高级功能受商业授权限制SpreadJS商业授权Canvas功能全面企业级授权费用高闭源选Univer不入坑的原因主要三个第一性能模型是现代的。Canvas渲染让它在渲染大数据量时不必操作一堆DOM节点。第二代码结构清晰插件化、命令化未来改功能、加功能都方便。第三是社区热度我观察GitHub趋势从2023年到写作时一直往上走提交活跃新版功能不断。当然要接受它的短板。最明显的是“年轻”跟SpreadJS这种打拼十几年的商业产品比部分Excel高级能力还没完全铺齐比如复杂的图表、透视表的深度交互。如果项目里需要百分之百还原Excel的细节比如老文件的透视表结构、跨Sheet交叉引用等需要先在测试环境验证。1.3 开源的边与商业的边现在Univer的核心仓库使用Apache-2.0协议可以让团队在开源协议范围内自由使用和修改这是它在开源社区迅速获得口碑的关键。但同样要留意不是所有能力都在开源版里开放。像协同编辑这一类偏“在线办公基础设施”的能力背后涉及服务端、存储、OT/CRDT算法等复杂实现Univer将其放在商业授权服务中也就是所谓Univer Commercial。个人学习和内部做原型没关系但如果要对外交付尤其要卖给政企客户就要在采购阶段跟官方确认清楚开放边界避免踩“社区版能跑但高级功能是电缆盒子里需要钥匙”的坑。换句话说技术选型是不是选Univer不只是看GitHub星星还要看功能边界是否覆盖你的核心业务场景。2. 核心架构拆解为什么它做到百万行不卡2.1 Canvas 渲染与分层绘制Univer性能的核心是把“文档内容”用Canvas画出来而不是用成百上千个DOM单元格来拼表格。常规的HTML table方案里一个10x10表格就是一百个单元格每个单元格对应一组DOM节点浏览器还需要维护样式、布局、事件。如果数据量到几千行乘以几十列DOM数量轻松突破十万级别滚动、选中、编辑的卡顿感会非常明显。浏览器重排重绘是有成本上限的这也是传统表格组件在数据量上天然受限的原因。Univer的做法和游戏引擎类似可视区域是一个视口只有当前视口内能看到的内容才进入绘制逻辑。Canvas会分层绘制包括背景层、网格线层、单元格内容层、选择区域层、浮动对象层等。滚动时Univer并不是把所有数据重绘一遍而是通过坐标换算确定当前视口应该显示哪些行、哪些列并只绘制那些可见单元格。听起来简单实际工作量在于字体测量、单元格合并判断、数字格式、公式结果缓存等细节。我上次给一个大数据量表格做过实测一次性向表格引擎灌入十万行数据向上滚动、快速跳转到末尾虽然不能说毫无压力但体感明显优于传统DOM方案。注意“百万行不卡”是有前提的它是渲染层通过Canvas和视口裁剪带来的综合效果不是对用户输入瞬间给到响应。具体配置和硬件环境、数据处理逻辑也会影响最终表现。2.2 数据模型Workbook 到 Cell 的分层结构Univer定义了一套与Excel心智模型对齐的数据结构。最外层是Workbook对应一个Excel文件Workbook里包含若干Worksheet也就是Excel左下角的Sheet页签每个Worksheet包含一个二维矩阵矩阵的每个节点是Cell而Range则是一个连续区域比如“A1:B10”表示从第一行第一列到第二行第十列的矩形。这套模型的价值在于“引用一致性”。用户输入公式、设置样式、做条件格式、做数据透视最终引用和修改的都是这套结构化数据而不是DOM里的某一行。这样任何操作都能被拿到数据层做统一处理也方便做撤销重做、数据校验与序列化。另一个特点是数据与样式分离。单元格本身存的是值和值类型比如数字、字符串、布尔值、日期而字体颜色、背景色、对齐方式等属于样式。这种分离带来了一个重要能力值可以做运算和公式引用而样式在复制粘贴时可以单独处理。比如“只保留值”“只保留格式”这类Excel原生操作在Univer的数据结构下自然能实现。2.3 Command 命令总线与撤销重做Univer在架构层面做了一个很关键的抽象所有操作都被建模为Command也就是把用户或程序发起的一个动作封装成对象。比如说“向A1单元格写入100”不是一个直接修改内部对象的函数而是一个Command被推送到命令总线。命令总线决定这个Command是否允许执行执行前是否需要建立快照或记录反向操作执行对哪个Sheet的哪段Range生效。这套机制最直接的好处是撤销重做变得“自动”了。既然每个操作都是可描述、可反向执行的对象那撤销的时候只需要调用对应的反向Command重做同理。我写业务系统时曾经自己硬撸过一套撤销逻辑最后代码里写满各种“备份原来的值再恢复”等到需求变成“把这种撤销应用在所有操作类型上”时基本等于重构。用Command总线等于从架构层面把这个问题消解掉了。当然前提是团队遵守规则新增功能时也走Command注册流程而不能写一个“直接改单元格内部属性”的快捷方法。这点需要作为团队纪律明确下来。2.4 插件化架构Univer的插件化是它的第二大设计支点。公式、格式化、工具栏、数据透视、筛选器、导入导出这些能力都是独立的插件模块。按需加载带来几个实际收益初始体积更可控。只是展示一个只读表格就不需要加载一堆重交互插件。业务定制不污染内核。你自己写的“库存校验逻辑”可以做成一个插件而不用改Univer源码。版本升级相对友好。核心升级时自定义插件只依赖稳定接口不至于一次升级就碎一地代码。和VSCode插件机制对照着理解会更直观VSCode有扩展宿主Univer也有类似的“插件注册表”。你注册一个插件插件可以在生命周期钩子中增强UI、监听消息、注册命令。我做了个偏报表预览的产品只需要表格展示、列宽自适应、导出图片就不加载公式栏等高交互插件加载速度和运行占有量都更可控。2.5 从公式引擎到协同编辑Univer公式引擎的工作方式和Excel类似但不是完全一致。它维护了一张公式依赖图单元格里写的是公式比如“A1*2”公式引擎计算时先找A1的值计算结果再填回当前单元格。如果A1的值变化所有依赖它的单元格会进入“需要重新计算”的队列从而避免全表重算。Excel文件里常见函数如SUM、IF、VLOOKUP、TEXT、ROUND这类Univer大体覆盖。但如果你依赖的是极冷门的数组公式或复杂的三维引用仍需要验证。协同时代公式引擎还有另一个大问题多端同改时怎么办协同编辑需要解决多个用户同时编辑同一个表格时的冲突问题。Univer后续补充的协同能力核心思路建立在它的数据模型和Command机制上。当一个用户做了写入操作时先传服务端服务端基于版本号或其他一致性算法做合并再把结果广播给其他端。因为每个操作都是离散Command同步和合并时能相对清楚地找到“哪个操作基于哪个版本”。3. 上手实践把 Univer 装进你的项目3.1 接入方式怎么选Univer目前有两种常见的接入路径通过npm包管理器适合有构建工具的前端工程。直接通过CDN使用构建产物适合做原型、静态Demo或者非重型项目。我自己的建议偏向npm接入。你有版本锁定、代码提示、按需打包的能力用起来更稳。如果是临时做一个验证页CDN引入足够。需要留意的是版本动态。Univer现在迭代速度比较快API变化也相对频繁不同大版本之间可能存在breaking change。网上教程大多基于某个特定版本照着敲之前一定先看当前官方文档确认接口名。3.2 最小可用示例这里以最常见的npm接入方式为例。第一步先安装Univer的核心包和预设样式包。npm install univerjs/preset-sheets univerjs/preset-toolsUniver设计了一套比较完整的预设装好预设后基本就能在新页面里渲染一个可编辑的表格。初始化逻辑大概是这样的import { Univer } from univerjs/preset-sheets; import { UniverSheets } from univerjs/preset-sheets; import { UniverTools } from univerjs/preset-tools; import univerjs/preset-sheets/styles/index.css;在页面里准备一个div容器然后创建Univer实例。const univer new Univer({ locale: zhCN, plugins: [ new UniverSheets({ // 这里可以传入初始化数据 }), new UniverTools(), ], });大多数情况下插件预设已经为我们默认实例化了渲染引擎和交互工具栏开发者不需要手动一一创建。业务侧主要工作变成了创建实例、绑定容器、传入数据、监听事件。这里的细节是Univer的入口不再是老版本里那种“new UniverSheet并在里面包各种子实例”的写法而是通过构造参数传入各个插件内部帮你组装好引擎。刚开始接触的朋友看到老教程时容易困惑如果发现怎么都渲染不出来先跑一遍官方模板工程确认版本一致。用Vite创建一个空白工程把上述代码复制进去能看到一个带有工具栏的表格出现在页面里最小Demo就跑通了。3.3 React/Vue框架怎么接入Univer里面依然是“命令式和实例式”思路不依赖某个特定框架。也就是说在React里可以直接使用在Vue里也直接使用。在React里比较常见的方式是用一个useRef或useEffect在组件挂载后创建实例import { useEffect, useRef } from react; import { Univer } from univerjs/preset-sheets; import { UniverSheets } from univerjs/preset-sheets; import { UniverTools } from univerjs/preset-tools; import univerjs/preset-sheets/styles/index.css; export default function SheetEditor() { const containerRef useRef(null); useEffect(() { if (!containerRef.current) return; const univer new Univer({ locale: zhCN, plugins: [ new UniverSheets(), new UniverTools(), ], }); // 挂载到dom节点 const mount univer.mount(containerRef.current); return () { mount?.dispose(); univer.dispose(); }; }, []); return div ref{containerRef} style{{ width: 100%, height: 600px }} /; }在Vue里写法类似只是在onMounted中初始化在onUnmounted中销毁。核心只有一个原则容器生命周期和Univer实例生命周期要保持一致否则容易出现“页面跳转后实例还活着”或“容器被删了还在渲染”的问题。3.4 需要理解的几个初始化配置源数据传入是Univer常见的接入需求。可以通过两种方式给表格喂数据初始化时把工作簿对象直接作为配置传进去。实例创建之后通过API操作工作表写入单元格区域。如果你是把已有的业务数据转换成表格展示第二种往往更灵活。因为运行时拿到数据是异步的从服务端拉完数据再灌入而不是等数据都齐了再初始化页面。创建一个带初始数据的工作表常见的做法是构造一份“工作簿描述对象”const workbookData { sheetOrder: [Sheet1], sheets: { Sheet1: { id: sheet-1, name: Sheet1, cellData: { 0: { 0: { v: 产品 }, 1: { v: 销量 }, }, 1: { 0: { v: A产品 }, 1: { v: 120 }, }, }, }, }, };然后在初始化时传入new Univer({ locale: zhCN, plugins: [ new UniverSheets({ workbook: workbookData, }), new UniverTools(), ], });cellData的层级逻辑是“行号”对应“列号”从0开始也就是Excel里的第1行第1列。这个数据结构长得比较啰嗦习惯了以后反而觉得清晰没有隐式映射直接定位单元格。如果要在运行时动态写值可以通过Univer实例拿到当前的工作簿、激活Sheet再调用写值相关API。下面的写法是常见的一种伪代码形态实际方法名以当前版本官方文档为准const activeSheet univer.getActiveSheet(); activeSheet.getRange(0, 0, 1, 1).setValue(Hello Univer);对于集成方来说设置值、监听点击、监听编辑结束这三个能力基本覆盖了90%业务场景。4. 实战搭一个轻量在线 Excel 编辑器4.1 需求范围与功能设计我前阵子接了一个内部项目需求很明确运营团队希望有一个网页既能像Excel一样做数据记录和计算又能在保存后同步到后端数据库。具体功能拆下来核心四块多个Sheet页可切换常见公式可用比如SUM、AVERAGE、IF支持上传Excel文件并把内容导入支持把当前工作簿导出为Excel文件。这个需求并不复杂但足够走一遍完整链路。整个搭建过程大概是接入编辑器、初始化多Sheet工作簿、处理数据导入导出、再写一点业务监听逻辑。导入导出这块值得单独说。Univer生态里常见做法是通过插件或封装模块解析xlsx。解析出来的数据结构能直接映射到Sheet数据模型导出的路径则是反向从Univer数据序列化再到xlsx文件。4.2 搭建基本的 Editor 容器页面结构用一个顶部工具栏加一个表格编辑区。工具栏我最终没有直接用原生的因为这个项目里只需要保留特定功能自定义工具栏反而能让界面更清爽。Univer允许你不加载默认工具栏自行绑定按钮事件。这种粒度是它适合嵌入业务系统的重要原因很多现成开源表格组件都把工具栏、右键菜单、状态栏绑在一起想拆反而麻烦。自定义工具栏时需要注意一点按钮对应的操作也要通过Command或公开API完成而不是自己拆内部数据结构去改。比如设置单元格背景色走Univer的样式API合并单元格走选区处理API。这样操作仍能进入撤销重做体系不会造成“界面操作能撤销自定义按钮操作不能撤销”的割裂体验。4.3 多 Sheet 与实际业务联动默认新建工作簿往往只有一个Sheet。在线Excel编辑器的标准体验是点击底部加号新增Sheet并对Sheet重命名、删除或复制。新建Sheet的API若记不住直接去官方示例里翻。集成后反正要处理的是当活动Sheet切换时当前页面可能要根据不同Sheet展示不同的业务上下文。我这里是这么做的每次激活Sheet变化时触发一个监听读取当前Sheet名称并把这个名称展示到页面顶部的“当前工作表: XXX”位置。这样设计简单不会干扰表格自身状态。监听逻辑代码不复杂关键点在于时机。可以在Univer实例的Command监听里捕获“工作表激活”这类操作也可以监听编辑完成事件。已编辑状态这个状态很重要。业务系统里常见做法是用户改完数据点“保存”前端把整个工作簿序列化成JSON提交给后端后端存储这个JSON下次打开时再把这个JSON灌回工作簿。有个细节必须注意保存不能用“用户在哪个单元格就存哪个单元格”的思路因为用户完全可以不去点任何位置直接刷新页面。最佳实践是一旦监听到编辑修改就把整个工作簿数据整体提取一次放到内存缓存里标记为“有未保存修改”。用户点保存时提交缓存数据而不是现场临时拉。4.4 Excel 导入导出流程导入流程是选择本地文件读取为ArrayBuffer或Base64然后解析为工作簿数据再替换掉当前Univer实例里的数据。这里最常见的问题是样式丢失。很多在线表格组件导入xlsx后能保住数据但单元格的合并、列宽、字体、颜色、数字格式等表现和Excel原文件不一致。Univer在这点上的处理能力相对完整但仍不是100%。解析Excel文件时某些特殊格式、条件格式规则可能会被降级或忽略。导出流程相对简单关键点是选择合适的导出库确保它能和Univer的数据模型互相转换。实操时要注意数字类型的保留比如手机号很可能是文本类型如果导出时被当成数字就会变成科学计数法。这类问题往往不是Univer自身的问题而是导入导出链路上类型推断逻辑需要仔细处理。文本型数字应设为字符串类型而不是数字类型。4.5 只读权限与展示态另一个常见需求是只读预览。比如A用户编辑完保存B用户打开查看不允许修改。Univer支持将表格切换为只读或禁用编辑状态。我一般在初始化前根据用户权限决定是否启用编辑能力而不暴露各种散装的“禁用按钮”。最佳配置是启动完整表格但把工作簿设置为“不允许编辑”这样视觉上依然是完整的Excel交互感但数据改不了。如果希望交互上更严格比如不允许选择区域那还需要额外禁用选区相关能力。这块在混合业务系统中比较关键因为有些表单页面只是借用表格做展示用户误操作后内心会很慌。5. 踩坑记录常见问题与排查思路5.1 表格渲染出来是空白这是我见过最多的问题。大概率不是代码逻辑写错而是容器高度为0。Canvas渲染需要容器有明确高度如果把div放在没有高度的父容器里表格自然显示不出来。排查顺序先打开浏览器控制台看看有没有异常没有异常就给容器设置固定高度比如500px再看是否出现。还需要关注样式表是否引入Univer的布局依赖预设CSS如果漏掉css import工具栏和网格线都会异常。另外一个隐蔽问题是多个实例共存于同一页面。某些场景下比如弹窗里有一个表格编辑器页面上又有一个两个实例如果共享同一个容器或实例未正确销毁会出现渲染错乱。用React调试时常见的原因是effect被StrictMode执行两次导致创建了两个Univer实例挂在同一个容器上。初始化前判断容器是否被占用或正确返回销毁函数就能避开。5.2 大数据量加载卡顿大数据量下卡顿很容易被误解为“引擎不行”实际上要看具体瓶颈。我验证过几次发现卡顿主要不在渲染而在数据填充方式。如果按单元格逐行逐列调用写值API比如五万行十列直冲五十万次调用每次调用还有内部命令开销不卡才怪。正确方式是构造好完整cellData结构一次性交给Univer内部处理而不是一格格塞。渲染上Univer的视口机制本身会裁剪不可见区域。但如果加了大量自定义绘制或大量浮动图片则每一帧绘制成本都会增加。建议在数据量庞大的场景尽量避免过度自定义绘制。公式计算量过大也会造成卡顿。公式引擎是全量参与依赖图的如果有几千个单元格引用了另一个Sheet里的长公式改一个输入值会触发大批量重算这是公式引擎的工作方式决定的。如果数据是纯展示不需要公式就不要给表格加载公式计算插件或者及时把公式结果转成静态值。5.3 导入的 Excel 显然“变了样”导入后的表变了样大部分不是选项问题而是Excel格式本身的复杂性决定。第一类是样式降级。Excel有很多CSS一道样式搞不定的复杂规则比如条件格式的“色阶”“数据条”在Web表格里处理逻辑迥异。如果业务场景对样式还原要求高要先拿一份代表复杂样式的真实文件做验收而不是拿简单表格测试后拍板“没问题”。第二类是公式兼容。Excel内置函数有几百个某些函数在Univer公式引擎里可能以兼容模式实现边界行为有细微差异。如果文件中存在“跨文件引用”或“宏”则基本不可能还原因为浏览器场景从一开始就不支持这些能力。第三类是字符编码。xlsx本身是zip包内部XML用UTF-8编码。解析库一般能处理但如果原文件是从某个老系统导出的可能存在非法字符或在Excel中被强制转换的类型。遇到异常时先看控制台有没有解析警告再定位具体sheet。5.4 协同后数据冲突团队合作编辑表格冲突难以完全避免。注意这里说的是“协同能力”Univer的开源社区版并非默认全带使用商业版或自研协同方案时都要在数据冲突上做功课。核心原则是基于版本号或操作序列做合并而不是简单覆盖。比如两个用户同时编辑不同单元格合理预期是双方都保留同时编辑同一个单元格则需要按业务规则决定后写覆盖或提示冲突。这在Univer中本质上依赖其Command表示法。因为操作是离散的Command服务端能够知道每个操作的内容和基准版本。如果团队自己实现服务端建议不要存储整个工作簿快照然后整体覆盖而是记录操作日志按版本回放和合并这样你才有能力处理冲突。5.5 我的另外几个经验升级版本前先跑一遍官方迁移文档和测试用例。Univer小版本之间有时也会改默认行为不要盲目升。不要绕过API直接修改Univer内部对象。从控制台data里看到的内部结构和正式API是两回事直接改必然引起不可预期的状态。中文字体渲染在Canvas上是细节活如果表格里中文较多测试时注意字体加载和字体测量避免出现截断或对不齐现象。在服务端解析或导出Excel时如果只是做文件格式转换没必要启动整个Univer实例。找到合适的解析库分离前端展示和文件转换效率会高很多。6. 应用场景与选型建议6.1 适合用 Univer 的场景第一个是后台系统中的嵌入式表格编辑器。不管是ERP、CRM还是项目管理工具只要需要“像一个表格一样录入数据、计算合计、导入导出”Univer都是很好的底层底座。第二个是数据分析类产品。让用户自己看原始数据列表意义不大给予“筛选、排序、临时加一列算比例”这种偏Excel的操作会更受运营欢迎。第三个是低代码/零代码平台里的数据表格组件。Univer的插件化很适合低代码平台因为你只要把核心表格能力注册成组件配置项通过初始化参数注入即可。第四个是教育场景的Spreadsheet教学。比如用前端复刻Excel基础操作公式计算过程可视化Univer能提供真实的表格数据模型和公式计算机制学生上手成本低。6.2 不建议硬上的场景如果你的核心诉求是“必须与Excel像素级一致”那当下的Univer未必合适。虽然基础能力覆盖能力在不断提升但在复杂公式异常行为、宏、透视表、旧版图表等特殊领域直接和Excel对齐仍有差距。选择时要做一次针对典型文件的验证而不是在宣传页上看到“兼容Excel”就直接全信。另一种不适合的情况是团队没有前端工程能力只想要一个能打开的网页。Univer是开发组件不是成品软件它需要写代码、需要构建。没有专职前端还是优先找现成SaaS更稳妥。6.3 后续方向从我持续关注Univer的体验来看它正在从“在线Excel组件”走向“Web办公基础设施”。文档、幻灯片等模块也逐步被纳入同一数据模型和渲染框架中。未来一个Web系统内部如果同时需要表格、文档、幻灯片用同一套组件底座来支撑无论是数据打通还是交互一致都比分别找不同组件强很多。往更远的看对前端团队的启示不是“我们可以少写表格代码了”而是“重活交给专业底层做业务层集中解决业务问题”。整合一个强壮的表格内核业务侧只需要关心权限、校验、数据结构、接口对接这确实是能大幅节省研发成本的路线。如果让我给你的建议就是拿着自己系统的真实Excel文件写一个最小Demo跑一遍验证导入导出、公式、大数据量、中文和样式这五件事。这五件事过关Univer基本可以在你项目里落地不过关也省去了后面折腾迁移的麻烦。
返回列表