Go-бібліотека для Office — швидкий старт
Пакет Go github.com/yfedoseev/office_oxide/go обгортає C FFI office_oxide через cgo і дає ідіоматичні Go-типи для читання, конвертації та редагування DOCX / XLSX / PPTX / DOC / XLS / PPT.
Встановлення
go get github.com/yfedoseev/office_oxide/go@latest
Прив’язка потребує C-бібліотеки office_oxide під час лінкування. Два способи отримати її.
Варіант 1 — однорядковий установник (рекомендовано):
go run github.com/yfedoseev/office_oxide/go/cmd/install@latest
Установник завантажує підходящий prebuilt-liboffice_oxide (і заголовок) під вашу ОС/архітектуру і кладе так, щоб cgo міг їх знайти. Після оновлення запустіть знову, щоб підтягнути новий ABI.
Варіант 2 — задати cgo-прапорці вручну, якщо ви зібрали бібліотеку з Rust-джерел (cargo build --release --lib) або вона лежить у системному prefix:
export CGO_CFLAGS="-I/usr/local/include"
export CGO_LDFLAGS="-L/usr/local/lib -loffice_oxide"
Прочитати документ
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)
}
Одноразовий помічник:
text, err := officeoxide.ExtractText("report.docx")
Базовий API
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 обгортає C-handle; finalizer звільнить його, якщо забути Close, але завжди надавайте перевагу defer doc.Close() для детермінованого очищення.
Відкриття з байтів (для стримінгу/serverless):
data, _ := os.ReadFile("report.pptx")
doc, err := officeoxide.OpenFromBytes(data, "pptx")
format повинен бути "docx", "xlsx", "pptx", "doc", "xls" або "ppt".
Редагування
Editable-handle зберігає при збереженні всі незмінені OPC-частини (зображення, діаграми, кастомний XML). Лише DOCX, XLSX та PPTX.
ed, err := officeoxide.OpenEditable("template.docx")
if err != nil { log.Fatal(err) }
defer ed.Close()
n, _ := ed.ReplaceText("{{name}}", "Alice")
fmt.Printf("%d замін\n", n)
err = ed.Save("out.docx")
Заміна тексту в DOCX / PPTX
ed, _ := officeoxide.OpenEditable("slides.pptx")
defer ed.Close()
ed.ReplaceText("Q3", "Q4")
ed.ReplaceText("2024", "2025")
buf, _ := ed.SaveToBytes() // []byte для аплоаду/стрімінгу
_ = os.WriteFile("slides_q4.pptx", buf, 0o644)
Запис клітинок 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")
Використовуйте NewStringCell, NewNumberCell, NewBoolCell або NewEmptyCell — конструктор обере правильний варіант для FFI-виклику.
Формат-незалежний IR
doc.ToIRJSON() повертає JSON, що відповідає схемі Rust DocumentIR. Unmarshal у потрібну форму:
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 секцій\n", len(ir.Sections))
Визначення формату без відкриття
fmt := officeoxide.DetectFormat("mystery.bin") // "" якщо не підтримується
Legacy-формати
Відкриваються як OOXML; SaveAs прозоро конвертує через IR:
doc, _ := officeoxide.Open("old.xls")
defer doc.Close()
_ = doc.SaveAs("modern.xlsx")
Помилки
Кожен виклик з можливою помилкою повертає *officeoxide.Error з типізованим кодом та операцією походження:
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)
}
}
Використання закритої handle повертає officeoxide.ErrClosed.
| Код | Ім’я | Значення |
|---|---|---|
| 0 | OK |
успіх |
| 1 | INVALID_ARG |
nil / порожньо / неправильний рядок формату |
| 2 | IO |
помилка файлової системи |
| 3 | PARSE |
пошкоджений документ |
| 4 | EXTRACTION |
парсинг ОК, але рендер не вдався |
| 5 | INTERNAL |
баг — заведіть issue |
| 6 | UNSUPPORTED |
розширення/функція не підтримується |
Діагностика
| Симптом | Що робити |
|---|---|
could not determine kind of name for C.office_document_open |
C-заголовки невидимі для cgo. Запустіть установник або задайте CGO_CFLAGS. |
Лінкування: cannot find -loffice_oxide |
Задайте CGO_LDFLAGS="-L/path/to/lib -loffice_oxide" або запустіть установник. |
Рантайм: cannot open shared object file |
Додайте каталог бібліотеки до LD_LIBRARY_PATH (Linux), DYLD_LIBRARY_PATH (macOS) або покладіть DLL поруч із бінарем (Windows). |
unsupported format для .doc/.xls |
Переконайтеся, що розширення в нижньому регістрі, або викличте OpenFromBytes(data, "doc"). |
| Крос-компіляція падає | cgo потребує C-toolchain під цільову платформу. Використовуйте zig cc або CC=aarch64-linux-gnu-gcc. |
Дивіться також
- Бенчмарки продуктивності
- Пакунок: pkg.go.dev
- C-заголовок —
include/office_oxide_c/office_oxide.h