Biblioteca Office para Go — Inicio Rápido
El paquete Go github.com/yfedoseev/office_oxide/go envuelve el FFI C de office_oxide vía cgo y ofrece tipos Go idiomáticos para leer, convertir y editar DOCX / XLSX / PPTX / DOC / XLS / PPT.
Instalación
go get github.com/yfedoseev/office_oxide/go@latest
El binding necesita la librería C office_oxide en tiempo de enlace. Dos formas de proporcionarla.
Opción 1 — instalador en una línea (recomendado):
go run github.com/yfedoseev/office_oxide/go/cmd/install@latest
El instalador descarga el liboffice_oxide prebuilt (y la cabecera) que coincida con tu OS/arch y los coloca donde cgo pueda encontrarlos. Vuelve a ejecutarlo tras un upgrade para tomar la nueva ABI.
Opción 2 — define las flags de cgo a mano si compilaste desde el source Rust (cargo build --release --lib) o tienes la librería en un prefijo del sistema:
export CGO_CFLAGS="-I/usr/local/include"
export CGO_LDFLAGS="-L/usr/local/lib -loffice_oxide"
Leer un documento
package main
import (
"fmt"
"log"
officeoxide "github.com/yfedoseev/office_oxide/go"
)
func main() {
doc, err := officeoxide.Open("report.docx")
if err != nil {
log.Fatal(err)
}
defer doc.Close()
text, err := doc.PlainText()
if err != nil {
log.Fatal(err)
}
fmt.Println(text)
}
Helper de un solo paso:
text, err := officeoxide.ExtractText("report.docx")
API principal
doc, err := officeoxide.Open("file.xlsx")
if err != nil { log.Fatal(err) }
defer doc.Close()
format, _ := doc.Format() // "xlsx"
text, _ := doc.PlainText()
md, _ := doc.ToMarkdown()
html, _ := doc.ToHTML()
irJSON, _ := doc.ToIRJSON()
err = doc.SaveAs("file.docx")
Document envuelve un handle C; un finalizer lo libera si olvidas Close, pero siempre prefiere defer doc.Close() para una limpieza determinista.
Abrir desde bytes (útil para streaming / serverless):
data, _ := os.ReadFile("report.pptx")
doc, err := officeoxide.OpenFromBytes(data, "pptx")
format debe ser "docx", "xlsx", "pptx", "doc", "xls" o "ppt".
Edición
Los handles editables conservan al guardar todas las partes OPC sin tocar (imágenes, gráficos, XML personalizado). Solo DOCX, XLSX y PPTX.
ed, err := officeoxide.OpenEditable("template.docx")
if err != nil { log.Fatal(err) }
defer ed.Close()
n, _ := ed.ReplaceText("{{name}}", "Alice")
fmt.Printf("%d reemplazos\n", n)
err = ed.Save("out.docx")
Reemplazar texto en DOCX / PPTX
ed, _ := officeoxide.OpenEditable("slides.pptx")
defer ed.Close()
ed.ReplaceText("Q3", "Q4")
ed.ReplaceText("2024", "2025")
buf, _ := ed.SaveToBytes() // []byte listo para subir / streamear
_ = os.WriteFile("slides_q4.pptx", buf, 0o644)
Establecer celdas XLSX
ed, _ := officeoxide.OpenEditable("budget.xlsx")
defer ed.Close()
ed.SetCell(0, "A1", officeoxide.NewStringCell("Total"))
ed.SetCell(0, "B1", officeoxide.NewNumberCell(42.5))
ed.SetCell(0, "C1", officeoxide.NewBoolCell(true))
ed.SetCell(0, "D1", officeoxide.NewEmptyCell())
ed.Save("budget.xlsx")
Usa NewStringCell, NewNumberCell, NewBoolCell o NewEmptyCell — el constructor elige la variante correcta para la llamada FFI.
IR independiente del formato
doc.ToIRJSON() devuelve JSON acorde al esquema DocumentIR de Rust. Unmarshal en la forma que necesites:
import "encoding/json"
irJSON, _ := doc.ToIRJSON()
var ir struct {
Sections []struct {
Title *string `json:"title"`
Elements []json.RawMessage `json:"elements"`
} `json:"sections"`
}
_ = json.Unmarshal([]byte(irJSON), &ir)
fmt.Printf("%d secciones\n", len(ir.Sections))
Detectar formato sin abrir
fmt := officeoxide.DetectFormat("mystery.bin") // "" si no se soporta
Formatos heredados
Se abren como OOXML; SaveAs convierte transparentemente vía IR:
doc, _ := officeoxide.Open("old.xls")
defer doc.Close()
_ = doc.SaveAs("modern.xlsx")
Errores
Cada llamada falible devuelve un *officeoxide.Error con código tipado y la operación de origen:
if _, err := officeoxide.Open("missing.docx"); err != nil {
var e *officeoxide.Error
if errors.As(err, &e) {
fmt.Printf("code=%d op=%s\n", e.Code, e.Op)
}
}
Usar un handle cerrado devuelve officeoxide.ErrClosed.
| Código | Nombre | Significado |
|---|---|---|
| 0 | OK |
éxito |
| 1 | INVALID_ARG |
nil / vacío / cadena de formato errónea |
| 2 | IO |
error de filesystem |
| 3 | PARSE |
documento corrupto |
| 4 | EXTRACTION |
el parseo fue bien, pero falló el render |
| 5 | INTERNAL |
bug — abre una issue |
| 6 | UNSUPPORTED |
extensión/función no soportada |
Solución de problemas
| Síntoma | Solución |
|---|---|
could not determine kind of name for C.office_document_open |
Las cabeceras C no son visibles para cgo. Ejecuta el instalador o define CGO_CFLAGS. |
cannot find -loffice_oxide al enlazar |
Define CGO_LDFLAGS="-L/path/to/lib -loffice_oxide" o ejecuta el instalador. |
En runtime cannot open shared object file |
Añade el directorio de la lib a LD_LIBRARY_PATH (Linux), DYLD_LIBRARY_PATH (macOS) o copia la DLL junto al binario (Windows). |
unsupported format en .doc/.xls |
Asegúrate de que la extensión esté en minúsculas o llama a OpenFromBytes(data, "doc"). |
| Falla la cross-compilation | cgo necesita un toolchain C que coincida con el target. Usa zig cc o CC=aarch64-linux-gnu-gcc. |
Véase también
- Benchmarks de rendimiento
- Paquete en pkg.go.dev
- Cabecera C —
include/office_oxide_c/office_oxide.h