use std::path::Path; use umya_spreadsheet::{Range, Worksheet, reader}; use crate::arguments::Arguments; use crate::error::Error; pub fn xlsxtocsv(args: &Arguments) -> Result<(), Error> { let book = reader::xlsx::read(Path::new(&args.file)) .expect(format!("Can't open {}", args.file).as_str()); let sheet = match book.get_sheet(&0) { Some(sheet) => sheet, None => return Err(Error::new("cannot open sheet")), }; let merged_cells = MergedCells::new(sheet); let (num_cols, num_rows) = sheet.get_highest_column_and_row(); for i in 1..=num_rows { if !args.include_hidden_lines { match sheet.get_row_dimension(&i) { Some(dim) => { if *dim.get_hidden() { continue; } } None => continue, } } let row = sheet.get_collection_by_row(&i); let row_len = row.len(); let mut first = true; for cell in row { if first { first = false; } else { print!("{}", args.separator); } let cell_coordinate = cell.get_coordinate(); let mut value; if let Some((col, row)) = merged_cells.in_merged_cell(*cell_coordinate.get_col_num(), *cell_coordinate.get_row_num()) { value = match sheet.get_cell((col,row)) { Some(merged_cell) => merged_cell.get_formatted_value(), None => String::from(""), } } else { value = cell.get_formatted_value(); } if let Some(ref replacement) = args.replacement { value = value.replace(args.separator, replacement); } else { if value.contains(args.separator) { return Err(Error::new( format!( "Cell {} contains separator char, use -r to choose a replacement char", cell.get_coordinate().get_coordinate() ) .as_str(), )); } } print!("{}", value); } for _ in row_len..num_cols as usize { print!("{}", args.separator); } println!(""); } Ok(()) } struct MergedCells { merged_cells: Vec, } impl MergedCells { pub fn new(sheet: &Worksheet) -> Self { let merged = sheet.get_merge_cells(); let mut merged_cells: Vec = vec![]; for cell in merged { merged_cells.push(cell.clone()); } MergedCells { merged_cells } } pub fn in_merged_cell(&self, col: u32, row: u32) -> Option<(u32, u32)> { for range in &self.merged_cells { if col >= *range.get_coordinate_start_col().unwrap().get_num() && col <= *range.get_coordinate_end_col().unwrap().get_num() && row >= *range.get_coordinate_start_row().unwrap().get_num() && row <= *range.get_coordinate_end_row().unwrap().get_num() { return Some((range.get_coordinate_start_col().unwrap().get_num().clone(), (range.get_coordinate_start_row().unwrap().get_num().clone()))); } } None } }