diff --git a/crates/xlsx/src/tests/passthrough_tests.rs b/crates/xlsx/src/tests/passthrough_tests.rs index eff83703e..c3211492a 100644 --- a/crates/xlsx/src/tests/passthrough_tests.rs +++ b/crates/xlsx/src/tests/passthrough_tests.rs @@ -819,7 +819,16 @@ fn file_version_and_calc_features_survive_a_save() { assert!(text.contains(&format!("{calc_features}")), "{text}"); } - // A workbook that had neither gets neither. - let plain = Unpacked::new(&write_xlsx(&gridcraft_model::Workbook::new()).unwrap()).text("xl/workbook.xml"); - assert!(!plain.contains("fileVersion") && !plain.contains("extLst"), "{plain}"); + // A workbook that had neither gets a naming GridCraft (#1699), kept on the next + // save, and no calcFeatures: Excel recalculates it on open. + let new = write_xlsx(&gridcraft_model::Workbook::new()).unwrap(); + let (reread, _) = read_xlsx(&new).unwrap(); + for saved in [new, write_xlsx(&reread).unwrap()] { + let u = Unpacked::new(&saved); + u.assert_valid(); + let plain = u.text("xl/workbook.xml"); + let root = xml::parse(plain.as_bytes()).unwrap(); + assert_eq!(root.children.first().map(|e| e.name.as_str()), Some("fileVersion"), "{plain}"); + assert!(plain.contains(r#""#) && !plain.contains("extLst"), "{plain}"); + } } diff --git a/crates/xlsx/src/write.rs b/crates/xlsx/src/write.rs index c4a8bac01..fa69e1572 100644 --- a/crates/xlsx/src/write.rs +++ b/crates/xlsx/src/write.rs @@ -328,7 +328,10 @@ pub fn write_xlsx(wb: &Workbook, kind: XlsxKind) -> Result, IoError> { } let mut w = format!("{XML_DECL}"); - w.push_str(&crate::passthrough::workbook_elements(wb, "fileVersion")); + // A workbook read from a file keeps its as it was: Excel trusts the saved values + // only when appName is "xl" (#799). One without names GridCraft (#1699), and Excel recalculates it. + let file_version = crate::passthrough::workbook_elements(wb, "fileVersion"); + w.push_str(if file_version.is_empty() { "" } else { &file_version }); w.push_str(" {}