A CLI tool for finding differences between Excel files based on a UID column.
Project description
diffxl
diffxl is a robust CLI tool designed to compare two Excel tables based on a Unique Identifier (UID). It identifies exactly what has been added, removed, or changed, and generates portable reports in both XLSX and HTML formats.
The Use Case
A typical use case involves comparing two revisions of the same document to answer: "What has been added, removed, or changed in the table, and how have the cell values shifted?"
Example: In plant engineering projects, diffxl can compare two revisions of a valve list. It produces a clear audit trail showing exactly which technical details (pressure ratings, materials, tag numbers) have changed since the last submission.
Quick Start Logic
diffxl is built for quickly getting a comparison done. It attempts to perform a comparison even with minimal configuration:
- No Key Column? It defaults to the active sheet, and automatically detects the table header and uses the left-most column as the UID.
- No Sheet Name? It scans through the file to find which sheet contains the table with the UID column.
- The html report is opened automatically after a successful diff.
Features
Deep Comparison
- Row-Level Diff: Identifies Added and Removed rows based on the UID.
- Cell-Level Diff: Highlights exactly which cell values have Changed between revisions.
- Format Support: Compatible with
.xlsx,.xlsm,.xls, and.csv.
Reporting
- Interactive Web Report: Generates an HTML report with filtering, highlighting, and inline value comparisons.
- Excel Diff Report: Generates a multi-sheet Excel workbook separating Additions, Removals, and Changes per column for easy filtering. Also includes a color-coded complete table similar to the html report.
Smart Processing
- Auto-Detection: Automatically locates the table header, ignoring metadata or titles above/below the actual data.
- NaN Normalization: By default, treats
NaN,None, and""as equal to reduce noise. (Disable with--raw). - Failure Analysis: If a comparison fails (e.g., a missing key),
diffxlanalyzes the files and suggests the most likely UID columns. - Duplicate Handling: The
--dedupflag allows processing of files with duplicate UIDs by keeping the first occurrence and logging the ignored rows.
Installation
pip install diffxl
Usage
# Simple usage (uses leftmost column as key, generates Excel + HTML)
diffxl <old_file> <new_file>
# Specify a key column
diffxl <old_file> <new_file> --key "Tag"
Alternatively, run directly with uvx:
uvx diffxl <old_file> <new_file>
Arguments
old_file: Path to the original file.new_file: Path to the new file.--key,-k: The column name to use as the unique identifier (default: column furthest to the left in the identified table).--sheet,-s: (Optional) Specific sheet name to compare.--output,-o: Output filename or path for the xlsx report(default:diff_report.xlsx). html report will be saved in the same directory with the same name.--prefix,-p: Add a prefix to output filenames (e.g.,ABC_diff_report.xlsx) to keep track of multiple runs.--raw: Perform exact string comparison (disable smart normalization like treatingNaNas equal toNone).--no-web: Disable HTML report generation.--diagnostic,-d: Generate a detailed HTML diagnostic report if validation fails.--dedup: Remove duplicate rows based on Key column (keeps first occurrence).
Example
diffxl samples/valvelist_v1.xlsx samples/valvelist_v2.xlsx --prefix "valves_v1_v2_"
Output
By default, the tool generates:
- Excel Report (
diff_report.xlsx): Contains Added, Removed, Changed, and Complete diff sheets. - Web Report (
diff_report.html): An interactive comparison view.
Smart Diagnostics
If the tool cannot find your specified key column, it will automatically analyze the file and suggest alternative columns that look like unique identifiers (UIDs), sorted by confidence.
To get a full visual analysis when something goes wrong, run with:
diffxl <old_file> <new_file> --key "WrongKey" --diagnostic
Development
This project uses uv for dependency management.
# Install dependencies
uv sync
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file diffxl-0.1.0.tar.gz.
File metadata
- Download URL: diffxl-0.1.0.tar.gz
- Upload date:
- Size: 79.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4455336dd7cb238c6fc00b549fa267893c1e5f18ea6e0eee2766d1ec21f0aca4
|
|
| MD5 |
1bde27dc29d41d688230cf6e70255bbc
|
|
| BLAKE2b-256 |
020896afccacdcd73455c63af2274259b193c94484be86d5e685193fc037ffd8
|
Provenance
The following attestation bundles were made for diffxl-0.1.0.tar.gz:
Publisher:
publish.yml on meerola/diffxl
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
diffxl-0.1.0.tar.gz -
Subject digest:
4455336dd7cb238c6fc00b549fa267893c1e5f18ea6e0eee2766d1ec21f0aca4 - Sigstore transparency entry: 833673083
- Sigstore integration time:
-
Permalink:
meerola/diffxl@28c95d42a969661917b5968fdc034e864e5c5eb6 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/meerola
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@28c95d42a969661917b5968fdc034e864e5c5eb6 -
Trigger Event:
release
-
Statement type:
File details
Details for the file diffxl-0.1.0-py3-none-any.whl.
File metadata
- Download URL: diffxl-0.1.0-py3-none-any.whl
- Upload date:
- Size: 28.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b1f1d7861ee637d9e7217b53f0941f31444347b7054dbe70c425648d96905016
|
|
| MD5 |
0bf6353c7552d33d09b9f9bf3439c81a
|
|
| BLAKE2b-256 |
3546e815e3067b90523e77a8e14c47a64fd0ea5b5596dbe6010b2029bdcf50e7
|
Provenance
The following attestation bundles were made for diffxl-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on meerola/diffxl
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
diffxl-0.1.0-py3-none-any.whl -
Subject digest:
b1f1d7861ee637d9e7217b53f0941f31444347b7054dbe70c425648d96905016 - Sigstore transparency entry: 833673084
- Sigstore integration time:
-
Permalink:
meerola/diffxl@28c95d42a969661917b5968fdc034e864e5c5eb6 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/meerola
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@28c95d42a969661917b5968fdc034e864e5c5eb6 -
Trigger Event:
release
-
Statement type: