1. 项目起因与核心思路为什么偏偏是Univer先说结论Univer是一款开源的、以电子表格为核心的企业级在线文档解决方案技术栈基于TypeScript同时覆盖Sheet、Doc、Slide三种文档类型。简单点说它就是一个可以嵌入到你自己Web应用里的“在线Excel”而且还附带开箱即用的协同能力与可扩展插件机制。我最初盯上它是因为手头一个内部数据管理后台需要嵌入表格编辑能力。需求看起来不复杂用户要能在网页里直接改数据、做筛选、导出Excel但真调研一圈就发现这事特别麻烦。自研表格是条不归路光公式解析、单元格选区、行列拖拽、合并单元格这些交互要做到像样的水平没有几个人月根本下不来。更不用说撤销栈、复制粘贴格式、移动端适配这些“看不见”的细节。买商业授权又是另一笔账而且定制程度受限。开源方案在当时的选择也都不太理想有老牌的Handsontable但它强在网格交互公式和运算偏弱也有Luckysheet这类自带公式引擎的方案但当时的代码活跃度和生态完善程度很难支撑长期使用。直到看到Univer的几个关键特性才觉得这事能成首先是它把核心引擎和UI层彻底解耦核心引擎只负责模型、计算、命令UI层负责Canvas渲染和DOM交互这意味着我可以把表格能力嵌进任意框架而不用被它的组件形态绑架。其次是它的Excel兼容度明显做了功课打开xlsx文件不乱码公式保留样式保留单元格类型基本都能映射。最后是它的插件生态设计每个功能模块都是一个独立插件按需加载不是一上来就给你塞一个100MB的“全家桶”。这篇文章我会从选型、架构、集成实操、问题排查几个角度完整过一遍适合两类人看一类是正在评估Univer但不确定它能不能扛住真实业务需求的开发者另一类是已经被Univer圈住、正在集成过程中和文档与框架“搏斗”的技术同学。如果你只是单纯好奇这个开源项目能做到什么程度也可以当一篇“在线Excel替代方案实践手记”来读我会尽量把踩过的坑、验过的数据都摆出来。2. 方案选型的底层逻辑它到底赢在哪些地方2.1 研发成本与可维护性的平衡点做在线文档类功能的团队最先要回答的问题就是“自研还是引开源”。很多人评估开源方案时会低估两个成本一是学习成本二是二次开发时的理解成本。Univer在这两块的友好度来自它的模块划分。它的核心依赖分为几个包univerjs/core、univerjs/sheets、univerjs/ui、univerjs/sheets-ui从包名就能看出引擎逻辑、表格数据模型、界面渲染是分离的。你要嵌入到自己系统里核心逻辑与界面框架的边界很清晰出了问题也容易定位。另外它的技术栈不绑死框架。底层是纯TypeScript逻辑UI层通过Web Components形式暴露意味着Vue、React、甚至原生JS项目都能接。我给团队做技术评估时专门列过一个对比表方案公式能力渲染机制二次开发成本社区活跃度自研极高成本极高成本无底洞无Handsontable 公式插件中等DOM网格中高架构耦合较深稳定但趋缓Luckysheet中等Canvas中但代码结构偏重较低Univer高公式引擎独立Canvas Web Components低插件化模块清晰活跃迭代快从表格可以看到Univer的性价比主要体现在“公式引擎独立”和“插件化结构清晰”这两项上。公式不是硬编码在UI里而是一个独立子系统能服务自定义公式注册和数据校验。这对我们这种有一个自己的业务计算规则的团队来说太关键了。2.2 生态扩展的想象力在线表格最常见的扩展诉求有权限控制、自定义报表格式、关联企业数据源。这三件事在Univer里都有对应的切口。权限控制走UI插件层可以自己实现“只读模式”、“单元格锁定”、“列隐藏”的组合自定义报表格式走渲染层能自定义单元格渲染器比如给特定数值画进度条、给异常值标红底关联数据源则可以直接在自定义命令里插入异步请求逻辑用户操作触发命令后拉取接口数据再写回单元格。拿“给异常值标红底”这个场景来说Univer的单元格渲染器提供完整的上下文参数你可以根据行列号判断当前坐标取到单元格值之后返回一套自定义样式。整个过程不会破坏原数据模型不存储非标准数据只影响渲染结果。这一点比在原始数据上做样式标记要卫生得多因为导出的xlsx不会带有一堆垃圾样式。2.3 在线文档的市场观感“univer在线”这个组合词最近热度不低本质上是因为整个行业都在讨论“在线Office替代”这件事。很多团队从几个关键词开始搜索在线表格、协同编辑、xlsx解析、Canvas渲染。Univer恰好把这些词全占了。更深一层看它是目前开源阵营里少数既保留了Excel深度功能、又提供了现代前端架构的选项。老牌方案中很多项目的核心代码还停留在类jQuery时代的组织方式模块一多就很容易失去控制力。Univer的新代码组织方式天然适合多人协作开发这在实际团队落地时非常重要。3. 架构设计拆解把Univer的内部地图画出来3.1 核心引擎与渲染层的“心与手”理解Univer的架构我的建议是先抓住一条主脉络Core是引擎UI是外观两者之间靠命令和事件通信。核心引擎里维护了Workbook工作簿、Worksheet工作表、CellData单元格数据三类核心模型所有编辑操作都会转换为Command命令命令在引擎里执行后更新模型然后通知UI重新渲染。这个模式的好处是不管用户是从界面点击按钮改数据还是脚本直接调API改数据最终走的都是同一条命令链路逻辑完全一致。渲染层用的是Canvas把整个Sheet区域绘制成一个或者多个可局部刷新的Canvas图层。每个单元格不必单独创建DOM节点所以大数据量场景下性能比纯DOM方案好很多。我实测过10万行数据基础的滚动和筛选整体流畅度可以接受不会出现拖动时浏览器卡死的情况。当然要想达到“丝滑”的体感还需要配合虚拟滚动Univer的显示层已经做了视口内单元格裁剪不会把范围外的单元格全部渲染出来。3.2 插件机制像装手机App一样扩展功能Univer的插件体系是我最喜欢的一部分。每个能力模块比如“公式”、“筛选”、“数据透视表”、“图表”都被设计成独立插件。集成时你可以选择只引入需要的插件从而控制包体积和加载时间。更重要的是自定义插件的注册方式非常简洁。比如我现在要做一个“导出PDF”按钮不用去改Univer源码而是写一个自定义插件在UI层注册一个新菜单项然后调用核心API生成PDF内容最后挂载到工具栏。整个过程和框架业务代码完全隔离Univer大版本升级时我的自定义插件只需要适配少量API变化而不是重写一整块逻辑。3.3 协同编辑的实现基础Univer的协同能力也是基于命令机制做的。每一个Command本身就是一个可序列化的操作描述比如“在Sheet1的A1单元格写入值100”。协同场景下每个客户端的操作都会被封装为这样的Op然后通过你指定的传输通道广播给其他客户端最后再按顺序应用到本地模型。它没有内置后端服务意味着你需要自己实现一个轻量级的协同转发逻辑——WebSocket也好WebRTC也罢它只负责Op的传递和排序。这个设计虽然把后端职责推给了使用者但也带来了极高灵活性。我第一次接入时只写了几百行Node.js代码用WebSocket连接多个客户端收到Op后广播给其他客户端就实现了一个可用的协同编辑Demo。对于业务场景来说它不像Google Docs那样开箱即用但如果你的团队需要的是“内部系统的多人同时编辑一张订单表”这种轻量协同完全够用了。4. 集成实操从零开始把Univer嵌入Vue项目4.1 环境准备与安装我以Vue 3 Vite项目为例实际步骤在Univer官方文档里已经很全但有些细节是需要自己摸索的。先创建一个空项目然后安装核心依赖npm create vitelatest univer-demo -- --template vue cd univer-demo npm install univerjs/core univerjs/sheets univerjs/ui univerjs/sheets-ui npm install univerjs/sheets-formula univerjs/sheets-export univerjs/sheets-import这几个包的区别容易让人迷惑前四个是基础必备sheets-formula是公式引擎sheets-export和sheets-import负责xlsx格式的导入导出。我没装文档和演示相关的包因为它们不是当前项目的需求。按需加载的思想在这里体现得很直接你装得越少首屏加载就越快。初始化代码也很直观在Vue组件里写一个生命周期钩子来创建Univer实例import { Univer, UniverInstanceType } from univerjs/core; import { defaultTheme } from univerjs/design; import { UniverSheetsPlugin } from univerjs/sheets; import { UniverSheetsUIPlugin } from univerjs/sheets-ui; import { UniverFormulaPlugin } from univerjs/sheets-formula; const univer new Univer({ theme: defaultTheme, locale: zhCN, }); univer.registerPlugin(UniverSheetsPlugin); univer.registerPlugin(UniverSheetsUIPlugin, { container: univer-container, layout: auto, }); univer.registerPlugin(UniverFormulaPlugin); univer.createUnit(UniverInstanceType.UNIVER_SHEET, { name: 测试工作簿, sheetOrder: [sheet1], sheets: { sheet1: { name: 订单数据, rowCount: 1000, columnCount: 30, cellData: { 0: { 0: { v: 订单号 }, 1: { v: 客户名称 }, 2: { v: 金额 }, }, }, }, }, });这里的createUnit是核心API它创建了一个工作簿实例并定义了第一个Sheet的基本结构和初始单元格数据。rowCount和columnCount可以根据实际场景设置不必一开始开成Excel默认的百万行级别因为那会浪费内存和渲染资源。4.2 从后端拉取数据并填充表格实际项目里数据一定来自接口不会是硬编码。我把初始化流程拆成两步先创建空的工作簿再通过命令向指定Sheet写入数据。示例做法import { FWorksheet, CommandType, ICommandService } from univerjs/core; const activeSheet univer.getActiveUnit().getActiveSheet(); const range activeSheet.getRange(0, 0, recordList.length 1, 5); range.setValues([ [订单号, 客户, 金额, 状态, 时间], ...recordList.map(item [ item.orderNo, item.customer, item.amount, item.status, item.time, ]), ]);getRange的参数依次是起始行、起始列、行数、列数和Excel的Range概念一致。实际调通之后我建议把数据拉取和初始化分成独立函数这样将来切换不同数据源时无需改动表格初始化逻辑。要注意一个容易踩的点给单元格写入值如果直接改cellData对象的属性界面不会自动刷新必须通过上面这种Range API或命令方式操作UI才会收到模型更新事件进而重新绘制Canvas。这也是核心引擎和UI分离带来的一个“返璞归真”点——数据模型是唯一事实来源界面上看到的东西永远来自模型快照。4.3 自定义工具栏按钮做一个导出PDF的功能Univer默认工具栏已经有基础的样式操作按钮但业务特性功能需要自己加。自定义按钮的常规做法是注册一个UI插件在工具栏指定位置挂载自定义DOM。参考实现思路univer.registerPlugin(UniverSheetsUIPlugin, { container: univer-container, toolbar: { customItems: [ { name: exportPdf, icon: download, label: 导出PDF, handler: () { const unit univer.getActiveUnit(); const workbook unit.getWorkbook(); // 这里调用你自己的导出PDF服务或前端打印逻辑 exportWorkbookToPdf(workbook); }, }, ], }, });唯一的坑是要注意toolbar配置项的层级和格式不同版本略有差异。遇到更新导致的API变化时先查对应版本的迁移文档不要拿着旧代码硬试。5. 核心功能实测与调优记录5.1 大数据量渲染从卡顿到流畅的3个调整真实数据导入后第一版使用体验非常一般滚动时能感觉到明显延迟。排查后发现主要有三个原因一是初始化的Sheet行数我直接设成了100万行Univer虽然做了虚拟滚动但定义超大Sheet会拉高模型初始化成本二是每个单元格都设置了自定义样式导致渲染层需要计算的样式样式数量暴涨三是把数据一次性暴力写入没有批量提交。解决办法很简单。第一步把rowCount调整到实际数据量加一个合理缓冲比如1万行。第二步把周期性的、能够通过条件判断得出的样式改成在Renderer层做拦截而不是直接写到单元格的style字段里。第三步用startTransaction和endTransaction把批量写入包裹成一个事务减少模型通知次数。这三招做完滚动流畅度有了质的提升在十万行级别的数据里操作基本感觉不到延迟。5.2 公式引擎像Excel一样算但小心循环引用Univer的公式引擎支持SUM、AVERAGE、IF、VLOOKUP等常用函数也支持自定义公式。在实测中基础公式的计算结果和Excel保持一致。但要注意循环引用检测复杂业务表里经常有人写出A1 B1 1、B1 A1 1这种逻辑Univer默认会阻断循环并报错这个行为是安全的不用特意关闭。需要额外处理的是大量公式同时计算时的性能我在一千行、每行四个公式的场景下测试重新计算耗时在几十毫秒级别完全可以接受但如果公式数量上万、且相互依赖复杂建议提前做好计算降级比如用户停止输入300毫秒后才触发公式刷算法。5.3 导入导出xlsx业务刚需的实测细节导入导出是B端系统的硬指标我用一个含合并单元格、批注、多Sheet、数据验证的Excel文件做了测试。导入结果很完整合并单元格保留批注可以读出来数据验证逻辑也能还原。导出功能生成的xlsx文件可以被市面主流办公软件正常打开。唯一需要留意的是图片类对象如果Excel里嵌入了大量图片导入导出时的处理策略需要单独设定。Univer支持图片对象但放在不同Sheet里的锚定方式要提前约定否则会有位置偏移。6. 典型问题速查把那些文档里不写的坑都摊开聊问题现象思路与解法初始化后表格空白container容器没有高度或宽度给容器元素设置明确的宽高建议至少width:100%;height:600px工具栏中文乱码按钮显示英文或方块初始化时设置locale为zhCN并确认对应的locale包是否正确引入自定义插件不生效注册时无报错但UI不出现检查插件是否在Univer实例注册之前完成以及插件内部是否正确引用了UIManager服务大数据量写入卡死一次性写入几千行就很慢使用批量事务API并分片写入每片几百行中间留出渲染空闲时间协同编辑时数据错乱多人同时操作偶尔丢字段确认每个客户端都保持版本号递增Op广播前先校验本地版本服务端可将错序的Op按版本重新排序自定义单元格渲染不生效样式偶尔丢失检查渲染器返回的样式对象是否完整某些属性名大小写不匹配会导致静默失败导出PDF报错控制台提示找不到字体确认导出的PDF模板字体资源路径是否正确尤其是中文环境下常见的字体缺失其中一个让我纠结点最多的坑是“渲染器不生效”。第一次写自定义渲染器时我在返回对象里写了一个不符合规范的样式属性名比如把backgroundColor写成了background。这在CSS里可能也能生效但Univer的Canvas渲染器严格遵守它定义的样式模型一旦属性名不合法它会直接忽略也不报错表现就是改了代码没效果。排查了几小时才找到这个细节之后我只要写渲染器就强制自己对照类型定义的字段名不再凭日常CSS习惯猜。另一个高频问题是“容器初始化时机”。Vue里经常出现在mounted钩子里DOM还没完全就绪的情况这时创建Univer实例就会得到一个空画布。解决办法是确认容器已挂载且宽高已计算完毕后用nextTick再初始化或者直接监听容器尺寸变化后执行初始化流程。7. 深度改造经验许可证校验、只读模式与自定义公式7.1 实现“只读查看”模式B端后台经常需要给外部合作方开放“只看不编辑”的页面Univer没有直接提供一个readOnly开关给整个工作表进行强制锁定但可以通过组合实践实现类似效果。第一是给所有核心命令加一层守卫拦截比如单元格编辑、行列插入、删除行、拖拽填充等命令根据当前模式丢弃它们的执行。第二是把工具栏上的编辑类按钮隐藏或置灰只保留滚动、筛选、排序等操作按钮。第三是在模型层对Range设置单元格保护即便通过键盘操作触发命令守卫没拦住模型也不会更新。三层组合下来只读模式下用户能看、能筛选、能搜索但数据完全不能被修改。7.2 自定义业务公式有一个实际场景订单表里需要计算“客户积分等级”规则比较复杂——根据最近三个月消费金额分档。这种逻辑放到前端是指数级复杂度放到公式引擎里是标准姿势。Univer支持注册自定义公式节点实现getValue方法并声明参数个数。注册完成后单元格里写CUSTOM_LEVEL(A1,B1,C1)就能实时计算。实测中我这个公式被Excel原有公式引用来引用去参与SUM、IF嵌套都没有问题。唯一需要注意的是公式在本地计算和协同合并时的行为自定义公式的执行需要确保是幂等的否则多人同时编辑时结果会不一致。7.3 接入服务端校验还有一个工程上容易被忽略的点所有前端校验都不可靠。Univer的模型在浏览器里是完整的用户完全可以绕过UI直接调API修改数据。因此任何终态数据校验必须落到服务端。我在Univer的命令链路里增加了一层自定义校验逻辑前端每次提交命令前会请求后端做校验校验不通过就丢弃并给用户一个轻提示。这个方案的代价是每次编辑都要等待网络但内部系统数据量不大体验完全能接受。如果你有批量连续编辑的场景可以优化为“防抖校验”等用户停止操作1秒后再批量校验当前快照。8. 移动端与安全合规实战记录8.1 移动端适配能用、能用好、能守住体验内部后台的移动端访问需求一直存在通常的期待是收起键盘、查看数据、简单编辑。Univer的Canvas渲染可以在手机浏览器上运行但默认工具栏占地方且交互设计偏桌面直接放上去体验很差。我的做法是打包一个“移动端精简版”入口隐藏大部分工具栏只保留最核心的保存、撤销和刷新按钮。单元格点击时会自动放大区域的编辑框避免手指误触相邻单元格。实测在主流手机浏览器上可以流畅查看和编辑一千行以内的数据表超过这个规模建议直接提示用户“请在电脑端操作”或者转为分页预览模式。8.2 数据安全和合规自查清单这块容易被忽略我在接入外部合作方后被迫系统性补了一遍。核心是几个层面前端打开页面时如果涉及敏感数据必须通过统一网关做接口鉴权Univer本身不提供鉴权所有请求都要通过用户系统统一代理。公式和单元格内容如果带缓存需要在后端设置无缓存头以避免退出登录后还能看到前一个用户的数据。导出的xlsx文件路径要注意权限生成后统一走临时下载链接过期即失效。若表格引擎被嵌入到iframe里务必设置X-Frame-Options或CSP策略防止恶意站点嵌入你的表格页面。这些和Univer本身没有直接关系但一旦你把自己的核心数据交给了开源引擎渲染外围的安全审计就变得格外重要。8.3 性能预算给团队立一个“红线”集成期间我特意整理了各项指标的红线形成内部约束指标红线值备注初始化耗时1秒内以中等配置电脑为准首屏渲染时间2秒内包体压缩后加载完成十万行基础滚动帧率30fps以上关闭所有自定义渲染器时有自定义渲染器时滚动帧率20fps以上对复杂报表的容忍下限公式重算耗时500ms内工作表一次全量重算超过红线我们宁可砍功能也不硬上比如把某些复杂自定义渲染器改成纯文本预览让出性能预算给更高频的操作。9. 下一步的想象空间与方向探索集成接近稳定之后我把它往更接近一个产品级模块的方向推。第一个方向是深度定制编辑器体验。基于Univer底层可以接入自定义的单元格编辑器在“点击单元格后弹出抽屉表单”这类交互上原生Univer是做不到的但通过拦截单元格激活事件、弹出自定义浮层可以做成一个类似低代码表单的配置器表单提交后再写入单元格。目前我们内部已经把它用作“审批表单数据回填”的联动模块。第二个方向是数据分析联动。表格只是手段分析才是目的。给Univer的网格视图叠一个自定义侧边栏可以展示当前选中区域的实时汇总求和、均值、最大最小这个功能对运营和财务团队极其实用。实现上只依赖选中区域事件数据量再大也有好的表现。第三个方向是接入模板市场。把常用报表做成Univer工作簿模板用户新建表格时从模板库选择。由于Univer的workbook数据结构是JSON模板就是一个个JSON文件上传下载都很好做。甚至可以做一个轻量级的“主题”系统切换模板时只替换工作簿配置不用重新加载脚本。如果未来对协同的要求越来越高还可以调研Univer官方提供的协同后端思路基于Op变换做的增量同步比整体同步的带宽消耗低很多。这点在企业内部网环境下非常实用——把单元格级操作转化为增量Op即使并发用户数较高服务器压力也远小于每次全量传文件。结束语前的一个真诚建议如果只说一条经验我想说是“不要高估一键集成也不要低估思维转换”。Univer的文档确实不错API也够现代但真正能决定项目成败的是你如何理解“核心引擎与UI分离”、“一切操作皆命令”、“模型是唯一真相”这三条设计原则。先花两天时间把这三个设计哲学弄透再动手写业务代码可能会少走很多弯路。我自己就是在第一版代码里摸爬滚打后反过来读了一遍架构设计文档才把几个埋着雷的写法彻底改掉的。如果你也正在评估Univer我祝你能在踩坑之前看到这篇文章少走一段我已经走完的弯路。
企业数字化 ERP 产品动态
相关推荐
SkyWalking动态配置探针功能详解与实践 1. SkyWalking动态配置探针功能概述Apache SkyWalking作为一款优秀的应用性能监控(APM)系统,其Java Agent探针功能一直是其核心能力之一。在实际生产环境中,我们经常需要在不重启应用的情况下动态调整探针的采集行为,这正是Dynamic Configura… · 2026/11/3 14:42:43
Univer开源文档引擎:嵌入式富文档渲染与离线计算能力解析 1. Univer 是什么:一个被误读的开源办公引擎,不是“在线 Office”替代品很多人第一次看到“Univer”这个词,是在技术社区里刷到“univer在线”“univer SDK”这类关键词,下意识以为这是又一个国产版 WPS Web 或腾讯文档的底层框架… · 2026/11/3 14:42:43
C、Go、Rust内存管理与并发模型深度对比 1. 编程语言发展现状与对比意义 1972年诞生的C语言至今已走过半个世纪,而Go、Rust等新生代语言正以每年两位数的增长率快速占领市场。作为参与过银行核心系统C语言改造项目的工程师,我亲眼目睹了不同语言在关键业务场景中的真实表现。这次对比不是简单的… · 2026/11/3 14:42:43
Claude Code三层架构:AI编程工具链深度解析 1. Claude Code工具链的三层架构解析在AI辅助编程领域,Claude Code凭借其强大的代码生成和问题解决能力,已成为开发者日常工作中不可或缺的伙伴。但真正发挥其潜力的关键在于如何构建高效的技能栈(Skills Stack)。Superpowers、gs… · 2026/11/3 15:25:58
LabVIEW使用DocX工具生成Word文档的完整指南 1. LabVIEW与DocX工具概述 在工业自动化和测试测量领域,LabVIEW作为图形化编程环境的标杆已经服务了工程师三十余年。但鲜为人知的是,当我们需要将测试报告、数据记录等文档输出为行业通用的Word格式时,传统的LabVIEW字符串操作显得力不从心。… · 2026/11/3 15:25:58
LIMS标准体系与合规落地:从ISO/IEC 17025到审计追踪 1. 先把标准地图摊开:LIMS要面对的三层标准体系做实验室信息化这些年,最常被问到的一个问题就是“我们这套LIMS到底要过哪些标准”。问这话的人里,有刚立项的项目负责人,也有被审核报告追着跑的实验室质量主管。他们通常已经翻过一… · 2026/11/3 15:25:58
Univer:基于Canvas与TypeScript的模块化在线表格引擎解析与集成实践 聊到给业务系统集成在线表格,前端的同学估计都有点一言难尽。商业组件功能全,但授权费用高、源码封闭,想改个交互都得跟客服扯皮;开源方案里 Luckysheet 算是不错的,可它把大量逻辑绑在 DOM 和旧架构上,玩到… · 2026/11/3 15:25:58
paperclip:轻量级桌面信息暂存工具,提升碎片信息处理效率 1. 从“paperclip”这个词说起:一个被低估的桌面效率入口第一次看到“paperclip”这个项目标题,很多人脑子里蹦出来的可能是那个经典的曲别针图标,或者早年办公软件里那个总爱跳出来打断你写字的助手。但在我实际接触并把它用起来之后&#x… · 2026/11/3 15:25:58
LangChain+ChromaDB 崩溃排查:OOM、段错误与工程化配置 内核掉了。不是抛异常,不是栈回溯,是 Jupyter 的 kernel 直接变灰,或者终端里的 python 进程凭空消失,只留下一行Killed或者什么都没有。我第一次在 LangChain 里挂上 ChromaDB 做本地知识库时,就是这么被教育了一整晚… · 2026/11/3 15:24:57
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 6:04:24
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 5:52:46
STM32F411RE与MAX14431实现SPI隔离:工业现场抗共模干扰实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59
ESP32+大模型AI硬件开发:从Demo到产品的8个工程问题 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59
基于MAX14431BAEE+与PIC18F85J10的SPI隔离方案设计与实践 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 6:04:24
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 5:52:46