Implement conditional formatting#628
Open
ddimaria wants to merge 2 commits into
Open
Conversation
Collaborator
|
PR #538 will have to be resolved before this can be reviewed/merged. |
3 tasks
1b68eb9 to
8ba7b7d
Compare
…eet layout Add style support for Calamine xlsx files. Public API: - `Xlsx::worksheet_style(sheet)` returns a row x col grid of cell styles using run-length encoding for memory efficiency on large workbooks. - `Xlsx::worksheet_layout(sheet)` returns column widths and row heights. Style types (in `src/style.rs`): - `Style` with optional Font / Fill / Borders / Alignment / NumberFormat / Protection. - `Color` with theme + tint resolution and indexed-color fallback. - `RichText` / `TextRun` for cells with mixed inline formatting. - `StyleRange` with RLE storage and a `cells()` iterator. Parser in `src/xlsx/style_parser.rs` handles fonts (bold / italic / underline / strikethrough / sz / color), fills, borders (with color and style per side), number formats (built-in + custom format codes), alignment (horizontal / vertical / wrap / indent / shrink / text rotation incl. stacked), protection (locked default per OOXML), theme colors with tint, and sysClr lastClr fallback. Shared-string reader now decodes rich text runs and preserves their formatting, while also handling plain text that precedes rich runs (consistent with upstream PR tafia#637). Includes benchmarks in `benches/style.rs` and test fixtures (styles.xlsx, borders.xlsx, EMSI_JobChange_UK.xlsx, problematic_formats.xlsx, styles_1M.xlsx) covering the various code paths. Co-authored-by: Cursor <cursoragent@cursor.com>
Add conditional formatting parsing for xlsx files. Builds on the
styles work added in the preceding commit.
Public API:
```rust
// vector of conditional formatting blocks for the named sheet
let cfs = xlsx.worksheet_conditional_formatting("Sheet1")?;
for cf in &cfs {
println!("range {}: {} rule(s)", cf.sqref, cf.rules.len());
for rule in &cf.rules {
match &rule.rule_type {
ConditionalFormatRuleType::CellIs { operator, formulas } => { /* ... */ }
ConditionalFormatRuleType::ColorScale3 { /* ... */ } => { /* ... */ }
/* ... */
}
}
}
```
Supported rule types (`src/conditional_format.rs`):
- `CellIs` (greaterThan, lessThan, between, equal, etc.)
- `ColorScale2` and `ColorScale3`
- `DataBar` (with fill and optional border color)
- `IconSet` (3TrafficLights, 5Arrows, ..., with `reversed` / `showValue`)
- `Top10` (top / bottom, percent / count)
- `AboveAverage` (above / below, equal-average, stdDev)
- `Text` (contains, notContains, beginsWith, endsWith)
- `ContainsBlanks` / `NotContainsBlanks`
- `ContainsErrors` / `NotContainsErrors`
- `DuplicateValues` / `UniqueValues`
- `Expression`
- `TimePeriod`
- `Unknown` (forwards the raw type for unrecognised rules)
Each rule carries `priority`, `stop_if_true`, the optional resolved
`Format` (looked up from the `<dxfs>` table), and any per-rule formula
strings.
Includes a criterion benchmark (`benches/conditional_formatting.rs`),
an example (`examples/conditional_formatting.rs`), and a fixture
covering all 25 supported rule variants (`tests/conditional_formatting.xlsx`).
Co-authored-by: Cursor <cursoragent@cursor.com>
8ba7b7d to
b2ac03f
Compare
Collaborator
|
@ddimaria just to give you a heads up that I will get to this and merge it in the next release +1. Can you keep it up to date with the current main branch and resolve any conflicts. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add conditional formatting support for XLSX
Adds read support for conditional formatting rules from XLSX worksheets. This parses
<conditionalFormatting>elements and their child<cfRule>nodes, resolving differential format styles (dxf) into the existingStyletype.Branched from #653, so this should be reviewed after 653 is merged into main.
Supported rule types
CellIs(all operators: equal, between, greaterThan, etc.)ColorScale2,ColorScale3DataBar(with fill and border colors)IconSet(all 20 built-in icon set types)Top10(rank, percent, bottom)AboveAverage(with std deviation support)Text(contains, notContains, beginsWith, endsWith)TimePeriod(yesterday, today, last7Days, etc.)ExpressionContainsBlanks,NotContainsBlanks,ContainsErrors,NotContainsErrorsDuplicateValues,UniqueValuesUnknown(preserves raw type string)API
Two new public methods on
Xlsx<RS>:worksheet_conditional_formatting(&mut self, name: &str)-- by sheet nameworksheet_conditional_formatting_at(&mut self, index: usize)-- by sheet indexBoth return
Vec<ConditionalFormatting>, where each block contains the targetsqrefrange and a list of prioritized rules with resolvedStyleformats.Changes
src/conditional_format.rs(new): Public data model --ConditionalFormatting,ConditionalFormatRule,ConditionalFormatRuleType, and supporting enums (CfOperator,CfTextOperator,CfValueObject,IconSetType,TimePeriodType, etc.)src/xlsx/mod.rs: Parses<dxfs>fromstyles.xmlinto differential format styles; addsparse_conditional_formattingsand helpers (parse_cf_rules,parse_single_cf_rule,parse_color_scale,parse_data_bar,parse_icon_set,parse_cfvo) to walk the worksheet XMLsrc/lib.rs: Re-exports all new public typestests/test.rs: 29 new tests covering every rule type variant, multi-rule blocks,stop_if_true, reversed icon sets, bottom-percent, std-dev below-average, unknown types, and dxf style resolutiontests/conditional_formatting.xlsx(new): Test fixture with 25 conditional formatting blocksExample & Benchmarks
examples/conditional_formatting.rs: Demonstrates reading and printing all conditional formatting rules from a workbookbenches/conditional_formatting.rs: Criterion benchmarks for three scenarios:cf_small_25_blocks-- real-world file with 25 CF blockscf_large_200_blocks_1000_rules-- synthetic file with 200 blocks / 1,000 rulescf_large_with_dxf_access-- large file with dxf style resolutionRun with:
Test plan
cargo run --example conditional_formattingcargo bench --bench conditional_formatting