能力一键集成:@univerjs/preset-sheets-find-replace 使用与 Facade 编程实战)
Univer 表格查找替换Find Replace能力一键集成univerjs/preset-sheets-find-replace 使用与 Facade 编程实战【免费下载链接】univerUniver is a full-stack framework for creating and editing spreadsheets / word processor / presentation on both web and server.项目地址: https://gitcode.com/GitHub_Trending/un/univeruniverjs/preset-sheets-find-replace是 Univer 面向表格场景提供的高层预设包它把通用的查找替换基础设施univerjs/find-replace与表格专用能力univerjs/sheets-find-replace打包成一个开箱即用的插件集合通过一行UniverSheetsFindReplacePreset()即可接入createUniver。本文以该预设包为主线结合仓库源码讲解其安装、配置、内部插件组合关系并给出基于 Facade APIcreateTextFinderAsync/FTextFinder的查找、遍历、替换完整实战示例。包概览一个预设三项能力根据 presets/packages/preset-sheets-find-replace/README.md 中的 Package Overview该预设包的能力清单如下PackageCSSLocalesFacade entryuniverjs/preset-sheets-find-replaceYesYesYes也就是说安装这一个包即可获得CSS 样式查找替换对话框、高亮等 UI 样式随包内置无需额外引入样式文件多语言资源Locales包含完整语言文案可合并进 Univer 的 locale 映射Facade 入口通过univerAPI直接调用createTextFinderAsync等高级 API 进行程序化查找替换。相比手动注册底层插件预设包显著降低了接入门槛是 presets 体系中面向某一完整功能域的标准封装方式。安装与版本约束从 presets/packages/preset-sheets-find-replace/package.json 可见该包当前版本为1.0.0-beta.2采用 pnpm workspace 管理依赖以workspace:*形式声明。安装命令与原文档一致pnpm add univerjs/preset-sheets-find-replace # or npm install univerjs/preset-sheets-find-replace需要注意两个版本层面的约束同版本原则原文档明确要求Keep alluniverjs/*packages on the same version——所有univerjs/*包应保持同一版本避免因跨版本间的内部类型与协议不一致导致运行时问题。Peer 依赖该预设包以 peerDependencies 形式依赖react^16.9.0 ~ ^19、react-dom以及rxjs7.0.0安装时宿主项目需自行满足这些版本要求。该预设包本身的依赖非常简单仅包含两个业务依赖见 package.jsonuniverjs/find-replace提供共享的查找替换服务与 UI 基础设施univerjs/sheets-find-replace将查找替换能力扩展到工作表Worksheet场景。快速接入在 createUniver 中启用预设原文档给出的用法示例极为精简import { UniverSheetsFindReplacePreset } from univerjs/preset-sheets-find-replace; // Use with createUniver: // createUniver({ presets: [UniverSheetsFindReplacePreset()] });仓库中的真实示例 examples/src/preset-sheets-core/main.ts 展示了更完整的接入方式包括预设与本地化资源的组合import { createUniver, defaultTheme, LocaleType, mergeLocales } from univerjs/presets; import { UniverSheetsFindReplacePreset } from univerjs/preset-sheets-find-replace; import UniverPresetSheetsFindReplaceZhCN from univerjs/preset-sheets-find-replace/locales/zh-CN; const { univer, univerAPI } createUniver({ locale: LocaleType.ZH_CN, locales: { zhCN: mergeLocales( // ...其他预设的 locale 资源 UniverPresetSheetsFindReplaceZhCN, // ... ), }, theme: defaultTheme, presets: [ // ...其他预设 UniverSheetsFindReplacePreset(), ], });要点说明UniverSheetsFindReplacePreset()是一个工厂函数返回IPreset结构可直接放入createUniver的presets数组预设函数接受一个可选的PartialIUniverSheetsFindReplacePresetConfig配置参数默认{}目前该配置接口为空见 preset.ts即当前版本无需传任何配置即可使用中文环境下应将univerjs/preset-sheets-find-replace/locales/zh-CN通过mergeLocales合并进locales.zhCN确保查找替换对话框等界面文案正确显示。预设内部结构两个插件的自动组合预设之所以一行接入是因为它在内部替你完成了插件编排。查看 src/preset.tsexport function UniverSheetsFindReplacePreset(_config: PartialIUniverSheetsFindReplacePresetConfig {}): IPreset { return { plugins: [ [UniverFindReplacePlugin], [UniverSheetsFindReplacePlugin], ].filter((v) !!v) as IPreset[plugins], }; }即该预设展开后等价于依次注册两个插件UniverFindReplacePlugin来自univerjs/find-replace提供跨产品共用的查找替换服务IFindReplaceService、FindReplaceModel、对话框 UI 组件与命令/操作层是能力底座UniverSheetsFindReplacePlugin来自univerjs/sheets-find-replace面向表格的扩展层负责工作表内容提供器Provider、命中单元格导航与高亮等。同时src/preset.ts 中还执行了import univerjs/sheets-find-replace/facade并把univerjs/sheets-find-replace/facade的类型重新导出这正是该预设包 Facade entry 为 Yes 的原因——引入预设即同时激活univerAPI.createTextFinderAsync扩展点。从UniverSheetsFindReplacePlugin的声明见 packages/sheets-find-replace/src/plugin.ts可以确认它的完整依赖链UniverSheetsFindReplacePlugin └─ DependsOn: UniverRenderEnginePlugin, UniverSheetsPlugin, UniverFindReplacePlugin, UniverSheetsUIPlugin也就是说表格查找替换是在渲染引擎、工作表内核、共享查找替换服务与表格 UI 之上工作的。如果你使用UniverSheetsCorePreset()等基础预设通常这些依赖已就绪若按旧式univer.registerPlugin(...)手动注册则需自行保证依赖插件已先注册。作为对照不使用预设时的等价手动写法是见 packages/find-replace/README.md 与 packages/sheets-find-replace/README.mdimport { UniverFindReplacePlugin } from univerjs/find-replace; import { UniverSheetsFindReplacePlugin } from univerjs/sheets-find-replace; univer.registerPlugin(UniverFindReplacePlugin); univer.registerPlugin(UniverSheetsFindReplacePlugin); // 记得合并 EnUS / zh-CN 等 locale 资源预设包的价值正在于此把上述步骤压缩为一次调用同时通过sideEffects: [*.css]见 package.json保证样式自动随包引入。程序化查找替换createTextFinderAsync 与 FTextFinder该预设包提供的 Facade 入口是univerAPI.createTextFinderAsync(text)返回一个FTextFinder实例。其声明位于 packages/sheets-find-replace/src/facade/f-univer.tsexport class FUniverSheetsFindReplaceMixin extends FUniver implements IFUniverSheetsFindReplaceMixin { override async createTextFinderAsync(text: string): PromiseFTextFinder | null { const state: PartialIFindReplaceState { findString: text }; const textFinder this._injector.createInstance(FTextFinder, state); await textFinder.ensureCompleteAsync(); return textFinder; } }内部实现要点结合 f-text-finder.tsFTextFinder会从IFindReplaceService获取所有已注册的查找提供器getProviders()并创建独立的FindReplaceModel每次createTextFinderAsync都会立即执行一次完整的查找ensureCompleteAsync所以返回的 textFinder 已经是查找完成状态可直接遍历结果查找结果被封装为FRange可以继续使用表格 Facade 的链式 API如getA1Notation()、getValues()、setValues()。FTextFinder 方法一览以下方法均有完整 JSDoc 与可运行示例见 packages/sheets-find-replace/src/facade/f-text-finder.ts方法返回值说明findAll()FRange[]获取当前工作表所有命中单元格当前命中为最后一个命中项findNext()NullableFRange移动到下一个命中项并返回其范围findPrevious()NullableFRange移动到上一个命中项并返回其范围getCurrentMatch()NullableFRange获取当前命中项范围查找未完成时会抛出异常matchCaseAsync(matchCase)PromiseIFTextFinder开关大小写敏感匹配内部会触发重新查找matchEntireCellAsync(matchEntireCell)PromiseIFTextFinder开关匹配整个单元格内容matchFormulaTextAsync(matchFormulaText)PromiseIFTextFinder切换按公式文本而非计算结果匹配replaceAllWithAsync(replaceText)Promisenumber全部替换返回被替换的次数replaceWithAsync(replaceText)Promiseboolean仅替换当前命中项ensureCompleteAsync()PromiseNullableIFindComplete确保查找完成切换工作表后需重新调用查找全部命中项以下示例取自 f-text-finder.ts 的 JSDoc演示了写入数据后用createTextFinderAsync找出所有包含 5 的单元格const fWorkbook univerAPI.getActiveWorkbook(); const fWorksheet fWorkbook.getSheetByName(Sheet1); if (!fWorksheet) return; const fRange fWorksheet.getRange(A1:D10); fRange.setValues([ [1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6], [4, 5, 6, 7], [5, 6, 7, 8], // ...共 10 行对角递增数据 ]); // 查找文本 5 const textFinder await univerAPI.createTextFinderAsync(5); // 获取所有命中单元格 const matchCells textFinder.findAll(); matchCells.forEach((cell) { console.log(cell.getA1Notation()); // D2, C3, B4, A5 });顺序遍历findNext / findPrevious / getCurrentMatchFacade 层对命中项实现了当前命中游标语义内部由FindReplaceModel维护currentMatch$。官方 JSDoc 示例见 f-text-finder.ts演示了方向遍历const textFinder await univerAPI.createTextFinderAsync(5); console.log(textFinder.getCurrentMatch().getA1Notation()); // 初始命中 A5 const nextMatch textFinder.findNext(); console.log(nextMatch.getA1Notation()); // D2 console.log(textFinder.getCurrentMatch().getA1Notation()); // 当前命中已移动至 D2对应地findPrevious()会向反方向移动并返回上一个命中项。若已无上一项/下一项返回null。大小写、整格与公式文本三种匹配模式FTextFinder提供了三个可编程的匹配开关均会触发重新查找并返回自身以便链式调用大小写敏感示例见 f-text-finder.tsconst textFinder await univerAPI.createTextFinderAsync(univer); console.log(textFinder.findAll().map((c) c.getA1Notation())); // 单元格内容为 hello univer / hello UNIVER / HELLO UNIVER / HELLO univer // 默认忽略大小写 → A1, B1, C1, D1 await textFinder.matchCaseAsync(true); console.log(textFinder.findAll().map((c) c.getA1Notation())); // 大小写敏感 → A1, D1匹配整个单元格内容示例见 f-text-finder.tsconst textFinder await univerAPI.createTextFinderAsync(hello univer); // 默认部分匹配 → A1, B1, C1, D1 await textFinder.matchEntireCellAsync(true); // 整格匹配 → A1其余单元格为 hello univer 1/2/3不命中按公式文本匹配示例见 f-text-finder.ts// A1:D1 [sum, 1, SUM(2), 3] const textFinder await univerAPI.createTextFinderAsync(sum); console.log(textFinder.findAll().map((c) c.getA1Notation())); // 默认按值匹配 → A1 await textFinder.matchFormulaTextAsync(true); console.log(textFinder.findAll().map((c) c.getA1Notation())); // 按公式文本匹配 → A1, C1SUM(2) 命中从实现看matchCaseAsync与matchEntireCellAsync分别更新caseSensitive与matchesTheWholeCell状态而matchFormulaTextAsync本质上是把findBy切换为FindBy.FORMULA或FindBy.VALUE见 f-text-finder.ts与共享层FindBy枚举保持一致。替换单个替换与全部替换替换当前命中项示例见 f-text-finder.ts// B1:E1 [hello, hello, hello, hello] const textFinder await univerAPI.createTextFinderAsync(hello); const replaced await textFinder.replaceWithAsync(hello univer); console.log(replaced); // true console.log(fRange.getValues()); // [[hello, hello, hello, hello univer]] —— 仅当前命中被替换替换全部命中项示例见 f-text-finder.ts// A1:D1 [hello, hello, hello, hello] const textFinder await univerAPI.createTextFinderAsync(hello); const count await textFinder.replaceAllWithAsync(hello univer); console.log(count); // 4 console.log(fRange.getValues()); // [[hello univer, hello univer, hello univer, hello univer]]实现上替换操作会先通过_state.changeState({ replaceRevealed: true, replaceString: replaceText })写入替换文本再委托FindReplaceModel.replace()/replaceAll()执行底层经由表格的替换命令与SetRangeValuesCommand落到单元格数据相关命令实现见 packages/sheets-find-replace/src/commands/commands/sheet-replace.command.ts。ensureCompleteAsync切换工作表后的关键一步FTextFinder的查找是异步完成的且命中结果与当前工作表绑定。官方建议只要切换了当前工作表就应调用await textFinder.ensureCompleteAsync()重新完成查找再继续遍历。官方示例见 f-text-finder.tsconst textFinder await univerAPI.createTextFinderAsync(1); const matchCells textFinder.findAll(); matchCells.forEach((cell) console.log(cell.getA1Notation())); const fWorkbook univerAPI.getActiveWorkbook(); const sheets fWorkbook.getSheets(); sheets[1]?.activate(); // 切换工作表 await textFinder.ensureCompleteAsync(); // 重新完成当前表查找 const matchCells2 textFinder.findAll(); matchCells2.forEach((cell) console.log(cell.getA1Notation()));此外findAll()在查找未完成时会返回空数组见 f-text-finder.ts而getCurrentMatch()会直接抛错提示 Find operation is not completed.因此按文档流程先await ensureCompleteAsync()是最稳妥的用法。底层协作工作表提供器与高亮表格场景的查找替换由SheetsFindReplaceController见 packages/sheets-find-replace/src/controllers/sheet-find-replace.controller.ts负责编排。其职责包括向IFindReplaceService注册工作表查找提供器registerFindReplaceProvider把在哪个单元格范围里搜、命中后如何定位的表格语义接入共享查找服务见 sheet-find-replace.controller.ts在单元格编辑器激活、公式编辑器聚焦等场景下自动关闭查找替换面板通过ScrollToCellCommand、SetSelectionsOperation等命令同步命中项的选中与滚动定位使用SheetFindReplaceHighlightShape见 packages/sheets-find-replace/src/views/shapes/find-replace-highlight.shape.ts在渲染层绘制命中高亮。因此接入预设后不仅获得 UI 对话框与快捷键/菜单入口univerjs/find-replace中定义相关控制器见 packages/find-replace/src/controllers/find-replace.controller.ts 与 packages/find-replace/src/menu/find-replace.menu.ts还拥有与 Facade 编程一致的高亮与定位体验。总结univerjs/preset-sheets-find-replace是 Univer 中查找替换功能域的一站式预设接入成本极低pnpm add之后在createUniver的presets数组中放入UniverSheetsFindReplacePreset()并合并对应 locale 即可样式自动生效内部职责清晰由UniverFindReplacePlugin共享服务与 UIUniverSheetsFindReplacePlugin表格语义扩展组合而成依赖渲染引擎、工作表内核与表格 UI 插件Facade 编程能力强univerAPI.createTextFinderAsync(text)返回FTextFinder支持查找全部、前后遍历、大小写/整格/公式文本三种匹配模式以及单个替换与全部替换返回的命中项均为可继续操作的FRange版本一致是关键与所有univerjs/*包保持同一版本并确保宿主满足 react / react-dom / rxjs 的 peer 依赖。需要更深入的内容时可继续研读 packages/find-replace共享模型、服务与命令与 packages/sheets-find-replace表格控制器、高亮形状与 Facade 实现这两个底层包或参考 examples/src/preset-sheets-core/main.ts 的完整示例工程。【免费下载链接】univerUniver is a full-stack framework for creating and editing spreadsheets / word processor / presentation on both web and server.项目地址: https://gitcode.com/GitHub_Trending/un/univer创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考