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

  1. Check the embedded cause in the message; if permission/locked, close the file in Excel/LibreOffice or pick another output path
  2. Verify the output directory exists and is writable (create_dir_all / check permissions)
  3. Save to a temp file then atomically rename, so partial writes don't corrupt the target
  4. 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

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)