use std::io::{Read, Seek};
use anyhow::bail;
use calculation_properties::XlsxCalculationProperties;
use custom_workbook_view::{load_custom_bookviews, XlsxCustomWorkbookViews};
use defined_name::{load_defined_names, XlsxDefinedNames};
use quick_xml::events::Event;
use sheet::{load_sheets, XlsxSheets};
use workbook_properties::XlsxWorkbookProperties;
use workbook_view::{load_bookviews, XlsxWorkbookViews};
use zip::ZipArchive;
use crate::excel::xml_reader;
pub mod calculation_properties;
pub mod custom_workbook_view;
pub mod defined_name;
pub mod sheet;
pub mod workbook_properties;
pub mod workbook_view;
#[derive(Debug, Clone, PartialEq)]
pub struct XlsxWorkbook {
pub bookviews: Option<XlsxWorkbookViews>,
pub calculation_propertis: Option<XlsxCalculationProperties>,
pub custom_workbook_views: Option<XlsxCustomWorkbookViews>,
pub defined_names: Option<XlsxDefinedNames>,
pub sheets: Option<XlsxSheets>,
pub workbook_properties: Option<XlsxWorkbookProperties>,
}
impl XlsxWorkbook {
pub(crate) fn load(zip: &mut ZipArchive<impl Read + Seek>) -> anyhow::Result<Self> {
let path = "xl/workbook.xml";
let mut workbook = Self {
bookviews: None,
calculation_propertis: None,
custom_workbook_views: None,
defined_names: None,
sheets: None,
workbook_properties: None,
};
let Some(mut reader) = xml_reader(zip, path) else {
return Ok(workbook);
};
let mut buf = Vec::new();
loop {
buf.clear();
match reader.read_event_into(&mut buf) {
Ok(Event::Start(ref e)) if e.local_name().as_ref() == b"extLst" => {
let _ = reader.read_to_end_into(e.to_end().to_owned().name(), &mut Vec::new());
}
Ok(Event::Start(ref e)) if e.local_name().as_ref() == b"bookViews" => {
workbook.bookviews = Some(load_bookviews(&mut reader)?);
}
Ok(Event::Start(ref e)) if e.local_name().as_ref() == b"calcPr" => {
workbook.calculation_propertis = Some(XlsxCalculationProperties::load(e)?);
}
Ok(Event::Start(ref e)) if e.local_name().as_ref() == b"customWorkbookViews" => {
workbook.custom_workbook_views = Some(load_custom_bookviews(&mut reader)?);
}
Ok(Event::Start(ref e)) if e.local_name().as_ref() == b"definedNames" => {
workbook.defined_names = Some(load_defined_names(&mut reader)?);
}
Ok(Event::Start(ref e)) if e.local_name().as_ref() == b"sheets" => {
workbook.sheets = Some(load_sheets(&mut reader)?);
}
Ok(Event::Start(ref e)) if e.local_name().as_ref() == b"workbookPr" => {
workbook.workbook_properties = Some(XlsxWorkbookProperties::load(e)?);
}
Ok(Event::End(ref e)) if e.local_name().as_ref() == b"workbook" => break,
Ok(Event::Eof) => break,
Err(e) => bail!(e.to_string()),
_ => (),
}
}
return Ok(workbook);
}
}