tonhowtf/omniget · error
não gravei o xlsx
Error message
não gravei o xlsx: {} What it means
Wraps the umya-spreadsheet `book.save(path)` failure when persisting the generated XLSX workbook. The original save error (io or zip-related) is embedded in the message. It fires only at the final write step — table extraction itself already succeeded.
Solutions
- Check the embedded cause in the message; if permission/locked, close the file in Excel/LibreOffice or pick another output path
- Verify the output directory exists and is writable (create_dir_all / check permissions)
- Save to a temp file then atomically rename, so partial writes don't corrupt the target
- Confirm disk space and that the path is a valid file path, not a directory
Example fix
// before
write_xlsx(&book, &Path::new("C:\\relatorio.xlsx"))?;
// after
let target = Path::new("C:\\relatorio.xlsx");
if target.exists() && !fs::remove_file(target).map(|_| true).or_else(|e| e.kind()==NotFound).unwrap_or(false) {
anyhow::bail!("feche o arquivo no Excel antes de sobrescrever");
}
let tmp = target.with_extension("xlsx.tmp");
write_xlsx(&book, &tmp)?;
fs::rename(&tmp, target)?; Defensive patterns
Strategy: try-catch
Validate before calling
// Rust: ensure the destination is writable before extraction
fn ensure_writable_target(path: &std::path::Path) -> anyhow::Result<()> {
if let Some(dir) = path.parent() { std::fs::create_dir_all(dir)?; }
if path.exists() {
std::fs::OpenOptions::new().append(true).open(path)
.map_err(|e| anyhow!("alvo bloqueado/sem permissão: {}", e))?;
}
Ok(())
} Type guard
fn target_writable(path: &std::path::Path) -> bool {
path.extension().map(|e| e == "xlsx").unwrap_or(false)
&& path.parent().map(|d| d.is_dir()).unwrap_or(true)
&& std::fs::OpenOptions::new().write(true).create(true).open(path).is_ok()
} Try / catch
match write_xlsx(&book, &path) {
Err(e) if e.to_string().contains("não gravei o xlsx") => {
let tmp = path.with_extension("xlsx.tmp");
write_xlsx(&book, &tmp)?; // retry via temp file
std::fs::rename(&tmp, &path)?;
}
other => other?,
} Prevention
- Write to a temp file and rename, avoiding corrupt/locked targets
- Check the .xlsx isn't open in Excel/LibreOffice before overwriting on Windows
- create_dir_all the output directory and test writability up front
- Catch the error early in long batch jobs and continue with remaining files instead of aborting
When it happens
Trigger: The destination path is in a read-only or nonexistent directory; insufficient write permission; path is a directory, not a file; path length/format issues (invalid chars on Windows); disk full; another process holds a lock on the target .xlsx (e.g. open in Excel).
Common situations: Target .xlsx is currently open in Excel/LibreOffice (Windows file lock); output_dir points to a non-writable location; saving to a network share that dropped; filename contains characters the OS rejects.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12).
Data as JSON: /api/errors/9fe31e17fa8db6de.
Report an issue: GitHub.
Appendix: source
Thrown at src-tauri/omniget-core/src/core/tools/pdf_table.rs:417
.take(31)
.collect();
sheet.set_name(&name)?;
for (r, row) in t.cells.iter().enumerate() {
for (c, cell) in row.iter().enumerate() {
let (r, c) = (r as u32, c as u16);
match as_number(cell) {
Some(v) => {
sheet.write_number(r, c, v)?;
}
None => {
sheet.write_string(r, c, cell.trim())?;
}
}
}
}
}
book.save(path)
.map_err(|e| anyhow!("não gravei o xlsx: {}", e))?;
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use crate::core::tools::pdf::TextChar;
fn ch(c: char, x: f32, y: f32, size: f32) -> TextChar {
TextChar {
ch: c,
x0: x,
x1: x + size * 0.5,
y0: y,
y1: y + size,
size,
mono: false,
bold: false,View on GitHub (pinned to 8600b91f42)