xl-cli-tools

CLI tools for viewing and editing Excel files
Log | Files | Refs | README | LICENSE

README.md (8031B)


      1 <div align="center">
      2 
      3 <h1>xl-cli-tools</h1>
      4 <h3>View, edit, query, and diff Excel files from the command line</h3>
      5 
      6 [![Vibecoded](https://img.shields.io/badge/vibecoded-%E2%9C%A8-blueviolet)](https://claude.ai)
      7 [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
      8 
      9 <table>
     10 <tr>
     11 <td align="center" width="50%"><strong>xlcat</strong> — view</td>
     12 <td align="center" width="50%"><strong>xlset</strong> — edit</td>
     13 </tr>
     14 <tr>
     15 <td><img src="demo/xlcat.gif" alt="xlcat demo" /></td>
     16 <td><img src="demo/xlset.gif" alt="xlset demo" /></td>
     17 </tr>
     18 <tr>
     19 <td align="center" width="50%"><strong>xlfilter</strong> — query</td>
     20 <td align="center" width="50%"><strong>xldiff</strong> — compare</td>
     21 </tr>
     22 <tr>
     23 <td><img src="demo/xlfilter.gif" alt="xlfilter demo" /></td>
     24 <td><img src="demo/xldiff.gif" alt="xldiff demo" /></td>
     25 </tr>
     26 </table>
     27 
     28 </div>
     29 
     30 ***
     31 
     32 [**xlcat**](#xlcat--view-excel-files) · [**xlset**](#xlset--edit-excel-cells) · [**xlfilter**](#xlfilter--query-and-filter) · [**xldiff**](#xldiff--compare-two-sheets) · [**Install**](#installation) · [**Claude Code**](#claude-code-integration)
     33 
     34 ***
     35 
     36 Four binaries, no runtime dependencies:
     37 
     38 ```bash
     39 # View a spreadsheet
     40 xlcat report.xlsx
     41 
     42 # Edit a cell
     43 xlset report.xlsx B3=42
     44 
     45 # Filter rows
     46 xlfilter data.xlsx --where "Amount>1000" --sort "Amount:desc"
     47 
     48 # Diff two files
     49 xldiff old.xlsx new.xlsx --key ID
     50 ```
     51 
     52 ## Installation
     53 
     54 ### Pre-built binaries (macOS)
     55 
     56 Download from [Releases](https://github.com/LouLouLibs/xl-cli-tools/releases):
     57 
     58 ```bash
     59 # Apple Silicon (macOS)
     60 for tool in xlcat xlset xlfilter xldiff; do
     61   curl -L "https://github.com/LouLouLibs/xl-cli-tools/releases/latest/download/${tool}-aarch64-apple-darwin" \
     62     -o ~/.local/bin/$tool
     63 done
     64 chmod +x ~/.local/bin/xl{cat,set,filter,diff}
     65 
     66 # Linux (x86_64)
     67 for tool in xlcat xlset xlfilter xldiff; do
     68   curl -L "https://github.com/LouLouLibs/xl-cli-tools/releases/latest/download/${tool}-x86_64-linux" \
     69     -o ~/.local/bin/$tool
     70 done
     71 chmod +x ~/.local/bin/xl{cat,set,filter,diff}
     72 ```
     73 
     74 ### From source
     75 
     76 ```bash
     77 cargo install --path .
     78 ```
     79 
     80 Requires Rust 1.85+.
     81 
     82 ## xlcat — View Excel Files
     83 
     84 ```bash
     85 # Overview: metadata, schema, first/last 25 rows
     86 xlcat report.xlsx
     87 
     88 # Column names and types only
     89 xlcat report.xlsx --schema
     90 
     91 # Summary statistics (count, mean, std, min, max, median)
     92 xlcat report.xlsx --describe
     93 
     94 # Pick a sheet in a multi-sheet workbook
     95 xlcat report.xlsx --sheet Revenue
     96 
     97 # First 10 rows / last 5 rows / both
     98 xlcat report.xlsx --head 10
     99 xlcat report.xlsx --tail 5
    100 xlcat report.xlsx --head 10 --tail 5
    101 
    102 # All rows (overrides large-file gate)
    103 xlcat report.xlsx --all
    104 
    105 # CSV output for piping
    106 xlcat report.xlsx --csv
    107 xlcat report.xlsx --csv --head 100 > subset.csv
    108 ```
    109 
    110 ### Example output
    111 
    112 ```
    113 # File: sales.xlsx (245 KB)
    114 # Sheets: 1
    115 
    116 ## Sheet: Q1 (1240 rows x 4 cols)
    117 
    118 | Column  | Type   |
    119 |---------|--------|
    120 | date    | Date   |
    121 | region  | String |
    122 | amount  | Float  |
    123 | units   | Int    |
    124 
    125 | date       | region | amount  | units |
    126 |------------|--------|---------|-------|
    127 | 2024-01-01 | East   | 1234.56 | 100   |
    128 | 2024-01-02 | West   | 987.00  | 75    |
    129 ... (1190 rows omitted) ...
    130 | 2024-12-30 | East   | 1100.00 | 92    |
    131 | 2024-12-31 | West   | 1250.75 | 110   |
    132 ```
    133 
    134 ### Adaptive defaults
    135 
    136 - **Single sheet, <=50 rows:** shows all data
    137 - **Single sheet, >50 rows:** first 25 + last 25 rows
    138 - **Multiple sheets:** lists schemas, pick one with `--sheet`
    139 - **Large file (>1MB):** schema + first 25 rows (override with `--max-size 5M`)
    140 
    141 ## xlset — Edit Excel Cells
    142 
    143 ```bash
    144 # Set a single cell
    145 xlset report.xlsx A2=42
    146 
    147 # Set multiple cells
    148 xlset report.xlsx A2=42 B2="hello world" C2=true
    149 
    150 # Preserve leading zeros with type tag
    151 xlset report.xlsx A2:str=07401
    152 
    153 # Target a specific sheet
    154 xlset report.xlsx --sheet Revenue A2=42
    155 
    156 # Write to a new file (don't modify original)
    157 xlset report.xlsx --output modified.xlsx A2=42
    158 
    159 # Bulk update from CSV
    160 xlset report.xlsx --from updates.csv
    161 
    162 # Bulk from stdin
    163 echo "A1,42" | xlset report.xlsx --from -
    164 ```
    165 
    166 ### Type inference
    167 
    168 Values are auto-detected: `42` becomes a number, `true` becomes boolean, `2024-01-15` becomes a date. Override with tags when needed:
    169 
    170 | Tag | Effect |
    171 |-----|--------|
    172 | `:str` | Force string (`A1:str=07401` preserves leading zero) |
    173 | `:num` | Force number |
    174 | `:bool` | Force boolean |
    175 | `:date` | Force date |
    176 
    177 ### CSV format for `--from`
    178 
    179 ```csv
    180 cell,value
    181 A1,42
    182 B2,hello world
    183 C3:str,07401
    184 D4,"value with, comma"
    185 ```
    186 
    187 ### What gets preserved
    188 
    189 xlset modifies only the cells you specify. Everything else is untouched: formatting, formulas, charts, conditional formatting, data validation, merged cells, images.
    190 
    191 ## xlfilter — Query and Filter
    192 
    193 ```bash
    194 # Filter rows by value
    195 xlfilter data.xlsx --where "State=CA"
    196 
    197 # Numeric comparisons
    198 xlfilter data.xlsx --where "Amount>1000"
    199 
    200 # Multiple filters (AND)
    201 xlfilter data.xlsx --where "State=CA" --where "Amount>1000"
    202 
    203 # Select columns (by name or letter)
    204 xlfilter data.xlsx --cols State,Amount,Year
    205 xlfilter data.xlsx --cols A,C,D
    206 
    207 # Sort results
    208 xlfilter data.xlsx --sort "Amount:desc"
    209 
    210 # Limit output
    211 xlfilter data.xlsx --sort "Amount:desc" --limit 10
    212 
    213 # Contains filter (case-insensitive)
    214 xlfilter data.xlsx --where "Name~john"
    215 
    216 # Skip metadata rows above the real header
    217 xlfilter data.xlsx --skip 2
    218 
    219 # CSV output for piping
    220 xlfilter data.xlsx --where "Status!=Draft" --csv | other-tool
    221 
    222 # Target a specific sheet
    223 xlfilter data.xlsx --sheet Revenue --where "Amount>5000"
    224 ```
    225 
    226 ### Filter operators
    227 
    228 | Operator | Meaning | Example |
    229 |----------|---------|---------|
    230 | `=` | Equals | `State=CA` |
    231 | `!=` | Not equals | `Status!=Draft` |
    232 | `>` | Greater than | `Amount>1000` |
    233 | `<` | Less than | `Year<2024` |
    234 | `>=` | Greater or equal | `Score>=90` |
    235 | `<=` | Less or equal | `Price<=50` |
    236 | `~` | Contains (case-insensitive) | `Name~john` |
    237 | `!~` | Not contains | `Name!~test` |
    238 
    239 Numeric columns compare numerically; string columns compare lexicographically. Row count is printed to stderr.
    240 
    241 ## xldiff — Compare Two Sheets
    242 
    243 ```bash
    244 # Positional diff (whole-row comparison)
    245 xldiff old.xlsx new.xlsx
    246 
    247 # Key-based diff (match rows by ID, compare cell by cell)
    248 xldiff old.xlsx new.xlsx --key ID
    249 
    250 # Composite key
    251 xldiff old.xlsx new.xlsx --key Date,Ticker
    252 
    253 # Compare sheets within the same file
    254 xldiff report.xlsx:Q1 report.xlsx:Q2
    255 
    256 # Float tolerance (differences <= 0.01 treated as equal)
    257 xldiff old.xlsx new.xlsx --key ID --tolerance 0.01
    258 
    259 # Only compare specific columns
    260 xldiff old.xlsx new.xlsx --key ID --cols Name,Salary
    261 
    262 # Skip metadata rows (different skip per file)
    263 xldiff file1.xlsx file2.xlsx --skip 3,5
    264 
    265 # Output formats
    266 xldiff old.xlsx new.xlsx --key ID --format markdown
    267 xldiff old.xlsx new.xlsx --key ID --format json
    268 xldiff old.xlsx new.xlsx --key ID --format csv
    269 ```
    270 
    271 ### Example output
    272 
    273 ```
    274 --- Sheet1 (old.xlsx)
    275 +++ Sheet1 (new.xlsx)
    276 
    277 Added: 1 | Removed: 1 | Modified: 2
    278 
    279 - ID: "3"  Name: "Charlie"  Department: "Engineering"  Salary: "88000"
    280 + ID: "5"  Name: "Eve"  Department: "Marketing"  Salary: "70000"
    281 ~ ID: "1"
    282     Salary: "95000" → "98000"
    283 ~ ID: "2"
    284     Department: "Marketing" → "Design"
    285     Salary: "72000" → "75000"
    286 ```
    287 
    288 ### Diff modes
    289 
    290 **Positional (no `--key`):** Every column defines row identity. Reports added/removed rows only.
    291 
    292 **Key-based (`--key`):** Match rows by key columns, compare remaining columns cell by cell. Reports added, removed, and modified rows with per-cell changes. Supports composite keys, duplicate key detection, and float tolerance.
    293 
    294 ### Exit codes (diff convention)
    295 
    296 | Code | Meaning |
    297 |------|---------|
    298 | 0 | No differences |
    299 | 1 | Differences found |
    300 | 2 | Error |
    301 
    302 ## Claude Code integration
    303 
    304 Claude Code skills are available in [claude-skills](https://github.com/LouLouLibs/claude-skills). Claude can view spreadsheets, analyze data, filter rows, compare files, and make targeted edits in conversations.
    305 
    306 ## Exit codes
    307 
    308 | Code | Meaning |
    309 |------|---------|
    310 | 0 | Success |
    311 | 1 | Runtime error (xldiff: differences found) |
    312 | 2 | Invalid arguments |
    313 
    314 ## License
    315 
    316 MIT