parent
d4a75ffb69
commit
a05d0a52b4
@ -1 +1 @@
|
||||
,sanchezn,pc-sanchezn,04.10.2025 13:10,file:///home/sanchezn/.config/libreoffice/4;
|
||||
,sanchezn,pc-sanchezn,04.10.2025 18:38,file:///home/sanchezn/.config/libreoffice/4;
|
||||
@ -1,67 +1,16 @@
|
||||
use clap::Parser;
|
||||
use std::path::Path;
|
||||
use umya_spreadsheet::reader;
|
||||
|
||||
pub mod arguments;
|
||||
use arguments::Arguments;
|
||||
|
||||
pub mod error;
|
||||
use crate::error::Error;
|
||||
pub mod arguments;
|
||||
pub mod xlsxtocsv;
|
||||
|
||||
fn main() -> Result<(), Error> {
|
||||
let args = Arguments::parse();
|
||||
let book = reader::xlsx::read(Path::new(&args.file))
|
||||
.expect(format!("Can't open {}", args.file).as_str());
|
||||
use clap::Parser;
|
||||
use arguments::Arguments;
|
||||
use xlsxtocsv::xlsxtocsv;
|
||||
|
||||
let sheet = match book.get_sheet(&0) {
|
||||
Some(sheet) => sheet,
|
||||
None => return Err(Error::new("cannot open 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 mut 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",
|
||||
cell.get_coordinate().get_coordinate()
|
||||
)
|
||||
.as_str(),
|
||||
));
|
||||
}
|
||||
}
|
||||
print!("{}", value);
|
||||
}
|
||||
for _ in row_len..num_cols as usize {
|
||||
print!("{}", args.separator);
|
||||
}
|
||||
println!("");
|
||||
fn main() {
|
||||
let args = Arguments::parse();
|
||||
if let Err(error) = xlsxtocsv(&args) {
|
||||
eprintln!("{}", error);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -0,0 +1,104 @@
|
||||
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<Range>,
|
||||
}
|
||||
|
||||
impl MergedCells {
|
||||
|
||||
pub fn new(sheet: &Worksheet) -> Self {
|
||||
let merged = sheet.get_merge_cells();
|
||||
let mut merged_cells: Vec<Range> = 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
|
||||
}
|
||||
|
||||
}
|
||||
|
Binary file not shown.
Loading…
Reference in new issue