UPDATE: Dump of initial files
This commit is contained in:
124
xlsx/src/import/mod.rs
Normal file
124
xlsx/src/import/mod.rs
Normal file
@@ -0,0 +1,124 @@
|
||||
mod colors;
|
||||
mod metadata;
|
||||
mod shared_strings;
|
||||
mod styles;
|
||||
mod tables;
|
||||
mod util;
|
||||
mod workbook;
|
||||
mod worksheets;
|
||||
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
fs,
|
||||
io::{BufReader, Read},
|
||||
};
|
||||
|
||||
use roxmltree::Node;
|
||||
|
||||
use ironcalc_base::{
|
||||
model::Model,
|
||||
types::{Metadata, Workbook, WorkbookSettings},
|
||||
};
|
||||
|
||||
use crate::error::XlsxError;
|
||||
|
||||
use shared_strings::read_shared_strings;
|
||||
|
||||
use metadata::load_metadata;
|
||||
use styles::load_styles;
|
||||
use util::get_attribute;
|
||||
use workbook::load_workbook;
|
||||
use worksheets::{load_sheets, Relationship};
|
||||
|
||||
fn load_relationships<R: Read + std::io::Seek>(
|
||||
archive: &mut zip::ZipArchive<R>,
|
||||
) -> Result<HashMap<String, Relationship>, XlsxError> {
|
||||
let mut file = archive.by_name("xl/_rels/workbook.xml.rels")?;
|
||||
let mut text = String::new();
|
||||
file.read_to_string(&mut text)?;
|
||||
let doc = roxmltree::Document::parse(&text)?;
|
||||
let nodes: Vec<Node> = doc
|
||||
.descendants()
|
||||
.filter(|n| n.has_tag_name("Relationship"))
|
||||
.collect();
|
||||
let mut rels = HashMap::new();
|
||||
for node in nodes {
|
||||
rels.insert(
|
||||
get_attribute(&node, "Id")?.to_string(),
|
||||
Relationship {
|
||||
rel_type: get_attribute(&node, "Type")?.to_string(),
|
||||
target: get_attribute(&node, "Target")?.to_string(),
|
||||
},
|
||||
);
|
||||
}
|
||||
Ok(rels)
|
||||
}
|
||||
|
||||
fn load_xlsx_from_reader<R: Read + std::io::Seek>(
|
||||
name: String,
|
||||
reader: R,
|
||||
locale: &str,
|
||||
tz: &str,
|
||||
) -> Result<Workbook, XlsxError> {
|
||||
let mut archive = zip::ZipArchive::new(reader)?;
|
||||
|
||||
let mut shared_strings = read_shared_strings(&mut archive)?;
|
||||
let workbook = load_workbook(&mut archive)?;
|
||||
let rels = load_relationships(&mut archive)?;
|
||||
let mut tables = HashMap::new();
|
||||
let worksheets = load_sheets(
|
||||
&mut archive,
|
||||
&rels,
|
||||
&workbook,
|
||||
&mut tables,
|
||||
&mut shared_strings,
|
||||
)?;
|
||||
let styles = load_styles(&mut archive)?;
|
||||
let metadata = match load_metadata(&mut archive) {
|
||||
Ok(metadata) => metadata,
|
||||
Err(_) => {
|
||||
// In case there is no metadata, add some
|
||||
Metadata {
|
||||
application: "Unknown application".to_string(),
|
||||
app_version: "".to_string(),
|
||||
creator: "".to_string(),
|
||||
last_modified_by: "".to_string(),
|
||||
created: "".to_string(),
|
||||
last_modified: "".to_string(),
|
||||
}
|
||||
}
|
||||
};
|
||||
Ok(Workbook {
|
||||
shared_strings,
|
||||
defined_names: workbook.defined_names,
|
||||
worksheets,
|
||||
styles,
|
||||
name,
|
||||
settings: WorkbookSettings {
|
||||
tz: tz.to_string(),
|
||||
locale: locale.to_string(),
|
||||
},
|
||||
metadata,
|
||||
tables,
|
||||
})
|
||||
}
|
||||
|
||||
// Public methods
|
||||
|
||||
/// Imports a file from disk into an internal representation
|
||||
pub fn load_from_excel(file_name: &str, locale: &str, tz: &str) -> Result<Workbook, XlsxError> {
|
||||
let file_path = std::path::Path::new(file_name);
|
||||
let file = fs::File::open(file_path)?;
|
||||
let reader = BufReader::new(file);
|
||||
let name = file_path
|
||||
.file_stem()
|
||||
.ok_or_else(|| XlsxError::IO("Could not extract workbook name".to_string()))?
|
||||
.to_string_lossy()
|
||||
.to_string();
|
||||
load_xlsx_from_reader(name, reader, locale, tz)
|
||||
}
|
||||
|
||||
pub fn load_model_from_xlsx(file_name: &str, locale: &str, tz: &str) -> Result<Model, XlsxError> {
|
||||
let workbook = load_from_excel(file_name, locale, tz)?;
|
||||
Model::from_workbook(workbook).map_err(XlsxError::Workbook)
|
||||
}
|
||||
Reference in New Issue
Block a user