Skip to content

Go Office 라이브러리 — 빠른 시작

Go 패키지 github.com/yfedoseev/office_oxide/go는 office_oxide의 C FFI를 cgo로 감싸서 DOCX / XLSX / PPTX / DOC / XLS / PPT를 읽고 변환·편집하는 관용적인 Go 타입을 제공합니다.

설치

go get github.com/yfedoseev/office_oxide/go@latest

이 바인딩은 링크 시 office_oxide C 라이브러리가 필요합니다. 두 가지 방법.

옵션 1 — 원라인 설치기(권장):

go run github.com/yfedoseev/office_oxide/go/cmd/install@latest

설치기는 OS/아키텍처에 맞는 사전 빌드된 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 핸들을 감쌉니다. Close를 잊으면 파이널라이저가 해제하지만, 결정적 정리를 위해 항상 defer doc.Close()를 우선하세요.

바이트에서 열기(스트리밍/서버리스용):

data, _ := os.ReadFile("report.pptx")
doc, err := officeoxide.OpenFromBytes(data, "pptx")

format"docx", "xlsx", "pptx", "doc", "xls", "ppt" 중 하나여야 합니다.

편집

편집 가능한 핸들은 저장 시 변경되지 않은 모든 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()은 Rust DocumentIR 스키마와 일치하는 JSON을 반환합니다. 원하는 타입으로 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")  // 미지원이면 ""

레거시 형식

OOXML과 동일하게 엽니다. SaveAs가 IR을 통해 투명하게 변환:

doc, _ := officeoxide.Open("old.xls")
defer doc.Close()
_ = doc.SaveAs("modern.xlsx")

오류

실패 가능한 모든 호출은 타입화된 코드와 발생 지점 operation을 가진 *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)
    }
}

닫힌 핸들을 사용하면 officeoxide.ErrClosed가 반환됩니다.

Code 이름 의미
0 OK 성공
1 INVALID_ARG nil / 빈 값 / 잘못된 format 문자열
2 IO 파일 시스템 오류
3 PARSE 문서가 잘못됨
4 EXTRACTION 파싱은 성공했지만 렌더링 실패
5 INTERNAL 버그 — 이슈를 등록해 주세요
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).
.doc/.xls에서 unsupported format 확장자가 소문자인지 확인하거나 OpenFromBytes(data, "doc")를 호출.
크로스 컴파일 실패 cgo는 타깃에 맞는 C 툴체인이 필요합니다. zig cc 또는 CC=aarch64-linux-gnu-gcc 사용.

더 보기