use calamine::{open_workbook, Data, Reader, Xlsx}; #[derive(Debug, Clone)] struct Record { client_code: String, species: String, variety: String, delivery_week: String, } const COLUMN_MAP: [(&str, char); 5] = [ ("client_code", 'A'), ("species", 'B'), ("variety", 'C'), ("sowing_week", 'I'), ("delivery_week", 'J'), ]; fn letter_to_index(col: char) -> usize { (col as u8 - b'A') as usize } fn column_name_to_index(column: &str) -> usize { COLUMN_MAP .map(|(name, col)| (name, letter_to_index(col))) .iter() .find(|(name, _)| *name == column) .unwrap() .1 } fn get_cell_value(row: &[Data], column: &str) -> String { let col_index = column_name_to_index(column); match row.get(col_index) { Some(Data::String(s)) => s.to_string(), Some(Data::Float(f)) => f.to_string(), _ => "".to_string(), } } fn parse_xlsx(delivery_week_filter: &str) -> Result, Box> { let mut workbook: Xlsx<_> = open_workbook("data.xlsx")?; let range = workbook.worksheet_range("Feuille1")?; let records: Vec = range .rows() .filter_map(|row| { let delivery_week = get_cell_value(row, "delivery_week"); if delivery_week.to_lowercase() != delivery_week_filter.to_lowercase() { return None; } Some(Record { client_code: get_cell_value(row, "client_code"), species: get_cell_value(row, "species"), variety: get_cell_value(row, "variety"), delivery_week, }) }) .collect(); Ok(records) } fn main() -> Result<(), Box> { let records = parse_xlsx("s06")?; for record in records { println!("{:?}", record); } Ok(()) }