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;
|
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());
|
|
||||||
|
|
||||||
let sheet = match book.get_sheet(&0) {
|
use clap::Parser;
|
||||||
Some(sheet) => sheet,
|
use arguments::Arguments;
|
||||||
None => return Err(Error::new("cannot open sheet")),
|
use xlsxtocsv::xlsxtocsv;
|
||||||
};
|
|
||||||
|
|
||||||
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();
|
fn main() {
|
||||||
if let Some(ref replacement) = args.replacement {
|
let args = Arguments::parse();
|
||||||
value = value.replace(args.separator, replacement);
|
if let Err(error) = xlsxtocsv(&args) {
|
||||||
} else {
|
eprintln!("{}", error);
|
||||||
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!("");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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