use std::fmt;
use std::fs::File;
use std::io;
use std::path::Path;
use std::string::FromUtf8Error;
use std::sync::Arc;
use std::sync::RwLock;
use super::driver;
use crate::helper::const_str::*;
use crate::structs::drawing::Theme;
use crate::structs::raw::RawWorksheet;
use crate::structs::SharedStringTable;
use crate::structs::Spreadsheet;
use crate::structs::Stylesheet;
use crate::structs::Worksheet;
use crate::XlsxError;
pub(crate) mod chart;
pub(crate) mod comment;
mod content_types;
mod doc_props_app;
mod doc_props_core;
mod doc_props_custom;
pub(crate) mod drawing;
mod jsa_project_bin;
mod pivot_table;
mod rels;
mod shared_strings;
mod styles;
pub(crate) mod table;
mod theme;
pub(crate) mod threaded_comment;
mod vba_project_bin;
pub(crate) mod vml_drawing;
mod workbook;
mod workbook_rels;
pub(crate) mod worksheet;
pub fn read_reader<R: io::Read + io::Seek>(
reader: R,
with_sheet_read: bool,
) -> Result<Spreadsheet, XlsxError> {
let mut arv = zip::read::ZipArchive::new(reader)?;
let mut book = workbook::read(&mut arv)?;
doc_props_app::read(&mut arv, &mut book)?;
doc_props_core::read(&mut arv, &mut book)?;
doc_props_custom::read(&mut arv, &mut book)?;
vba_project_bin::read(&mut arv, &mut book)?;
jsa_project_bin::read(&mut arv, &mut book)?;
content_types::read(&mut arv, &mut book)?;
let workbook_rel = workbook_rels::read(&mut arv, &mut book)?;
book.set_theme(Theme::get_default_value());
for (_, type_value, rel_target) in &workbook_rel {
if type_value == THEME_NS {
let theme = theme::read(&mut arv, rel_target)?;
book.set_theme(theme);
}
}
shared_strings::read(&mut arv, &mut book)?;
styles::read(&mut arv, &mut book)?;
for sheet in book.get_sheet_collection_mut() {
for (rel_id, _, rel_target) in &workbook_rel {
if sheet.get_r_id() != rel_id {
continue;
}
let mut raw_worksheet = RawWorksheet::default();
raw_worksheet.read(&mut arv, rel_target);
sheet.set_raw_data_of_worksheet(raw_worksheet);
}
}
if with_sheet_read {
book.read_sheet_collection();
}
Ok(book)
}
#[inline]
pub fn read<P: AsRef<Path>>(path: P) -> Result<Spreadsheet, XlsxError> {
let file = File::open(path)?;
read_reader(file, true)
}
#[inline]
pub fn lazy_read(path: &Path) -> Result<Spreadsheet, XlsxError> {
let file = File::open(path)?;
read_reader(file, false)
}
pub(crate) fn raw_to_deserialize_by_worksheet(
worksheet: &mut Worksheet,
shared_string_table: &RwLock<SharedStringTable>,
stylesheet: &Stylesheet,
) {
if worksheet.is_deserialized() {
return;
}
let raw_data_of_worksheet = worksheet.get_raw_data_of_worksheet().clone();
let shared_string_table = &*shared_string_table.read().unwrap();
worksheet::read(
worksheet,
&raw_data_of_worksheet,
shared_string_table,
stylesheet,
)
.unwrap();
if let Some(v) = raw_data_of_worksheet.get_worksheet_relationships() {
for relationship in v.get_relationship_list() {
match relationship.get_type() {
DRAWINGS_NS => {
drawing::read(
worksheet,
relationship.get_raw_file(),
raw_data_of_worksheet.get_drawing_relationships(),
)
.unwrap();
}
COMMENTS_NS => {
comment::read(worksheet, relationship.get_raw_file()).unwrap();
}
THREADED_COMMENT_NS => {
threaded_comment::read(worksheet, relationship.get_raw_file()).unwrap();
}
TABLE_NS => {
table::read(worksheet, relationship.get_raw_file()).unwrap();
}
_ => {}
}
}
for relationship in v.get_relationship_list() {
if relationship.get_type() == VML_DRAWING_NS {
vml_drawing::read(
worksheet,
relationship.get_raw_file(),
raw_data_of_worksheet.get_vml_drawing_relationships(),
)
.unwrap();
}
}
}
worksheet.remove_raw_data_of_worksheet();
}