mirror of
https://github.com/storytold/gridcraft.git
synced 2026-10-24 10:46:50 -06:00
XLSX: new workbooks get <fileVersion appName="gridcraft"/> (fixes #1699)
A workbook GridCraft created had no <fileVersion> in workbook.xml; it now names GridCraft, and keeps it on later saves. A workbook read from an Excel file still keeps its <fileVersion> as it was, appName="xl" included. Observed in Excel 16.114: with the calcFeatures extension present, Excel uses the saved cell values only when appName is "xl". appName="gridcraft", "Calc" or no appName makes it recalculate everything on open, which brings back #799 (lookups into closed workbooks open as #CALC!). The application that last saved the file is recorded in docProps/app.xml <Application>GridCraft</Application>, which GridCraft already writes on every save and which Excel's recalculation ignores.
This commit is contained in:
@@ -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}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -314,7 +314,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(if wb.date_system == gridcraft_core::DateSystem::D1904 { "<workbookPr date1904=\"1\"/>" } else { "<workbookPr/>" });
|
||||
if wb.protected_structure {
|
||||
let pw = wb.structure_password.as_ref().map(|h| crate::sheet_write::password_attrs(h, "workbook")).unwrap_or_default();
|
||||
|
||||
Reference in New Issue
Block a user