Conditional Formatting
Witan supports Excel conditional formatting as workbook rules attached to worksheet ranges. Use conditional formatting to make outliers, thresholds, trends, exceptions, and input states visible without changing the underlying cell values.
Conditional formatting is a workbook feature, not a standalone verifier. Scripts can inspect rules, add or replace rules, remove rules by index, and render the visible result with Witan Render.
Supported Rules
| Rule family | What it covers |
|---|---|
| Cell value | Comparison rules: equal, not equal, greater than, greater than or equal, less than, less than or equal, between, and not between |
| Text | Contains, does not contain, begins with, and ends with |
| Blank and error | Contains blanks, does not contain blanks, contains errors, and does not contain errors |
| Expression | Formula-backed rules evaluated relative to the target range |
| Time period | Today, yesterday, tomorrow, last 7 days, this/last/next week, and this/last/next month |
| Top and bottom | Top or bottom rank, by item count or percent |
| Average | Above average, below average, equal-average variants, and standard deviation thresholds |
| Duplicate and unique | Duplicate-value and unique-value rules |
| Color scales | Two-color and three-color scales with min, max, number, percent, percentile, and formula thresholds |
| Data bars | Positive and negative bars, value display, gradients, borders, axis position, direction, and threshold options |
| Icon sets | Icon-set style metadata is represented; icon glyphs are not currently drawn in range renders |
Rules can include differential styles for fills, fonts, borders, number formats, alignment, and protection where those styles apply to the rule type. Color scales, data bars, and icon sets carry their own visual configuration instead of a normal differential style.
Inspect Rules
Use getConditionalFormatting to list the rules on a sheet:
witan xlsx exec report.xlsx --expr 'await xlsx.getConditionalFormatting(wb, "Summary")'
Each returned rule includes:
index: the sheet-local rule index, used byremoveConditionalFormatting.address: the target range or multi-area range.type: the rule family.priorityandstopIfTrue: Excel rule ordering behavior where present.- Rule-specific fields such as
operator,formula,formula2,text,rank,timePeriod, scale thresholds, data bar options, or icon set style. style: the differential style for rule types that apply cell formatting.
Add Rules
Use setConditionalFormatting to append rules to a sheet:
witan xlsx exec report.xlsx --save --stdin <<'WITAN'
await xlsx.setConditionalFormatting(wb, "Summary", [
{
address: "B2:B20",
type: "cellValue",
operator: "greaterThan",
formula: "100000",
style: {
fill: { color: "#E2F0D9" },
font: { color: "#375623", bold: true }
}
}
])
WITAN
Use formula-backed expression rules when the condition depends on nearby cells:
await xlsx.setConditionalFormatting(wb, "Summary", [
{
address: "D2:D20",
type: "expression",
formula: "=$D2<$C2",
style: {
fill: { color: "#FCE4D6" },
font: { color: "#9C0006" }
}
}
])
Use color scales or data bars for quantitative ranges:
await xlsx.setConditionalFormatting(wb, "Summary", [
{
address: "E2:E20",
type: "threeColorScale",
lowValue: { type: "min", color: "#F8696B" },
midValue: { type: "percentile", value: 50, color: "#FFEB84" },
highValue: { type: "max", color: "#63BE7B" }
},
{
address: "F2:F20",
type: "dataBar",
dataBar: {
fillColor: "#4472C4",
negativeFillColor: "#C00000",
axisPosition: "automatic"
}
}
])
Replace And Remove Rules
By default, setConditionalFormatting appends rules to the sheet:
await xlsx.setConditionalFormatting(wb, "Summary", rules)
Pass { clear: true } to replace all existing rules on the sheet with the provided rules:
await xlsx.setConditionalFormatting(wb, "Summary", rules, { clear: true })
To remove rules, read the current rules, choose their index values, and pass those indices to removeConditionalFormatting:
const rules = await xlsx.getConditionalFormatting(wb, "Summary")
const stale = rules
.filter(rule => rule.address === "B2:B20")
.map(rule => rule.index)
await xlsx.removeConditionalFormatting(wb, "Summary", stale)
removeConditionalFormatting removes by index and preserves the relative order of the remaining rules.
Multi-Area Rules
A rule can target a union of concrete A1 ranges on the same sheet:
await xlsx.setConditionalFormatting(wb, "Summary", [
{
address: "A1:A10,D1:D10",
type: "duplicateValues",
style: { fill: { color: "#FFF2CC" } }
}
])
Conditional formatting addresses must resolve to concrete ranges on the sheet passed to setConditionalFormatting. Defined-name targets are not accepted for rule addresses.
Rendering
Witan Render evaluates conditional formatting before drawing cells, so rendered ranges show matching fills, fonts, borders, number formats, color scales, and data bars.
Icon-set rules are represented through the conditional formatting model, but icon glyphs are not currently drawn in range renders.
Use a render or diff after changing conditional formatting:
witan xlsx render report.xlsx -r "Summary!A1:F20"
Notes And Limits
- Conditional formatting rules are stored as normal Excel workbook rules and round-trip through
.xlsxfiles. - Rule
priorityandstopIfTrueare preserved for Excel workbooks. - Invalid rule payloads are rejected before mutation, including when
{ clear: true }is used.
See xlsx API for exact TypeScript and Python signatures.