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() {
|
fn main() -> Result<(), Error> {
|
||||||
let args = Arguments::parse();
|
XlsxReader::new("noms.xlsx")
|
||||||
/* if let Err(error) = xlsxtocsv(&args) {
|
.with_active_worksheet()
|
||||||
eprintln!("{}", error);
|
.to_csv(Output::Stdout)?;
|
||||||
}*/
|
|
||||||
|
|
||||||
let xlsxreader = XlsxReader::new(args).unwrap();
|
Ok(())
|
||||||
let reader = xlsxreader.to_csv();
|
|
||||||
for line in reader {
|
|
||||||
println!("{line}");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,35 +1,120 @@
|
|||||||
use crate::xlsx::XlsxReader;
|
use std::{
|
||||||
|
fs::File,
|
||||||
|
io::{BufWriter, Write, stderr, stdout},
|
||||||
|
};
|
||||||
|
|
||||||
pub struct XlsxToCsvLines<'a> {
|
use crate::{error::Error, xlsx::XlsxReader};
|
||||||
xlsx_reader: &'a XlsxReader,
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct XlsxToCsvLines {
|
||||||
|
xlsx_reader: XlsxReader,
|
||||||
current_row: u32,
|
current_row: u32,
|
||||||
num_rows: u32,
|
num_rows: u32,
|
||||||
|
separator: String,
|
||||||
|
end_of_line: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Iterator for XlsxToCsvLines<'a> {
|
impl Iterator for XlsxToCsvLines {
|
||||||
type Item = String;
|
type Item = Result<String, Error>;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
if self.current_row > self.num_rows {
|
if self.current_row > self.num_rows {
|
||||||
return None;
|
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;
|
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(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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Some(row)
|
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 {
|
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;
|
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,
|
xlsx_reader: self,
|
||||||
current_row: 0,
|
current_row: 0,
|
||||||
num_rows,
|
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