committed by
Nicolás Hatcher Andrés
parent
b9b3cb1628
commit
faa0ff9b69
@@ -336,6 +336,7 @@ fn get_cell_from_excel(
|
|||||||
sheet_name: &str,
|
sheet_name: &str,
|
||||||
cell_ref: &str,
|
cell_ref: &str,
|
||||||
shared_strings: &mut Vec<String>,
|
shared_strings: &mut Vec<String>,
|
||||||
|
rich_text_inline: Option<String>,
|
||||||
) -> Cell {
|
) -> Cell {
|
||||||
// Possible cell types:
|
// Possible cell types:
|
||||||
// 18.18.11 ST_CellType (Cell Type)
|
// 18.18.11 ST_CellType (Cell Type)
|
||||||
@@ -397,12 +398,15 @@ fn get_cell_from_excel(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
"inlineStr" => {
|
"inlineStr" => {
|
||||||
// Not implemented
|
let s = rich_text_inline.unwrap_or_default();
|
||||||
println!("Invalid type (inlineStr) in {sheet_name}!{cell_ref}");
|
let si = if let Some(i) = shared_strings.iter().position(|r| r == &s) {
|
||||||
Cell::ErrorCell {
|
i
|
||||||
ei: Error::NIMPL,
|
} else {
|
||||||
s: cell_style,
|
shared_strings.push(s.to_string());
|
||||||
}
|
shared_strings.len() - 1
|
||||||
|
} as i32;
|
||||||
|
|
||||||
|
Cell::SharedString { si, s: cell_style }
|
||||||
}
|
}
|
||||||
"empty" => Cell::EmptyCell { s: cell_style },
|
"empty" => Cell::EmptyCell { s: cell_style },
|
||||||
_ => {
|
_ => {
|
||||||
@@ -480,16 +484,11 @@ fn get_cell_from_excel(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
"inlineStr" => {
|
"inlineStr" => {
|
||||||
// Not implemented
|
// NB: This is untested, I don't know of any engine that uses inline strings in formulas
|
||||||
let o = format!("{sheet_name}!{cell_ref}");
|
Cell::CellFormulaString {
|
||||||
let m = Error::NIMPL.to_string();
|
|
||||||
println!("Invalid type (inlineStr) in {sheet_name}!{cell_ref}");
|
|
||||||
Cell::CellFormulaError {
|
|
||||||
f: formula_index,
|
f: formula_index,
|
||||||
ei: Error::NIMPL,
|
v: rich_text_inline.unwrap_or("".to_string()),
|
||||||
s: cell_style,
|
s: cell_style,
|
||||||
o,
|
|
||||||
m,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@@ -796,7 +795,7 @@ pub(super) fn load_sheet<R: Read + std::io::Seek>(
|
|||||||
// 18.3.1.4 c (Cell)
|
// 18.3.1.4 c (Cell)
|
||||||
// Child Elements:
|
// Child Elements:
|
||||||
// * v: Cell value
|
// * v: Cell value
|
||||||
// * is: Rich Text Inline (not used in IronCalc)
|
// * is: Rich Text Inline
|
||||||
// * f: Formula
|
// * f: Formula
|
||||||
// Attributes:
|
// Attributes:
|
||||||
// r: reference. A1 style
|
// r: reference. A1 style
|
||||||
@@ -820,6 +819,26 @@ pub(super) fn load_sheet<R: Read + std::io::Seek>(
|
|||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// <c r="A1" t="inlineStr">
|
||||||
|
// <is>
|
||||||
|
// <t>Hello, World!</t>
|
||||||
|
// </is>
|
||||||
|
// </c>
|
||||||
|
let cell_rich_text_nodes: Vec<Node> =
|
||||||
|
cell.children().filter(|n| n.has_tag_name("is")).collect();
|
||||||
|
let cell_rich_text = if cell_rich_text_nodes.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
let texts: Vec<String> = cell_rich_text_nodes[0]
|
||||||
|
.descendants()
|
||||||
|
.filter(|n| n.has_tag_name("t"))
|
||||||
|
.filter_map(|n| n.text())
|
||||||
|
.map(|s| s.to_string())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Some(texts.join(""))
|
||||||
|
};
|
||||||
|
|
||||||
let cell_metadata = cell.attribute("cm");
|
let cell_metadata = cell.attribute("cm");
|
||||||
|
|
||||||
// type, the default type being "n" for number
|
// type, the default type being "n" for number
|
||||||
@@ -976,6 +995,7 @@ pub(super) fn load_sheet<R: Read + std::io::Seek>(
|
|||||||
sheet_name,
|
sheet_name,
|
||||||
cell_ref,
|
cell_ref,
|
||||||
shared_strings,
|
shared_strings,
|
||||||
|
cell_rich_text,
|
||||||
);
|
);
|
||||||
data_row.insert(column, cell);
|
data_row.insert(column, cell);
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
xlsx/tests/openpyxl_example.xlsx
Normal file
BIN
xlsx/tests/openpyxl_example.xlsx
Normal file
Binary file not shown.
@@ -531,3 +531,33 @@ fn test_user_model() {
|
|||||||
// we can still use the model afterwards
|
// we can still use the model afterwards
|
||||||
model.set_rows_height(0, 1, 1, 100.0).unwrap();
|
model.set_rows_height(0, 1, 1, 100.0).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is produced with:
|
||||||
|
// from openpyxl import Workbook
|
||||||
|
|
||||||
|
// # Create new workbook
|
||||||
|
// wb = Workbook()
|
||||||
|
// ws = wb.active
|
||||||
|
|
||||||
|
// # Write text and formula
|
||||||
|
// ws['A1'] = 'Hello, World!'
|
||||||
|
// ws['A2'] = '=1+1'
|
||||||
|
|
||||||
|
// ws['B1'] = '=CONCAT("It is", " what it is")'
|
||||||
|
|
||||||
|
// # Save
|
||||||
|
// wb.save('openpyxl_example.xlsx')
|
||||||
|
#[test]
|
||||||
|
fn test_pyopenxl_example() {
|
||||||
|
let mut model = load_from_xlsx("tests/openpyxl_example.xlsx", "en", "UTC").unwrap();
|
||||||
|
model.evaluate();
|
||||||
|
|
||||||
|
let a1 = model.get_formatted_cell_value(0, 1, 1).unwrap();
|
||||||
|
assert_eq!(a1, "Hello, World!");
|
||||||
|
|
||||||
|
let a2 = model.get_formatted_cell_value(0, 2, 1).unwrap();
|
||||||
|
assert_eq!(a2, "2");
|
||||||
|
|
||||||
|
let b1 = model.get_formatted_cell_value(0, 1, 2).unwrap();
|
||||||
|
assert_eq!(b1, "It is what it is");
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user