feat: adiciona pré-visualização de arquivos CSV e XLSX na interface

This commit is contained in:
FelipeCN
2026-03-03 09:25:12 -03:00
parent 0f728b9684
commit 41c75e5ed1
6 changed files with 185 additions and 1 deletions
+36
View File
@@ -88,3 +88,39 @@ pub fn ler_csv(
avisos,
})
}
/// Retorna as primeiras `n` linhas brutas do CSV (sem pular cabeçalho).
/// Usado exclusivamente para pré-visualização na UI.
pub fn preview_csv(
caminho: &Path,
delimitador: u8,
encoding: &str,
n: usize,
) -> Result<Vec<Vec<String>>, ErroArquivo> {
let bytes = std::fs::read(caminho)
.map_err(|e| ErroArquivo::ErroLeitura(e.to_string()))?;
let conteudo = match encoding.to_lowercase().as_str() {
"windows-1252" | "latin-1" | "iso-8859-1" => {
let (decoded, _, _) = WINDOWS_1252.decode(&bytes);
decoded.into_owned()
}
_ => String::from_utf8(bytes)
.map_err(|e| ErroArquivo::ErroLeitura(format!("Encoding inválido: {}", e)))?,
};
let mut reader = csv::ReaderBuilder::new()
.delimiter(delimitador)
.has_headers(false)
.flexible(true)
.from_reader(conteudo.as_bytes());
let linhas = reader
.records()
.take(n)
.filter_map(|r| r.ok())
.map(|r| r.iter().map(|s| s.to_string()).collect())
.collect();
Ok(linhas)
}
+47
View File
@@ -97,6 +97,53 @@ pub fn ler_xlsx(
Ok(ResultadoXlsx { linhas, avisos })
}
/// Retorna as primeiras 5 linhas de uma aba XLSX, a partir da linha 1.
/// Usado exclusivamente para pré-visualização na UI.
pub fn preview_xlsx(
caminho: &Path,
nome_aba: &str,
) -> Result<Vec<Vec<String>>, ErroArquivo> {
verificar_tamanho(caminho)?;
let mut workbook = open_workbook_auto(caminho)
.map_err(|e| ErroArquivo::Corrompido(e.to_string()))?;
let range: calamine::Range<calamine::Data> = workbook
.worksheet_range(nome_aba)
.map_err(|e| ErroArquivo::Corrompido(e.to_string()))?;
let linhas = range
.rows()
.take(5)
.map(|row| {
row.iter()
.map(|cell| {
use calamine::Data;
match cell {
Data::Empty => String::new(),
Data::String(s) => s.clone(),
Data::Float(f) => {
if f.fract() == 0.0 {
format!("{}", *f as i64)
} else {
format!("{}", f)
}
}
Data::Int(i) => i.to_string(),
Data::Bool(b) => b.to_string(),
Data::DateTime(dt) => dt.to_string(),
Data::DateTimeIso(s) => s.clone(),
Data::DurationIso(s) => s.clone(),
Data::Error(_) => String::new(),
}
})
.collect()
})
.collect();
Ok(linhas)
}
/// Converte uma notação LetraLinha (ex: "B3") para (coluna_base0, linha_base1).
///
/// Retorna `None` se a notação for inválida.