use std::fs;
use std::io;
use std::path::Path;
use std::string::FromUtf8Error;
use crate::structs::CsvEncodeValues;
use crate::structs::CsvWriterOption;
use crate::structs::Spreadsheet;
use crate::structs::XlsxError;
use std::fmt::Write;
pub fn write_writer<W: io::Seek + io::Write>(
spreadsheet: &Spreadsheet,
writer: &mut W,
option: &CsvWriterOption,
) -> Result<(), XlsxError> {
let worksheet = spreadsheet.get_active_sheet();
let (max_column, max_row) = worksheet.get_highest_column_and_row();
let mut data = String::new();
for row in 0u32..max_row {
let mut row_vec: Vec<String> = Vec::new();
for column in 0u32..max_column {
let mut value = match worksheet.get_cell((column + 1, row + 1)) {
Some(cell) => cell.get_cell_value().get_value().into(),
None => String::new(),
};
if *option.get_do_trim() {
value = value.trim().to_string();
}
if option.get_wrap_with_char() != "" {
value = format! {"{}{}{}", option.get_wrap_with_char(), value, option.get_wrap_with_char()};
}
row_vec.push(value);
}
write!(data, "{}", row_vec.join(",")).unwrap();
write!(data, "\r\n").unwrap();
}
let data_bytes = match *option.get_csv_encode_value() {
CsvEncodeValues::ShiftJis => encoding_rs::SHIFT_JIS.encode(&data).0.into_owned(),
CsvEncodeValues::Koi8u => encoding_rs::KOI8_U.encode(&data).0.into_owned(),
CsvEncodeValues::Koi8r => encoding_rs::KOI8_R.encode(&data).0.into_owned(),
CsvEncodeValues::Iso88598i => encoding_rs::ISO_8859_8_I.encode(&data).0.into_owned(),
CsvEncodeValues::Gbk => encoding_rs::GBK.encode(&data).0.into_owned(),
CsvEncodeValues::EucKr => encoding_rs::EUC_KR.encode(&data).0.into_owned(),
CsvEncodeValues::Big5 => encoding_rs::BIG5.encode(&data).0.into_owned(),
CsvEncodeValues::Utf16Le => encoding_rs::UTF_16LE.encode(&data).0.into_owned(),
CsvEncodeValues::Utf16Be => encoding_rs::UTF_16BE.encode(&data).0.into_owned(),
_ => data.into_bytes(),
};
writer.write_all(&data_bytes).unwrap();
Ok(())
}
pub fn write<P: AsRef<Path>>(
spreadsheet: &Spreadsheet,
path: P,
option: Option<&CsvWriterOption>,
) -> Result<(), XlsxError> {
let extension = path.as_ref().extension().unwrap().to_str().unwrap();
let path_tmp = path
.as_ref()
.with_extension(format!("{}{}", extension, "tmp"));
let def_option = CsvWriterOption::default();
let option = match option {
Some(v) => v,
None => &def_option,
};
if let Err(v) = write_writer(
spreadsheet,
&mut io::BufWriter::new(fs::File::create(path_tmp.as_ref() as &Path)?),
option,
) {
fs::remove_file(path_tmp)?;
return Err(v);
}
fs::rename(path_tmp, path)?;
Ok(())
}