#[path = "fixtures/mod.rs"]
mod fixtures;
use fixtures::normal;
use std::io::Cursor;
use std::sync::Arc;
use xlsxparser::{parse_workbook_reader, to_json_string, CellRef, CellValue, DateTimeValue};
#[test]
fn wrap_text_resolves_per_cell_and_serializes_nested_under_style() {
let workbook = parse_workbook_reader(Cursor::new(normal::wrap_text_styles())).unwrap();
let sheet = &workbook.sheets()[0];
assert!(
sheet
.get(CellRef { row: 1, col: 1 })
.unwrap()
.style
.as_ref()
.unwrap()
.wrap_text
);
assert!(
!sheet
.get(CellRef { row: 1, col: 2 })
.unwrap()
.style
.as_ref()
.unwrap()
.wrap_text
);
let json = to_json_string(&workbook).unwrap();
let parsed: serde_json::Value = serde_json::from_str(&json).unwrap();
let cells = parsed["sheets"][0]["cells"].as_array().unwrap();
let a1 = cells.iter().find(|c| c["col"] == 1).unwrap();
let b1 = cells.iter().find(|c| c["col"] == 2).unwrap();
assert_eq!(a1["style"]["wrapText"], serde_json::json!(true));
assert_eq!(b1["style"]["wrapText"], serde_json::json!(false));
}
#[test]
fn number_format_resolves_per_cell_and_serializes_nested_under_style() {
let workbook = parse_workbook_reader(Cursor::new(normal::number_format_styles())).unwrap();
let sheet = &workbook.sheets()[0];
assert_eq!(
sheet
.get(CellRef { row: 1, col: 1 })
.unwrap()
.style
.as_ref()
.unwrap()
.number_format
.as_deref(),
Some("0%")
);
assert_eq!(
sheet
.get(CellRef { row: 1, col: 2 })
.unwrap()
.style
.as_ref()
.unwrap()
.number_format
.as_deref(),
Some("#,##0.00 \"円\"")
);
let json = to_json_string(&workbook).unwrap();
let parsed: serde_json::Value = serde_json::from_str(&json).unwrap();
let cells = parsed["sheets"][0]["cells"].as_array().unwrap();
let a1 = cells.iter().find(|c| c["col"] == 1).unwrap();
let b1 = cells.iter().find(|c| c["col"] == 2).unwrap();
assert_eq!(a1["style"]["numberFormat"], "0%");
assert_eq!(b1["style"]["numberFormat"], "#,##0.00 \"円\"");
}
#[test]
fn font_size_and_bold_resolve_per_cell_and_serialize_nested_under_style() {
let workbook = parse_workbook_reader(Cursor::new(normal::font_styles())).unwrap();
let sheet = &workbook.sheets()[0];
let a1_font = &sheet
.get(CellRef { row: 1, col: 1 })
.unwrap()
.style
.as_ref()
.unwrap()
.font;
assert_eq!(a1_font.size_pt, 11.0);
assert!(!a1_font.bold);
let b1_font = &sheet
.get(CellRef { row: 1, col: 2 })
.unwrap()
.style
.as_ref()
.unwrap()
.font;
assert_eq!(b1_font.size_pt, 14.0);
assert!(b1_font.bold);
let json = to_json_string(&workbook).unwrap();
let parsed: serde_json::Value = serde_json::from_str(&json).unwrap();
let cells = parsed["sheets"][0]["cells"].as_array().unwrap();
let a1 = cells.iter().find(|c| c["col"] == 1).unwrap();
let b1 = cells.iter().find(|c| c["col"] == 2).unwrap();
assert_eq!(
a1["style"],
serde_json::json!({
"font": { "sizePt": 11.0, "bold": false },
"wrapText": false,
"alignment": "general"
})
);
assert_eq!(
b1["style"],
serde_json::json!({
"font": { "sizePt": 14.0, "bold": true },
"wrapText": false,
"alignment": "general"
})
);
}
#[test]
fn date1904_workbook_pr_selects_the_1904_epoch_end_to_end() {
let workbook = parse_workbook_reader(Cursor::new(normal::date1904_styles())).unwrap();
let sheet = &workbook.sheets()[0];
assert_eq!(
sheet.get(CellRef { row: 1, col: 1 }).unwrap().value,
Some(CellValue::DateTime(DateTimeValue {
year: 1904,
month: 1,
day: 2,
hour: 0,
minute: 0,
second: 0,
}))
);
let json = to_json_string(&workbook).unwrap();
let parsed: serde_json::Value = serde_json::from_str(&json).unwrap();
assert_eq!(
parsed["sheets"][0]["cells"][0]["value"],
serde_json::json!({"type": "dateTime", "value": "1904-01-02T00:00:00"})
);
}
#[test]
fn alignment_resolves_per_cell_and_serializes_nested_under_style() {
let workbook = parse_workbook_reader(Cursor::new(normal::alignment_styles())).unwrap();
let sheet = &workbook.sheets()[0];
assert_eq!(
sheet
.get(CellRef { row: 1, col: 1 })
.unwrap()
.style
.as_ref()
.unwrap()
.horizontal_alignment,
xlsxparser::Alignment::Center
);
assert_eq!(
sheet
.get(CellRef { row: 1, col: 2 })
.unwrap()
.style
.as_ref()
.unwrap()
.horizontal_alignment,
xlsxparser::Alignment::General
);
let json = to_json_string(&workbook).unwrap();
let parsed: serde_json::Value = serde_json::from_str(&json).unwrap();
let cells = parsed["sheets"][0]["cells"].as_array().unwrap();
let a1 = cells.iter().find(|c| c["col"] == 1).unwrap();
let b1 = cells.iter().find(|c| c["col"] == 2).unwrap();
assert_eq!(a1["style"]["alignment"], "center");
assert_eq!(b1["style"]["alignment"], "general");
}
#[test]
fn column_widths_resolve_per_column_and_serialize_as_a_sheet_level_array() {
let workbook = parse_workbook_reader(Cursor::new(normal::column_widths())).unwrap();
let sheet = &workbook.sheets()[0];
assert_eq!(sheet.column_width(1), Some(12.5)); assert_eq!(sheet.column_width(3), Some(12.5));
assert_eq!(sheet.column_width(4), Some(9.1)); assert_eq!(sheet.column_width(5), Some(30.0)); assert_eq!(sheet.column_width(6), Some(9.1));
let json = to_json_string(&workbook).unwrap();
let parsed: serde_json::Value = serde_json::from_str(&json).unwrap();
let sheet_json = &parsed["sheets"][0];
assert_eq!(sheet_json["defaultColumnWidth"], serde_json::json!(9.1));
assert_eq!(
sheet_json["columns"],
serde_json::json!([
{"min": 1, "max": 3, "width": 12.5},
{"min": 5, "max": 5, "width": 30.0}
])
);
for cell in sheet_json["cells"].as_array().unwrap() {
assert!(cell.get("columnWidth").is_none());
}
}
#[test]
fn basic_types_maps_each_cell_to_the_right_json_type() {
let workbook = parse_workbook_reader(Cursor::new(normal::basic_types())).unwrap();
let sheet = &workbook.sheets()[0];
assert_eq!(
sheet.get(CellRef { row: 1, col: 1 }).unwrap().value,
Some(CellValue::Text(Arc::from("日本語Text")))
);
assert_eq!(
sheet.get(CellRef { row: 1, col: 2 }).unwrap().value,
Some(CellValue::Number(42.0))
);
assert_eq!(
sheet.get(CellRef { row: 1, col: 3 }).unwrap().value,
Some(CellValue::Number(19.99))
);
assert_eq!(
sheet.get(CellRef { row: 1, col: 4 }).unwrap().value,
Some(CellValue::DateTime(DateTimeValue {
year: 2023,
month: 3,
day: 15,
hour: 0,
minute: 0,
second: 0,
}))
);
assert_eq!(
sheet.get(CellRef { row: 1, col: 5 }).unwrap().value,
Some(CellValue::Boolean(true))
);
assert_eq!(
sheet.get(CellRef { row: 1, col: 6 }).unwrap().value,
Some(CellValue::Boolean(false))
);
assert_eq!(
sheet.get(CellRef { row: 1, col: 7 }).unwrap().value,
Some(CellValue::Error("#N/A".to_string()))
);
assert_eq!(sheet.iter_cells().count(), 7);
let json = xlsxparser::to_json_string(&workbook).unwrap();
let parsed: serde_json::Value = serde_json::from_str(&json).unwrap();
let cells = parsed["sheets"][0]["cells"].as_array().unwrap();
let mut types: Vec<&str> = cells
.iter()
.map(|c| c["value"]["type"].as_str().unwrap())
.collect();
types.sort_unstable();
let mut expected = vec![
"text", "number", "number", "dateTime", "boolean", "boolean", "error",
];
expected.sort_unstable();
assert_eq!(types, expected);
}
#[test]
fn shared_strings_resolves_repeated_and_distinct_indices() {
let workbook = parse_workbook_reader(Cursor::new(normal::shared_strings())).unwrap();
let sheet = &workbook.sheets()[0];
assert_eq!(
sheet.get(CellRef { row: 1, col: 1 }).unwrap().value,
Some(CellValue::Text(Arc::from("Apple")))
);
assert_eq!(
sheet.get(CellRef { row: 1, col: 2 }).unwrap().value,
Some(CellValue::Text(Arc::from("Banana")))
);
assert_eq!(
sheet.get(CellRef { row: 1, col: 3 }).unwrap().value,
Some(CellValue::Text(Arc::from("Apple")))
);
}
#[test]
fn inline_strings_are_extracted_without_a_shared_string_table() {
let workbook = parse_workbook_reader(Cursor::new(normal::inline_strings())).unwrap();
let sheet = &workbook.sheets()[0];
assert_eq!(
sheet.get(CellRef { row: 1, col: 1 }).unwrap().value,
Some(CellValue::Text(Arc::from("Inline One")))
);
assert_eq!(
sheet.get(CellRef { row: 1, col: 2 }).unwrap().value,
Some(CellValue::Text(Arc::from("Inline Two")))
);
}