Merge PR #1701: XLSX: new workbooks get <fileVersion appName="gridcraft"/>

Conflicts:
- crates/xlsx/src/write.rs: keeps #1701's fileVersion block followed by #1626's workbookPr attributes (showObjects, date1904)
This commit is contained in:
aiongg
2026-10-22 02:37:05 +00:00
2 changed files with 16 additions and 4 deletions
+12 -3
View File
@@ -819,7 +819,16 @@ fn file_version_and_calc_features_survive_a_save() {
assert!(text.contains(&format!("<extLst>{calc_features}</extLst>")), "{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 <fileVersion> 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#"<fileVersion appName="gridcraft"/>"#) && !plain.contains("extLst"), "{plain}");
}
}
+4 -1
View File
@@ -328,7 +328,10 @@ pub fn write_xlsx(wb: &Workbook, kind: XlsxKind) -> Result<Vec<u8>, IoError> {
}
let mut w = format!("{XML_DECL}<workbook xmlns=\"{NS_MAIN}\" xmlns:r=\"{NS_REL}\">");
w.push_str(&crate::passthrough::workbook_elements(wb, "fileVersion"));
// A workbook read from a file keeps its <fileVersion> 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() { "<fileVersion appName=\"gridcraft\"/>" } else { &file_version });
w.push_str("<workbookPr");
match wb.show_objects {
ShowObjects::All => {}