diff --git a/crates/xlsx/src/feature_bags.rs b/crates/xlsx/src/feature_bags.rs
index 71a6514a5..db2e73e91 100644
--- a/crates/xlsx/src/feature_bags.rs
+++ b/crates/xlsx/src/feature_bags.rs
@@ -25,10 +25,13 @@ pub const XF_EXT_URI: &str = "{C7286773-470A-42A8-94C5-96B5CB345126}";
/// The bags for one checkbox cell control, referenced as `xfComplement i="0"`: Checkbox (0),
/// XFControls → 0 (1), XFComplement → 1 (2), XFComplements mapping index 0 → 2 (3). Every
-/// reference points to an earlier bag, as [MS-XLSX] 2.6.230 requires.
+/// reference points to an earlier bag, as [MS-XLSX] 2.6.230 requires. The XFComplements bag is
+/// the one `xfComplement` indexes into, and Excel finds it by its `extRef`: without
+/// `extRef="XFComplementsMapperExtRef"` it repairs the workbook ("Format from /xl/styles.xml")
+/// and drops every checkbox (#2630).
pub fn checkbox_part() -> String {
format!(
- "\n012"
+ "\n012"
)
}
@@ -73,6 +76,9 @@ mod tests {
fn written_chain_resolves_and_hostile_chains_do_not() {
let root = crate::xml::parse(checkbox_part().as_bytes()).unwrap_or_default();
assert_eq!(checkbox_complements(&root), vec![true]);
+ // #2630: Excel repairs the file unless the mapping bag carries this extRef.
+ let mapper = root.kids("bag").find(|b| b.attr("type") == Some("XFComplements"));
+ assert_eq!(mapper.and_then(|b| b.attr("extRef")), Some("XFComplementsMapperExtRef"));
// Out-of-range, wrong-type and self references resolve to false without panicking.
let bad = format!(
"99114294967295x"