From 9f544e63d157c959faaea5b67b1912fbee6bfa48 Mon Sep 17 00:00:00 2001 From: Nicolas Sanchez Date: Thu, 26 Mar 2026 10:55:40 +0100 Subject: [PATCH] ajout code --- noms.xlsx | Bin 6445 -> 6442 bytes src/arguments.rs | 14 ++++++++++++++ src/main.rs | 1 + src/xlsx.rs | 16 ++++++++++++++-- src/xlsx_builder.rs | 10 ++++++++++ 5 files changed, 39 insertions(+), 2 deletions(-) diff --git a/noms.xlsx b/noms.xlsx index ca4f22559fdfa95cdfa330d3306eb9861984f9f4..a0333bd5f81690438bb9befd10aaeb1f03249619 100644 GIT binary patch delta 3213 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 LLdfCFXO8~?%r(C5 delta 3161 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 diff --git a/src/arguments.rs b/src/arguments.rs index bfd657f..fb8c183 100644 --- a/src/arguments.rs +++ b/src/arguments.rs @@ -122,6 +122,12 @@ pub(crate) struct RawArguments { /// avoid nth first rows of xlsx file #[arg(short = 'k', long, default_value_t = 0)] pub skip_rows: u32, + /// avoid empty lines + #[arg(short, long, default_value_t = false)] + pub avoid_empty_rows: bool, + /// consider first line (after row skipped) as header line + #[arg(short, long, default_value_t = false)] + pub header: bool, /// change end of line character #[arg(short, long, default_value_t = String::from("\n"))] pub end_of_line: String, @@ -160,6 +166,10 @@ pub struct Arguments { pub(crate) number_rows: NumberRows, /// Avoid nth first rows of xlsx file pub(crate) skip_rows: u32, + /// avoid empty lines + pub avoid_empty_rows: bool, + /// first line (after row skipped) is header line + pub header: bool, ///# csv output specific options /// Separator for output pub(crate) separator: char, @@ -194,6 +204,8 @@ impl Default for Arguments { trim: Default::default(), number_rows: Default::default(), skip_rows: Default::default(), + avoid_empty_rows: false, + header: false, end_of_line: String::from("\n"), replace_end_of_line_by: Default::default(), } @@ -231,6 +243,8 @@ impl From for Arguments { trim: raw.trim, number_rows: raw.number_rows, skip_rows: raw.skip_rows, + avoid_empty_rows: raw.avoid_empty_rows, + header: raw.header, end_of_line: raw.end_of_line, replace_end_of_line_by: raw.replace_end_of_line_by, } diff --git a/src/main.rs b/src/main.rs index d978d34..2536763 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,7 @@ pub use xlsxtocsv::{error::Error, xlsx::XlsxReader}; fn main() -> Result<(), Error> { let lf = XlsxReader::new("noms.xlsx") .with_active_worksheet() + .with_fill_merged_cells(xlsxtocsv::arguments::FillMergedCells::Both) .to_lazyframe()?; let df = lf.collect()?; diff --git a/src/xlsx.rs b/src/xlsx.rs index 9baf3ea..f3346af 100644 --- a/src/xlsx.rs +++ b/src/xlsx.rs @@ -13,9 +13,11 @@ pub struct XlsxReader { pub(crate) book: Option, pub(crate) sheet_index: Option, pub(crate) worksheet_dimensions: RefCell>, + pub(crate) current_row: u32, } impl XlsxReader { + /// Create an XlsxReader from a path or clap arguments pub fn new(args: impl IntoArgs) -> Self { let args = args.into_args(); @@ -24,6 +26,7 @@ impl XlsxReader { book: None, sheet_index: None, worksheet_dimensions: RefCell::new(None), + current_row: 0u32, } } @@ -91,7 +94,6 @@ impl XlsxReader { let mut num_cols = 0; let mut num_rows = 0; let sheet = self.get_sheet().unwrap(); - for cell in sheet.get_cell_collection() { let value = get_value(cell); //.get_formatted_value(); @@ -127,13 +129,23 @@ impl XlsxReader { let value = cell.get_formatted_value(); let coord = cell.get_coordinate(); let col = *coord.get_col_num() - 1; - res[col as usize] = value; + if col < num_cols.try_into().unwrap() { + res[col as usize] = value; + } } res } } +impl Iterator for XlsxReader { + type Item = Result; + + fn next(&mut self) -> Option { + todo!() + } +} + pub fn list_worksheets(book: Spreadsheet) -> Result, Error> { let sheets = book.get_sheet_collection(); let mut res = vec![]; diff --git a/src/xlsx_builder.rs b/src/xlsx_builder.rs index c8f55ca..9713c50 100644 --- a/src/xlsx_builder.rs +++ b/src/xlsx_builder.rs @@ -104,6 +104,16 @@ impl XlsxReader { self } + pub fn with_avoid_empty_rows(mut self) -> Self { + self.args.avoid_empty_rows = true; + self + } + + pub fn with_header(mut self) -> Self { + self.args.header = true; + self + } + pub fn with_end_of_line(mut self, eol: String) -> Self { self.args.end_of_line = eol; self