From f9cc0ecc6021db946f7d765adf58439175dbaa1e Mon Sep 17 00:00:00 2001 From: Nicolas Sanchez Date: Tue, 7 Oct 2025 21:51:28 +0200 Subject: [PATCH] readme.md --- .~lock.test_masque.xlsx# | 1 + src/main.rs | 4 +-- src/xlsxtocsv.rs | 75 +++++++++++++-------------------------- test_masque.xlsx | Bin 5844 -> 6252 bytes 4 files changed, 27 insertions(+), 53 deletions(-) create mode 100644 .~lock.test_masque.xlsx# diff --git a/.~lock.test_masque.xlsx# b/.~lock.test_masque.xlsx# new file mode 100644 index 0000000..540f683 --- /dev/null +++ b/.~lock.test_masque.xlsx# @@ -0,0 +1 @@ +,sanchezn,pc-sanchezn,07.10.2025 21:40,file:///home/sanchezn/.config/libreoffice/4; \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index fbf2d27..c3f3559 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,13 +4,13 @@ pub mod xlsxtocsv; use clap::Parser; use arguments::Arguments; -use xlsxtocsv::xlsxtocsv2; +use xlsxtocsv::xlsxtocsv; fn main() { let args = Arguments::parse(); - if let Err(error) = xlsxtocsv2(&args) { + if let Err(error) = xlsxtocsv(&args) { eprintln!("{}", error); } } \ No newline at end of file diff --git a/src/xlsxtocsv.rs b/src/xlsxtocsv.rs index 1b40be2..73ee4d9 100644 --- a/src/xlsxtocsv.rs +++ b/src/xlsxtocsv.rs @@ -4,7 +4,7 @@ use umya_spreadsheet::{Range, Worksheet, reader}; use crate::arguments::{Arguments, TrimSpaces}; use crate::error::Error; -pub fn xlsxtocsv2(args: &Arguments) -> Result<(), 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()); @@ -35,66 +35,37 @@ pub fn xlsxtocsv2(args: &Arguments) -> Result<(), Error> { // get all the merged cells let merged_cells = MergedCells::new(sheet, horiz, vert); - // get size of the worksheet - let mut col_max = 0; - let mut row_max = 0; + // get non-empty value size of the worksheet + let mut num_cols = 0; + let mut num_rows = 0; + + for cell in sheet.get_cell_collection() { + let value = cell.get_formatted_value(); + + if value == "" { + continue; + } - for cell in sheet.get_cell_collection_sorted() { let coord = cell.get_coordinate(); let col_num = coord.get_col_num().clone(); let row_num = coord.get_row_num().clone(); - if col_num > col_max { - col_max = col_num; + if col_num > num_cols { + num_cols = col_num; } - if row_num > row_max { - col_max = col_num; + if row_num > num_rows { + num_rows = row_num; } - println!("({}, {})", col_num, row_num); } - println!("highest : ({}, {})", col_max, row_max); - - Ok(()) -} - -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()); - - // get the sheet from name or number if specified, else the first of the spreadsheet - let sheet = match book.get_sheet_by_name(&args.worksheet) { - Some(sheet) => sheet, - None => { - let sheetnum: u32 = match args.worksheet.parse() { - Ok(sheetnum) => sheetnum, - Err(_) => return Err(Error::new("cannot open sheet")), - }; - let sheet = match book.get_sheet(&(sheetnum as usize)) { - Some(sheet) => sheet, - None => return Err(Error::new("cannot open sheet")), - }; - sheet - } - }; - // set the merged cells policy - let (horiz, vert) = match args.fill_merged_cells { - crate::arguments::FillMergedCells::None => (false, false), - crate::arguments::FillMergedCells::Horizontal => (true, false), - crate::arguments::FillMergedCells::Vertical => (false, true), - crate::arguments::FillMergedCells::Both => (true, true), - }; - - // get all the merged cells - let merged_cells = MergedCells::new(sheet, horiz, vert); - - // get size of the worksheet - let (num_cols, num_rows) = sheet.get_highest_column_and_row(); + let mut empty_row = String::from(""); + for _ in 1..num_cols { + empty_row += ";" + } // TODO get every hidden columns // for each row... for i in 1..=num_rows { - // Avoid hidden rows if asked for if !args.include_hidden_lines { match sheet.get_row_dimension(&i) { @@ -103,7 +74,10 @@ pub fn xlsxtocsv(args: &Arguments) -> Result<(), Error> { continue; } } - None => continue, + None => { + println!("{}", empty_row); + continue; + } } } @@ -118,7 +92,7 @@ pub fn xlsxtocsv(args: &Arguments) -> Result<(), Error> { let cell = match sheet.get_cell((j, i)) { Some(cell) => cell, - None => continue, + None => break, }; // get value from cell depending on merged cells and fill merged policy @@ -209,4 +183,3 @@ impl MergedCells { None } } - diff --git a/test_masque.xlsx b/test_masque.xlsx index 653d8802272a2cea99eb60e7b09d53ee9a60dd93..ca413f245a212a83539101563511466b0eaf89db 100644 GIT binary patch delta 4546 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 aasHddaS*h5_*t0%On}=*a&aDdeC}UGUP1%_