//!
//! 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}\
\
\
")
}