# Excel-CLI
一个运行在终端中的轻量级 Excel 查看器,具有类 Vim 导航功能,用于查看、编辑 Excel 数据并导出为 JSON 格式。
## 功能特点
- 使用类 Vim 快捷键浏览 Excel 工作表
- 在多工作表的 Excel 文件中创建、切换和删除工作表
- 直接在终端中编辑单元格内容
- 将数据导出为 JSON 格式
- 删除行和列
- 搜索并高亮显示结果
- 支持高级操作的命令模式
## 安装与卸载
### 安装
#### 方式 1:从 Cargo 安装(推荐)
该软件包已发布到 crates.io,可以直接使用以下命令安装:
```bash
cargo install excel-cli --locked
```
#### 方式 2:从 GitHub Release 下载
1. 访问 [GitHub Releases](https://github.com/fuhan666/excel-cli/releases)
2. 下载适合您操作系统的预编译二进制文件
3. 将可执行文件放置在系统环境变量中,或直接从下载位置运行
Linux 和 macOS 用户可能需要先添加执行权限
#### 方式 3:从源代码编译
需要 Rust 和 Cargo 环境。使用以下命令安装:
```bash
# 克隆仓库
git clone https://github.com/fuhan666/excel-cli.git
cd excel-cli
cargo build --release
# 安装到系统
cargo install --path . --locked
```
### 卸载
```bash
cargo uninstall excel-cli
```
## 使用方法
```bash
# 在交互模式下打开Excel文件
excel-cli path/to/your/file.xlsx
# 将所有工作表导出为JSON并输出到stdout(用于管道传输)
excel-cli path/to/your/file.xlsx --json-export
# 使用自定义表头方向和数量导出
excel-cli path/to/your/file.xlsx -j -d v -r 2
# 将JSON输出通过管道传输到另一个命令
excel-cli path/to/your/file.xlsx -j > data.json # (示例)将JSON输出保存到文件
```
### 命令行选项
- `--json-export`, `-j`:将所有工作表导出为 JSON 并输出到 stdout(用于管道传输)
- `--direction`, `-d`:Excel 中的表头方向:'h'表示水平(顶部行),'v'表示垂直(左侧列)。默认:'h'
- `--header-count`, `-r`:Excel 中的表头行数(水平方向)或列数(垂直方向)。默认:1
- `--lazy-loading`, `-l`:启用大型 Excel 文件的懒加载功能(仅在需要时加载数据)
## 用户界面
应用程序具有简单直观的界面:
- **标题栏和工作表选项卡**:显示当前文件名和所有可用工作表,当前工作表会被高亮显示
- **电子表格**:显示 Excel 数据的主要区域
- **内容面板**:显示当前选中单元格的完整内容
- **通知面板**:显示操作反馈和系统通知
- **状态栏**:显示操作提示和当前输入的命令
## 键盘快捷键
- `h`, `j`, `k`, `l` 或方向键:在单元格间移动(1 个单元格)
- `[`:切换到上一个工作表(在第一个工作表停止)
- `]`:切换到下一个工作表(在最后一个工作表停止)
- `0`:跳转到当前行的第一列
- `^`:跳转到当前行的第一个非空列
- `$`:跳转到当前行的最后一列
- `gg`:跳转到当前列的第一行
- `G`:跳转到当前列的最后一行
- `Ctrl+←`(Mac 上为 `Command+←`):如果当前单元格为空,跳转到左侧第一个非空单元格;如果当前单元格非空,跳转到左侧最后一个非空单元格
- `Ctrl+→`(Mac 上为 `Command+→`):如果当前单元格为空,跳转到右侧第一个非空单元格;如果当前单元格非空,跳转到右侧最后一个非空单元格
- `Ctrl+↑`(Mac 上为 `Command+↑`):如果当前单元格为空,跳转到上方第一个非空单元格;如果当前单元格非空,跳转到上方最后一个非空单元格
- `Ctrl+↓`(Mac 上为 `Command+↓`):如果当前单元格为空,跳转到下方第一个非空单元格;如果当前单元格非空,跳转到下方最后一个非空单元格
- `Enter`:编辑当前单元格
- `y`:复制当前单元格内容
- `d`:剪切当前单元格内容
- `p`:将剪贴板内容粘贴到当前单元格
- `u`:撤销上一次操作(编辑、行列变更、工作表创建/删除)
- `Ctrl+r`:重做上一次被撤销的操作
- `/`:开始向前搜索
- `?`:开始向后搜索
- `n`:跳转到下一个搜索结果
- `N`:跳转到上一个搜索结果
- `:`:进入命令模式(用于类 Vim 命令)
## 编辑模式
编辑单元格内容时(按 `Enter` 进入编辑模式):
- **模式切换**:
- `Esc`: 退出 Vim 模式并保存更改
- `i`: 进入插入模式
- `v`: 进入可视模式
- **导航(在普通模式下)**:
- `h`, `j`, `k`, `l`: 将光标向左、下、上、右移动
- `w`: 移动到下一个单词
- `b`: 移动到单词开头
- `e`: 移动到单词结尾
- `$`: 移动到行尾
- `^`: 移动到行内第一个非空字符
- `gg`: 移动到第一行
- `G`: 移动到最后一行
- **编辑操作**:
- `x`: 删除光标下的字符
- `D`: 删除到行尾
- `C`: 修改到行尾(删除并进入插入模式)
- `o`: 在下方新开一行并进入插入模式
- `O`: 在上方新开一行并进入插入模式
- `A`: 在行尾追加
- `I`: 在行首插入
- **可视模式操作**:
- `y`: 复制选中文本
- `d`: 删除选中文本
- `c`: 修改选中文本(删除并进入插入模式)
- **操作符命令**:
- `y{motion}`: 复制由动作指定的文本
- `d{motion}`: 删除由动作指定的文本
- `c{motion}`: 修改由动作指定的文本
- **剪贴板操作**:
- `p`: 粘贴已复制或删除的文本
- `u`: 撤销上一次更改
- `Ctrl+r`: 重做上一次被撤销的更改
## 搜索模式
通过按下`/`(向前搜索)或`?`(向后搜索)进入搜索模式:
- 输入搜索查询
- `Enter`:执行搜索并跳转到第一个匹配项
- `Esc`:取消搜索
- `n`:跳转到下一个匹配项(搜索执行后)
- `N`:跳转到上一个匹配项(搜索执行后)
- 搜索结果以黄色高亮显示
- 搜索使用先行后列的顺序(从左到右搜索每一行,然后移动到下一行)
## 命令模式
通过按下`:`进入命令模式。可用命令:
### 列宽命令
- `:cw fit` - 自动调整当前列宽以适应内容
- `:cw fit all` - 自动调整所有列宽以适应内容
- `:cw min` - 最小化当前列宽(最大 15 或内容宽度)
- `:cw min all` - 最小化所有列宽(最大 15 或内容宽度)
- `:cw [数字]` - 将当前列宽设置为指定值
### JSON 导出命令
- `:ej [h|v] [rows]` - 将当前工作表数据导出为 JSON 格式
- `h|v` - 表头方向:`h`表示水平(顶部行),`v`表示垂直(左侧列)
- `rows` - 表头行数(水平方向)或列数(垂直方向)
- `:eja [h|v] [rows]` - 将所有工作表导出到单个 JSON 文件
- 使用与`:ej`相同的参数
- 创建一个 JSON 对象,以工作表名称为键,工作表数据为值
输出文件名自动生成,格式如下:
- 单个工作表:`original_filename_sheet_SheetName_YYYYMMDD_HHMMSS.json`
- 所有工作表:`original_filename_all_sheets_YYYYMMDD_HHMMSS.json`
JSON 文件保存在原始 Excel 文件所在的目录中。
### 类 Vim 命令
- `:w` - 保存文件但不退出
- `:wq` 或 `:x` - 保存并退出
- `:q` - 退出(如有未保存的更改会发出警告)
- `:q!` - 强制退出而不保存
有关文件保存逻辑的详细信息,请参阅[文件保存逻辑](#文件保存逻辑)。
- `:y` - 复制当前单元格内容
- `:d` - 剪切当前单元格内容
- `:put` 或 `:pu` - 将剪贴板内容粘贴到当前单元格
- `:[cell]` - 跳转到单元格(例如,`:A1`,`:B10`)。支持大写和小写字母(`:a1`与`:A1`效果相同)
### 工作表管理命令
- `:addsheet [名称]` - 在当前工作表后新增一个工作表
- `:sheet [名称/编号]` - 按名称或索引切换工作表(基于 1 的索引)
- `:delsheet` - 删除当前工作表
### 行和列管理命令
- `:dr` - 删除当前行
- `:dr [row]` - 删除特定行(例如,`:dr 5`删除第 5 行)
- `:dr [start] [end]` - 删除一系列行(例如,`:dr 5 10`删除第 5 行到第 10 行)
- `:dc` - 删除当前列
- `:dc [col]` - 删除特定列(例如,`:dc A`或`:dc a`或`:dc 1`都删除 A 列)
- `:dc [start] [end]` - 删除一系列列(例如,`:dc A C`或`:dc a c`删除 A 列到 C 列)
### 其他命令
- `:nohlsearch` 或 `:noh` - 禁用搜索高亮
- `:help` - 显示可用命令
## 文件保存逻辑
Excel-CLI 使用非破坏性的文件保存方法:
- 当您保存文件(使用`:w`,`:wq`或`:x`)时,应用程序会检查是否进行了任何更改
- 如果没有进行更改,则不会创建新文件,并显示"No changes to save"消息
- 如果启用了懒加载,保存前会先加载尚未读取的工作表,以保留完整工作簿内容
- 如果进行了更改,则会创建一个文件名中带有时间戳的新文件,格式为`original_filename_YYYYMMDD_HHMMSS.xlsx`
- 创建的新文件不带任何样式
- 原始文件永远不会被修改
## 技术栈
- 使用 Rust 编写
- 使用 ratatui 库实现终端 UI
- 使用 crossterm 处理终端输入
- 使用 calamine 库读取 Excel 文件
- 使用 rust_xlsxwriter 写入 Excel 文件
- 使用 serde_json 进行 JSON 序列化
## 许可证
MIT