parent
9dd247b20c
commit
6d446b4767
@ -1 +0,0 @@
|
||||
,sanchezn,pc-sanchezn,17.02.2026 15:16,/home/sanchezn/.local/share/onlyoffice;
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,14 +1,9 @@
|
||||
use xlsxtocsv::{arguments::Arguments, xlsx::XlsxReader};
|
||||
use xlsxtocsv::{error::Error, xlsx::XlsxReader, xlsx_to_csv::Output};
|
||||
|
||||
fn main() {
|
||||
let args = Arguments::parse();
|
||||
/* if let Err(error) = xlsxtocsv(&args) {
|
||||
eprintln!("{}", error);
|
||||
}*/
|
||||
fn main() -> Result<(), Error> {
|
||||
XlsxReader::new("noms.xlsx")
|
||||
.with_active_worksheet()
|
||||
.to_csv(Output::Stdout)?;
|
||||
|
||||
let xlsxreader = XlsxReader::new(args).unwrap();
|
||||
let reader = xlsxreader.to_csv();
|
||||
for line in reader {
|
||||
println!("{line}");
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -1,35 +1,120 @@
|
||||
use crate::xlsx::XlsxReader;
|
||||
use std::{
|
||||
fs::File,
|
||||
io::{BufWriter, Write, stderr, stdout},
|
||||
};
|
||||
|
||||
pub struct XlsxToCsvLines<'a> {
|
||||
xlsx_reader: &'a XlsxReader,
|
||||
use crate::{error::Error, xlsx::XlsxReader};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct XlsxToCsvLines {
|
||||
xlsx_reader: XlsxReader,
|
||||
current_row: u32,
|
||||
num_rows: u32,
|
||||
separator: String,
|
||||
end_of_line: String,
|
||||
}
|
||||
|
||||
impl<'a> Iterator for XlsxToCsvLines<'a> {
|
||||
type Item = String;
|
||||
impl Iterator for XlsxToCsvLines {
|
||||
type Item = Result<String, Error>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.current_row > self.num_rows {
|
||||
return None;
|
||||
}
|
||||
|
||||
let row = self.xlsx_reader.get_row(self.current_row);
|
||||
let mut row = self.xlsx_reader.get_row(self.current_row);
|
||||
match &self.xlsx_reader.args.replace_separator_by {
|
||||
Some(replacement) => {
|
||||
row = row
|
||||
.iter()
|
||||
.map(|v| v.replace(self.xlsx_reader.args.separator, replacement.as_str()))
|
||||
.collect()
|
||||
}
|
||||
None => {
|
||||
if row
|
||||
.iter()
|
||||
.any(|v| v.contains(self.xlsx_reader.args.separator))
|
||||
{
|
||||
return Some(Err(
|
||||
"Some cells contains the separator char. Use a replacement for separator char inside cells.".into(),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.current_row += 1;
|
||||
|
||||
let row = row.join(";");
|
||||
let mut row = row.join(self.separator.as_str());
|
||||
match &self.xlsx_reader.args.replace_end_of_line_by {
|
||||
Some(replacement) => row = row.replace(self.end_of_line.as_str(), replacement),
|
||||
None => {
|
||||
if row.contains(self.end_of_line.as_str()) {
|
||||
return Some(Err("Some cells contains the end of line char. Use a replacement for end of line char inside cells.".into()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let row = row + self.end_of_line.as_str();
|
||||
|
||||
Some(row)
|
||||
Some(Ok(row))
|
||||
}
|
||||
}
|
||||
|
||||
pub enum Output {
|
||||
File(String),
|
||||
Stdout,
|
||||
Stderr,
|
||||
}
|
||||
|
||||
pub trait IntoOutput {
|
||||
fn into_output(self) -> Output;
|
||||
}
|
||||
|
||||
impl IntoOutput for Output {
|
||||
fn into_output(self) -> Output {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoOutput for String {
|
||||
fn into_output(self) -> Output {
|
||||
Output::File(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoOutput for &str {
|
||||
fn into_output(self) -> Output {
|
||||
Output::File(String::from(self))
|
||||
}
|
||||
}
|
||||
|
||||
impl XlsxReader {
|
||||
pub fn to_csv(&self) -> XlsxToCsvLines<'_> {
|
||||
pub fn to_csv_lines(mut self) -> Result<XlsxToCsvLines, Error> {
|
||||
self.finish()?;
|
||||
let num_rows = self.get_worksheet_dimensions().1;
|
||||
XlsxToCsvLines {
|
||||
let end_of_line = self.args.end_of_line.clone();
|
||||
let separator = String::from(self.args.separator);
|
||||
Ok(XlsxToCsvLines {
|
||||
xlsx_reader: self,
|
||||
current_row: 0,
|
||||
num_rows,
|
||||
separator,
|
||||
end_of_line,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn to_csv(self, output: impl IntoOutput) -> Result<(), Error> {
|
||||
let output = output.into_output();
|
||||
let mut writer: Box<dyn Write> = match output {
|
||||
Output::File(filename) => Box::new(BufWriter::new(File::open(filename)?)),
|
||||
Output::Stdout => Box::new(BufWriter::new(stdout().lock())),
|
||||
Output::Stderr => Box::new(BufWriter::new(stderr().lock())),
|
||||
};
|
||||
|
||||
for line in self.to_csv_lines()? {
|
||||
writer.write_all(line?.as_bytes())?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in new issue