- 添加 SQL、Markdown、JSON、日志等多种文本格式支持 - 增加 YAML、INI、配置文件等常见配置格式解析 - 扩展 XML、Shell 脚本和批处理文件格式支持 - 更新 ALL_EXTS 常量以包含新增的文本文件扩展名 - 提升引擎对多格式文档的处理能力
Excel Keyword Search Tool — Rust 版
跨 Excel / Word / CSV / 文本 文件批量关键字检索工具的 Rust 实现,包含两个交付物:
excel-search-rust.exe— 命令行搜索器(对标 Go 版cmd/searcher),追求极致的单二进制体积与启动速度;excel-search-rust-desktop.exe— 桌面版(对标 Go 版cmd/desktop): 原生 egui/eframe 图形界面,单 exe 直接出窗口。不沿用 Go 版"HTTP 服务 + Edge 应用窗口" 的前后端分离架构——那是受 Go 生态限制的妥协,Rust 有更好选择: 关窗即退出(无心跳判活 hack)、搜索跑后台线程 UI 全程可交互(无 30s 服务端超时截断)、 结果表原生虚拟滚动(万级命中不卡顿,无分页条)。
WebUI(独立浏览器标签页)形态仍由 Go 版提供(见 ../go/README.md)。
特性
- 并发扫描:rayon 线程池按文件并行解析,
--workers可配(默认 8,可用环境变量EXCEL_SEARCH_WORKERS覆盖)。 - 匹配语义与 Go 版逐字节对齐:
- 关键字与文本均做 Unicode NFC 规范化(
cafe\u{301}==café); - 默认不区分大小写(Unicode 折叠);
- 完整单词匹配默认关闭(模糊子串匹配);开启后要求关键字前后均为单词边界(字母/数字/组合标记/下划线之外)。
- 关键字与文本均做 Unicode NFC 规范化(
- 文件格式:
- Excel:
.xlsx/.xlsm/.xltx/.xltm,并借助 calamine 额外支持.xls/.xlsb/.ods(Go 版不含这三种); - Word:
.docx/.docm(解析word/document.xml,按段落定位Paragraph N,表格段落一并覆盖); - 文本:
.txt/.csv(按行定位Line N,CSV 不解析字段,整行视为纯文本)。
- Excel:
- 文件级缓存:与 Go 版相同的 JSON 结构(
{"version":2,"cache":{...}}), 按“路径 + 关键字 + ModTime + Size”判定命中;同一搜索根目录的缓存文件 (<cache_dir>/cache_kw_<sha256(绝对路径)前16字节>.json)可与 Go 版互换读写。 缓存目录由EXCEL_SEARCH_CACHE_DIR指定,默认运行目录下.cache/。 - 结果导出 CSV(桌面版):状态栏「📤 导出CSV」按钮弹出系统保存对话框选择位置;
所有列统一双引号包裹(RFC 4180,字段内
"转义为""),文件带 UTF-8 BOM, Excel 直接打开中文不乱码。 - 健壮性:单文件解析失败仅向 stderr 记
warn:告警并跳过,不中断整次搜索; stdout 只输出结果,--json可安全被管道消费。
目录结构
rust/
├── Cargo.toml # 包定义:两个 [[bin]](CLI + desktop)+ 依赖声明(calamine/rayon/eframe/rfd 等)
├── Cargo.lock # 依赖版本锁定(勿手改)
├── build.bat # Windows 一键构建脚本(自动探测 mise/PATH 工具链与 gnu+mingw 免 VS 路径)
├── src/
│ ├── lib.rs # 库入口(engine + error + history 模块导出)
│ ├── main.rs # CLI(clap):--dir/--keyword/--json 等参数与结果打印
│ ├── error.rs # 统一错误类型
│ ├── history.rs # 搜索历史 LRU(与 Go 桌面版同格式共用文件)
│ ├── desktop/
│ │ └── main.rs # 桌面版:原生 egui GUI(eframe);含 export_csv/quote_csv_field 导出逻辑与单测
│ └── engine/
│ ├── mod.rs # 搜索编排:并行调度 + 缓存合并 + 选项/结果类型
│ ├── matcher.rs # NFC + 大小写折叠 + 完整单词边界
│ ├── walker.rs # 目录遍历与文件类型过滤
│ ├── parser.rs # Excel(calamine) / Word(zip+quick-xml) / 文本 解析器
│ └── cache.rs # 文件级 JSON 缓存(与 Go 版 schema 兼容)
└── tests/
├── fixtures/search_sample.xlsx # 真实 xlsx 夹具(Go excelize 生成)
└── search.rs # 集成测试(与 Go scanner_test 断言语义对应)
构建与测试
一键构建(Windows)
双击 rust\build.bat,或命令行:
build.bat :: release 构建(默认)
build.bat debug :: debug 构建
build.bat test :: 运行全部测试
脚本自动探测工具链(优先 mise 托管的 cargo/rustup → 系统 PATH), 存在 GNU 工具链 + winlibs mingw 时自动走无 MSVC 编译路径,否则回退默认工具链并给出安装指引。
手动构建
cd rust
cargo test # 单元(lib 11 + 桌面 3,含 CSV 引号包裹回归)+ 集成(引擎端到端 10)
cargo build --release # 产物(一次构建出两个 exe;LTO 全量构建约 2-20 分钟):
# target/release/excel-search-rust.exe 命令行版 ≈1.3MB
# target/release/excel-search-rust-desktop.exe 桌面版(原生 egui GUI)≈9.6MB
Windows 工具链说明:本机若无 Visual Studio Build Tools / Windows SDK,
默认 x86_64-pc-windows-msvc 目标无法链接,请改用 GNU 目标(winlibs 便携版即可,免安装):
rustup target add x86_64-pc-windows-gnu
# 将 winlibs-x86_64-posix-seh-*-ucrt 解压后将 mingw64\bin 加入 PATH,然后:
cargo test --target x86_64-pc-windows-gnu
cargo build --release --target x86_64-pc-windows-gnu
# 产物:target/x86_64-pc-windows-gnu/release/ 下的两个 exe
用法
# 基本用法(默认:不区分大小写 + 模糊匹配 + 递归子目录 + 全部文件类型)
excel-search-rust --dir <目录> --keyword <关键字>
excel-search-rust <目录> <关键字> # 等价的位置参数写法
# 输出 JSON(便于脚本处理)
excel-search-rust --dir ./data --keyword 关键词 --json
# 区分大小写
excel-search-rust --dir ./data --keyword Phone --case-sensitive=true
# 完整单词匹配(默认关闭,开启后要求关键字前后均为单词边界)
excel-search-rust --dir ./data --keyword 手机 --whole-word
# 仅搜索根目录
excel-search-rust --dir ./data --keyword 关键词 --include-subdirectories=false
# 文件类型过滤:all | excel | word | csv
excel-search-rust --dir ./data --keyword 关键词 --file-type excel
# 并发 worker 数(或环境变量 EXCEL_SEARCH_WORKERS)
excel-search-rust --dir ./data --keyword 关键词 --workers 16
完整单词边界提示:汉字属于字母,因此开启完整单词后搜「手机」不会命中 「苹果手机壳」这类内部子串;默认(关闭)为模糊匹配则会命中。
桌面版用法
# 双击运行,直接弹出原生窗口
excel-search-rust-desktop.exe
窗口布局与 Go 桌面版一致:目录/关键字(含历史下拉)、四个搜索选项、结果表格 (虚拟滚动、列宽可拖拽、右键复制/打开文件)、状态栏「导出CSV」按钮。差异是架构性的、也是更好的:
- 关窗即退出:原生窗口生命周期与进程绑定,无心跳检测;
- 搜索不阻塞界面:搜索在后台线程执行,进行中可继续拖动窗口/改表单; 慢目录不再被 30s 服务端超时掐断(Go 版行为);
- 中文字体:运行时加载系统 SimHei/楷体/仿宋(epaint 不支持 .ttc 集合字体)。
| 环境变量 | 默认值 | 说明 |
|---|---|---|
EXCEL_SEARCH_WORKERS |
8 |
并发搜索线程数 |
EXCEL_SEARCH_CACHE_DIR |
.cache |
搜索缓存目录 |
搜索历史写入 .cache/search_history.json(与 Go 桌面版同格式,可共用同一份历史)。
与 Go 版的差异
| 维度 | Go 版 | Rust 版 |
|---|---|---|
| 交付形态 | searcher CLI + WebUI + 桌面版(HTTP+Edge 窗口) | CLI + 桌面版(原生 egui,无 WebUI) |
| Excel 格式 | xlsx/xlsm/xltx/xltm | 额外支持 xls/xlsb/ods |
| 搜索取消/超时 | context 全链路(服务端 600s 超时) | CLI:Ctrl+C 直接终止;桌面:后台线程不阻塞 UI,无超时截断 |
| 缓存 | JSON,版本 2 | 同 schema,条目可跨版本命中(已验证) |
| 日志 | slog(text/json,含请求日志中间件) | CLI stderr warn: 行 |
设计文档(历史)
原始设计指南(体积优化 profile、calamine/rayon 选型)已随实现落地,
关键决策保留在上文;[profile.release] 的 opt-level="z"、lto、strip 配置见 Cargo.toml。