umya_spreadsheet/reader/
xlsx.rs1use std::fmt;
2use std::fs::File;
3use std::io;
4use std::path::Path;
5use std::string::FromUtf8Error;
6use std::sync::Arc;
7use std::sync::RwLock;
8
9use super::driver;
10use crate::helper::const_str::*;
11use crate::structs::drawing::Theme;
12use crate::structs::raw::RawWorksheet;
13use crate::structs::SharedStringTable;
14use crate::structs::Spreadsheet;
15use crate::structs::Stylesheet;
16use crate::structs::Worksheet;
17use crate::XlsxError;
18
19pub(crate) mod chart;
20pub(crate) mod comment;
21mod content_types;
22mod doc_props_app;
23mod doc_props_core;
24mod doc_props_custom;
25pub(crate) mod drawing;
26mod jsa_project_bin;
27mod pivot_table;
28mod rels;
29mod shared_strings;
30mod styles;
31pub(crate) mod table;
32mod theme;
33pub(crate) mod threaded_comment;
34mod vba_project_bin;
35pub(crate) mod vml_drawing;
36mod workbook;
37mod workbook_rels;
38pub(crate) mod worksheet;
39
40pub fn read_reader<R: io::Read + io::Seek>(
46 reader: R,
47 with_sheet_read: bool,
48) -> Result<Spreadsheet, XlsxError> {
49 let mut arv = zip::read::ZipArchive::new(reader)?;
50
51 let mut book = workbook::read(&mut arv)?;
52 doc_props_app::read(&mut arv, &mut book)?;
53 doc_props_core::read(&mut arv, &mut book)?;
54 doc_props_custom::read(&mut arv, &mut book)?;
55 vba_project_bin::read(&mut arv, &mut book)?;
56 jsa_project_bin::read(&mut arv, &mut book)?;
57 content_types::read(&mut arv, &mut book)?;
58 let workbook_rel = workbook_rels::read(&mut arv, &mut book)?;
59
60 book.set_theme(Theme::get_default_value());
61 for (_, type_value, rel_target) in &workbook_rel {
62 if type_value == THEME_NS {
63 let theme = theme::read(&mut arv, rel_target)?;
64 book.set_theme(theme);
65 }
66 }
67
68 shared_strings::read(&mut arv, &mut book)?;
69 styles::read(&mut arv, &mut book)?;
70
71 for sheet in book.get_sheet_collection_mut() {
72 for (rel_id, _, rel_target) in &workbook_rel {
73 if sheet.get_r_id() != rel_id {
74 continue;
75 }
76 let mut raw_worksheet = RawWorksheet::default();
77 raw_worksheet.read(&mut arv, rel_target);
78 sheet.set_raw_data_of_worksheet(raw_worksheet);
79 }
80 }
81
82 if with_sheet_read {
83 book.read_sheet_collection();
84 }
85
86 Ok(book)
87}
88
89#[inline]
100pub fn read<P: AsRef<Path>>(path: P) -> Result<Spreadsheet, XlsxError> {
101 let file = File::open(path)?;
102 read_reader(file, true)
103}
104
105#[inline]
118pub fn lazy_read(path: &Path) -> Result<Spreadsheet, XlsxError> {
119 let file = File::open(path)?;
120 read_reader(file, false)
121}
122
123pub(crate) fn raw_to_deserialize_by_worksheet(
124 worksheet: &mut Worksheet,
125 shared_string_table: &RwLock<SharedStringTable>,
126 stylesheet: &Stylesheet,
127) {
128 if worksheet.is_deserialized() {
129 return;
130 }
131
132 let raw_data_of_worksheet = worksheet.get_raw_data_of_worksheet().clone();
133 let shared_string_table = &*shared_string_table.read().unwrap();
134 worksheet::read(
135 worksheet,
136 &raw_data_of_worksheet,
137 shared_string_table,
138 stylesheet,
139 )
140 .unwrap();
141
142 if let Some(v) = raw_data_of_worksheet.get_worksheet_relationships() {
143 for relationship in v.get_relationship_list() {
144 match relationship.get_type() {
145 DRAWINGS_NS => {
147 drawing::read(
148 worksheet,
149 relationship.get_raw_file(),
150 raw_data_of_worksheet.get_drawing_relationships(),
151 )
152 .unwrap();
153 }
154 COMMENTS_NS => {
156 comment::read(worksheet, relationship.get_raw_file()).unwrap();
157 }
158 THREADED_COMMENT_NS => {
160 threaded_comment::read(worksheet, relationship.get_raw_file()).unwrap();
161 }
162 TABLE_NS => {
164 table::read(worksheet, relationship.get_raw_file()).unwrap();
165 }
166 _ => {}
167 }
168 }
169 for relationship in v.get_relationship_list() {
170 if relationship.get_type() == VML_DRAWING_NS {
172 vml_drawing::read(
173 worksheet,
174 relationship.get_raw_file(),
175 raw_data_of_worksheet.get_vml_drawing_relationships(),
176 )
177 .unwrap();
178 }
179 }
180 }
181
182 worksheet.remove_raw_data_of_worksheet();
183}