Skip to content

Commit 06ac364

Browse files
phodalcodex
andcommitted
fix(office): render xlsx error condition rules
Co-authored-by: Codex (GPT 5.5) <codex@openai.com>
1 parent 1ed83b8 commit 06ac364

3 files changed

Lines changed: 61 additions & 0 deletions

File tree

docs/issues/2026-05-01-office-document-viewer-wasm-reader.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ Routa 应能在 session canvas 或 artifact tab 中直接预览 Office 文档(
123123
- XLSX conditional-format protocol parity now emits Walnut `CfRule` fields for `aboveAverage`, `bottom`, `rank`, `stdDev`, `equalAverage`, and `timePeriod`; the debug preview also evaluates Excel serial-date time-period rules such as `last7Days` and `thisMonth`.
124124
- XLSX conditional-format precedence now sorts decoded rules by Excel/Walnut `priority` and applies `stopIfTrue` consistently across format, color-scale, data-bar, and icon-set visuals instead of relying on protocol array order.
125125
- XLSX `cellIs` conditional-format comparisons now resolve formula thresholds from absolute/relative cell references, defined names, and common date helpers such as `DATE(...)` and `TODAY()` before applying comparison operators.
126+
- XLSX conditional-format preview now applies Excel error-value rules for `containsErrors` and `notContainsErrors`, covering common values such as `#DIV/0!`, `#N/A`, `#REF!`, and `#VALUE!`.
126127

127128
## Codex 技术方案逆向分析
128129

src/app/debug/office-wasm-poc/__tests__/spreadsheet-conditional-visuals.test.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,43 @@ describe("spreadsheet conditional visuals", () => {
445445
expect(visuals.get("4:3")).toBeUndefined();
446446
});
447447

448+
it("applies error-value conditional format rules", () => {
449+
const visuals = buildSpreadsheetConditionalVisuals({
450+
conditionalFormattings: [
451+
{
452+
ranges: ["A1:A3"],
453+
rules: [
454+
{
455+
fillColor: "FCA5A5",
456+
type: "containsErrors",
457+
},
458+
],
459+
},
460+
{
461+
ranges: ["B1:B3"],
462+
rules: [
463+
{
464+
fillColor: "BBF7D0",
465+
type: "notContainsErrors",
466+
},
467+
],
468+
},
469+
],
470+
rows: [
471+
{ cells: [{ address: "A1", value: "#DIV/0!" }, { address: "B1", value: "#REF!" }], index: 1 },
472+
{ cells: [{ address: "A2", value: "#N/A" }, { address: "B2", value: "ok" }], index: 2 },
473+
{ cells: [{ address: "A3", value: "ok" }, { address: "B3", value: 42 }], index: 3 },
474+
],
475+
});
476+
477+
expect(visuals.get("1:0")?.background).toBe("#FCA5A5");
478+
expect(visuals.get("2:0")?.background).toBe("#FCA5A5");
479+
expect(visuals.get("3:0")).toBeUndefined();
480+
expect(visuals.get("1:1")).toBeUndefined();
481+
expect(visuals.get("2:1")?.background).toBe("#BBF7D0");
482+
expect(visuals.get("3:1")?.background).toBe("#BBF7D0");
483+
});
484+
448485
it("applies duplicate and unique value conditional format rules", () => {
449486
const visuals = buildSpreadsheetConditionalVisuals({
450487
conditionalFormattings: [

src/app/debug/office-wasm-poc/spreadsheet-conditional-visuals.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,14 @@ function conditionalTextMatches(
804804
return normalizedText.length > 0;
805805
}
806806

807+
if (type === "containsErrors") {
808+
return spreadsheetErrorValueMatches(normalizedText);
809+
}
810+
811+
if (type === "notContainsErrors") {
812+
return !spreadsheetErrorValueMatches(normalizedText);
813+
}
814+
807815
if (type === "duplicateValues") {
808816
return normalizedText.length > 0 && (textCounts?.get(normalizedText) ?? 0) > 1;
809817
}
@@ -875,6 +883,21 @@ function conditionalTextMatches(
875883
return false;
876884
}
877885

886+
function spreadsheetErrorValueMatches(text: string): boolean {
887+
const normalized = text.toUpperCase();
888+
return normalized === "#DIV/0!" ||
889+
normalized === "#N/A" ||
890+
normalized === "#NAME?" ||
891+
normalized === "#NULL!" ||
892+
normalized === "#NUM!" ||
893+
normalized === "#REF!" ||
894+
normalized === "#VALUE!" ||
895+
normalized === "#SPILL!" ||
896+
normalized === "#CALC!" ||
897+
normalized === "#FIELD!" ||
898+
normalized === "#GETTING_DATA";
899+
}
900+
878901
function conditionalCellFormulaNumber(
879902
formula: unknown,
880903
definedNames?: unknown,

0 commit comments

Comments
 (0)