//! //! A workbook is composed of workbook-level properties and a collection of 1 or more sheets. //! The workbook part and corresponding properties comprise data //! used to set application and workbook-level operational state. The workbook also serves to bind all the sheets //! and child elements into an organized single file. The workbook XML attributes and elements include information //! about what application last saved the file, where and how the windows of the workbook were positioned, and //! an enumeration of the worksheets in the workbook. //! This is the XML for the smallest possible (blank) workbook: //! //! //! //! //! //! //! //! Note that this workbook has a single sheet, named Sheet1. An Id for the sheet is required, and a relationship Id //! pointing to the location of the sheet definition is also required. //! //! //! //! The most important objet of this part is a collection of all the sheets and all the defined names //! of the workbook. //! //! It also may hold state properties like the selected tab //! # bookViews //! use std::collections::HashMap; use ironcalc_base::types::{SheetState, Workbook}; use super::escape::escape_xml; use super::xml_constants::XML_DECLARATION; pub(crate) fn get_workbook_xml(workbook: &Workbook, selected_sheet: u32) -> String { // sheets // let mut sheets_str: Vec = vec![]; let mut sheet_id_to_sheet_index: HashMap = HashMap::new(); for (sheet_index, worksheet) in workbook.worksheets.iter().enumerate() { let name = &worksheet.name; let name = escape_xml(name); let sheet_id = worksheet.sheet_id; let state_str = match &worksheet.state { SheetState::Visible => "", SheetState::Hidden => " state=\"hidden\"", SheetState::VeryHidden => " state=\"veryHidden\"", }; sheets_str.push(format!( "", sheet_index + 1 )); sheet_id_to_sheet_index.insert(sheet_id, sheet_index as u32); } // defined names // shared!$G$5 // Sheet1!$A$16:$A$18 let mut defined_names_str: Vec = vec![]; for defined_name in &workbook.defined_names { let name = &defined_name.name; let name = escape_xml(name); let local_sheet_id = if let Some(sheet_id) = defined_name.sheet_id { // In Excel the localSheetId is actually the index of the sheet. let excel_local_sheet_id = sheet_id_to_sheet_index.get(&sheet_id).unwrap(); format!(" localSheetId=\"{excel_local_sheet_id}\"") } else { "".to_string() }; let formula = escape_xml(&defined_name.formula); defined_names_str.push(format!( "{formula}" )) } let sheets = sheets_str.join(""); let defined_names = defined_names_str.join(""); format!("{XML_DECLARATION}\n\ \ \ \ {sheets}\ \ \ {defined_names}\ \ \ ") }