VibeOffice 是一个跑在浏览器里的免费 Office 三件套:Quire 写字、Ledger 算表、Lectern 做幻灯片,都能直接读写真实的 .docx/.xlsx/.pptx。没有后端、没有账号,文件不离开本机。本文讲清怎么在本地跑起来、同格式保存的链路怎么设计,以及哪些限制会先拦住你。

场景很具体:同事发来一个 .docx,你只需要改两行字、再发回去。但这台机器上没装 Office,在线文档又要上传、要账号,还要把文件放进别人的服务器里。

装一套桌面 Office 越来越像一份订阅;网页版办公套件虽然开箱可用,但联网、登录、上传这三件事在有些团队里根本不被允许。于是最常见的妥协是「先传到云上再下载回来」,中间多了一步谁都不放心的搬运。

VibeOffice 接住的正是这一段:它把字处理、电子表格、演示三个编辑器做成一份纯静态网页,打开与保存的都是真实 Office 格式,编辑与保存全在本机完成。界面照 Office 2003 的菜单、工具条与任务窗格排布,据项目文档的说法,这样「没有新东西要学」。

这不是协作平台,没有共享、实时协同、云端版本历史;也不是万能转换器,跨格式转换只是顺带的能力,不是主目标。

核心能力

•Quire(文字处理):打开并保存 .docx/.docm/.dotx/.dotm,也可以读写 RTF、网页、纯文本,以及 GitHub 方言的 Markdown(表格、任务列表、删除线、脚注、告警都认),导出 PDF。据官方文档,它的 Markdown 阅读器在 CommonMark 0.31.2 的规范用例上通过 652/652,在 GFM 扩展用例上通过 22/22。

•Ledger(电子表格):读写 .xlsx/.xlsm/.xltx/.xltm、CSV 与文本、XML Spreadsheet 2003,也能把网页里的表格读成工作表,导出 PDF。官方文档给出 519 个工作表函数,除 Excel 2003 的全套外还收了 IFS、XLOOKUP、FILTER、LET、LAMBDA 这些后来出现的;支持结构化引用、动态数组、依赖图增量重算与 A1/R1C1 两种引用方式。

•Lectern(演示):读写 .pptx/.pptm/.ppsx/.potx,导出 PDF、PNG 与单文件网页;自带 14 套设计、21 个版式,IntelliArt(在文件里就是 SmartArt)有 26 种布局。

•同格式保存是它的核心目标:打开的文件保持为一份不可变基线,编辑只替换你动过的属性;写回时按部件所有权分三类处理——原样搬回原始字节、只替换设置类部件里模型拥有的属性、由模型重建内容部件并挂回保留片段。真的会丢的东西,会在下载之前由兼容性检查器用大白话告诉你。

•密码保护:能读写 Office 2007 的 Standard 加密与 Office 2010 以后的 Agile 加密,保存时用 AES-256 与 SHA-512(与 Office 2013 及以后一致)。加解密全在浏览器里做,所以页面必须走 https 或 localhost。

•命令检索与草稿恢复:每个应用、每种界面主题下都有命令检索框,Alt+Q 进入,支持整词与词首匹配、允许一个字母拼错,还会把日常说法映射过去(比如输入 image 找到「图片」、输入 pdf 找到「另存为」)。编辑停下 15 秒后会自动存一份草稿,标签页崩溃或关掉之后可以用「文档恢复」找回。

打开网易新闻 查看精彩图片

Quire 的文字处理界面:菜单、工具条、标尺与右侧任务窗格都是 Office 2003 的排布(

打开网易新闻 查看精彩图片

Ledger 的电子表格界面:名称框、编辑栏、工作表标签与 AutoCalculate 状态栏

打开网易新闻 查看精彩图片

Lectern 的演示编辑界面:左侧幻灯片列表、中间画布与下方备注区

环境与安装

最快的一条路是不装任何东西:直接用官网上的版本,或者把它当作 PWA 装进浏览器。要在本机跑一份自己的副本,需要的只有 Python 3(仓库的服务脚本只用标准库),以及一份仓库副本。

python3 tools/serve.py
# Serving .../public at http://127.0.0.1:8760/ (no-cache)

看到上面那行输出就算起来了:脚本把 public/ 目录挂在 127.0.0.1:8760,并给每个响应加上 Cache-Control: no-store,改完页面刷新就能看到,不用清缓存。打开 http://127.0.0.1:8760/ 会看到启动中心。

这里有一个容易踩的地方:tools/serve.py顶部的说明文字里写的端口是 8765,而代码里的默认端口是 8760,项目文档和仓库规则里也写 8760。以代码为准,需要换端口就往命令后面加一个数字,例如 python3 tools/serve.py 9000。

为什么不能直接双击 index.html 用 file:// 打开?据官方文档,有两个硬原因:一是拼写与同义词的词典是运行时从 common/dict/ 取的,file:// 页面取不到,拼写检查会一直关着;二是打开受密码保护的文件要用 WebCrypto,而它要求 https 或 localhost。

还有一点会让习惯前端工程的人意外:这里没有 npm install 这一步,也没有 package.json。运行时是纯静态文件加经典 script 标签,没有打包也没有构建;Node 只出现在测试和截图工具里。所以「装成功」的标志不是构建产物,而是上面那行服务日志和能正常打开的启动中心。

实操主路径

下面这条路径是把一个真实的 .docx 打开、改一处、存回去,全程在浏览器里。前提是本地服务已经在跑。

1.浏览器打开 http://127.0.0.1:8760/quire/ 。据官方文档,地址后面可以带参数控制启动方式:?new开一份空白文档,?template=从模板开,?open=与 ?recent=则是启动中心把文件交接给应用时用的。

2.用 File ▸ Open 选文件,或者直接把 .docx 拖进窗口。文档说明打开时会先读包、把原始字节留作不可变基线,这份基线不参与撤销历史,所以后面无论怎么改,没被碰过的部分都还有原件在。

3.改一处你真正会改的东西,比如改一行字、给一段加粗。保存用 Ctrl+S,或 File ▸ Save As;据官方文档,可选的落盘格式包括 DOCX/DOCM/DOTX/DOTM、RTF、网页、纯文本、Markdown,以及 PDF。

4.预期结果:浏览器按原文件名下载一份新文件,你改动的地方是新的,没动的地方尽量维持原样;如果这次保存会丢掉你会在意的内容或功能,兼容性检查器会在下载前弹出一句人能读懂的话,并指出发生在哪张工作表、哪一页。

5.失败时先查这几项:页面白屏或脚本报错,先确认终端里服务还在、端口是 8760;拼写和同义词不工作,多半是用 file:// 直接打开了页面;密码文件打不开,同样先确认地址是 http://127.0.0.1:8760;存出来的文件在 Office 里提示修复,这正是这个项目最重视的失败模式,项目文档明确请用户带着具体文件去开 issue。

同一条路径在三个应用里一致:Ledger 打开 .xlsx 或 CSV、Lectern 打开 .pptx,启动方式与保存对话框都对应各自的格式。想快速试功能,启动中心里每个应用都带一份示例文档和一组模板,Quire 有十份(简历、报表、会议纪要、活动传单等),Ledger 有八份(贷款摊销、费用报销、销售发票、工时卡等)。

另外路径

第一条是把它装成「双击文件就能开」的样子。在 Chrome 或 Edge 里打开启动中心,用 Install 把它装成 PWA;清单里声明了 .docx/.dotx/.docm/.rtf/.md、.xlsx/.xltx/.xlsm/.csv、.pptx/.ppsx/.potx 的文件处理器,装好之后可以从文件管理器直接打开,窗口复用交给 focus-existing 策略。

想要真正的原生壳,就走桌面端。据官方文档,构建需要 Rust、x86_64-pc-windows-gnu目标、mingw-w64、wixl(msitools)和 zip,文档特别写明它在 Linux 上构建、不需要 Windows SDK。

desktop/build.sh
# desktop/target/dist/ 下得到带版本号的 .msi 与 .zip

cargo build --no-default-features
# 不内嵌 public/,改读 devUrl 指向本地服务,改页面不用重编

作者记录的体积是 release exe 6.9 MB(其中内嵌页面约 4.1 MB)、MSI 5.6 MB,记录日期为 2026-10-11,用的是 Tauri 2.12.3。这条路的边界要说清楚:桌面端当前的保存是「下载到系统 Downloads 文件夹」,不是原地写回原文件;运行中再双击第二个文件会再起一个进程;而且文档里 Windows 版明确写着:已经构建出来,作者还没有实际跑过。所以现阶段的桌面端更像一个原生窗口的实验,主线仍然在 Web 侧。

第二条是拿仓库自带的工具做一次「它到底有没有偷偷联网」的核对。仓库里有 tools/shot.mjs:它通过 CDP 驱动一个 Chromium,打开指定页面、按脚本步骤操作、截图,最后列出控制台错误和所有离开 127.0.0.1 的请求。文档给的用法是这样:

node tools/shot.mjs ledger/ '[{"wait":1000,"shot":"ledger.png"}]'
node tools/shot.mjs quire/ steps.json --w 1440 --h 900 --out /tmp/shots

每一步写成 { "js": "...", "wait": 毫秒, "shot": "文件名" },js 是页面里执行的一段函数体;输出目录由 --out指定。预期是末尾不出现任何离开 127.0.0.1 的请求,这与项目「不用 CDN、不用外部字体、不放统计脚本」的设计约束是同一件事的两种写法。前置条件是一个开着 --remote-debugging-port=9222的 Chromium;文档还说明,如果 8760 上没有服务,工具会自己起一个。

关键实现

整体是四层:一个启动中心,三个互不依赖的应用,一层共享代码,再往下一层是与宿主的接口。三个应用都挂在同一个全局命名空间下,共享的那部分代码在 public/common/ 里只存一份——部件图与身份保留在 opc.js,压缩与加解密在 zip.js 与 crypto.js,菜单、工具条、对话框与图标在 ui.js 与 icons.js,界面配色在 looks.css。

打开网易新闻 查看精彩图片

VibeOffice 的分层:启动中心分发到三个应用,共享层承载 OOXML 部件所有权与加解密,最下面是浏览器或 Tauri 宿主接口

最值得看的是保存这条链:打开时 L.opc.open把包读成一份不可变的基线,并且刻意放在撤销快照之外;编辑发生在各应用自己的模型里(Quire 的 dmodel.js、Ledger 与 Lectern 的 model.js),一次编辑只替换它拥有的那个属性,兄弟属性原样留着;写回时按部件所有权分流——原始字节的部件直接搬,设置类部件在原始 DOM 上按 schema 顺序替换属性,内容部件由模型重建并把保留片段挂回去;过程中所有转换与丢弃都记进文档的损失账本,兼容性检查器只挑「用户会真的丢东西」的条目显示;最后才触发下载。

身份保留是这套设计里最较真的部分:写入时优先复用原来的部件名、关系 ID 和对象 ID,复制出来的对象分配新 ID 并把引用一起重映射,而新 ID 的形态要对齐 Office 自己写出来的样子。文档里有一句总结很到位——「schema 合法不等于 Office 会接受」,所以他们把「写 Office 会写的东西」当成硬规则,每发现一个 Office 报的缺陷就补一条规则加一个回归测试。

覆盖范围与验证强度也写在文档里,口径是作者自己的基线提交:固定语料 4,697 个真实文件、14,091 次驱动、30,919 个包与 SDK 状态(其中 29,341 通过、670 失败、908 排除);LibreOffice 能打开未编辑的保存件 2,869/2,880(Word)、930/935(Excel)、836/837(PowerPoint);Word 的文本保留 776,207/776,869 个词,Excel 有 883/889 次保存与原件单元格完全一致。同一份文档也把仍在静默丢内容的文件列进了待办,没有藏起来。这些数字取自检索日 2026-10-11 的仓库文档,是项目自测口径。

工程约束同样是硬编码进流程的:运行时无框架、无构建、无 CDN;共享代码不许复制进应用;界面颜色只能来自 looks.css 的命名设置,新增一个设置必须同时进三个主题并通过对应的检查。另外,应用里那只叫 Scout 的助手是 SVG 程序化姿态、没有图片资源,文档直言它是「AI 助手将来落脚的地方」——现在它只会做动作、会指向命令入口,不要把它当成 AI 功能来期待。

边界与代价

需要多人实时协作、评论服务、云端版本历史的团队;需要 VBA 宏真正运行起来的人;需要 Power Query 与 Power Pivot 真正执行的人;以及大量使用 iPad Safari 且开了 Lockdown Mode 的人——那种情况下 IndexedDB 不可用,草稿与最近文件都会失效。

宏在 .xlsm 里会被保留但不运行,也没有 VBA 编辑器;Power Pivot 模型与 Power Query 连接只作为包依赖被带着走,不执行也不维护查询语义;未编辑的图表类型如曲面图不绘制,只能整体替换;Excel 的二进制 .xls 不读,Ledger 会提示你先转换;Lectern 的旧 .ppt 同样需要先另存为 .pptx;没有对应版式的 SmartArt 只作为普通图形组保留,一旦编辑其内容就会转成图形;3D 图表是固定斜视角、没有透视与光照,曲面图、趋势线、误差线不画;嵌入的 OLE 对象与 ActiveX 控件按预览图显示。

Web 端是主线,浏览器要求是现代的 Chrome、Edge、Firefox、Safari;桌面端在 Windows 上走 WebView2、在 Linux 上走 WebKitGTK 4.1,而作者自己记录 Windows 版本「已构建、尚未运行」。字体方面,站点自带与 Calibri、Cambria、Georgia 度量兼容的三个替代字体;碰到没有替代字体的场合,在 Excel 里刚好放得下的数字可能显示成 ####。

主仓库是 Apache-2.0,但校对词典目录与字体目录各自带一份 LICENSES.txt,字体是 SIL OFL 1.1,二次分发时得连这些许可一起带走。

打开 vibeoffice.work,或者在本地跑起 python3 tools/serve.py 之后进 http://127.0.0.1:8760/。想读代码:先看仓库根的 AGENTS.md,它把设计规则和文档索引列全了;想理解共享层与启动流程,读 docs/suite.md;想理解保存,读 docs/LOSSLESS_SAVE.md,三个应用的具体行为分别在自己的 docs/ 文档里。想自己验证:tests/ 与 tools/ooxml/ 就是它的回归体系,测试语料需要另外下载到仓库外。想参与:遇到打不开或存坏的文件,直接开 issue 并附上文件,这是项目文档明确希望的反馈方式。

#纯前端#