spreadsheet

package module
v0.0.0-...-08943ef Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 7, 2026 License: MIT Imports: 7 Imported by: 0

README

go-spreadsheet

CI Go Reference Go Report Card

go-spreadsheet is a pure-Go, zero-CGO spreadsheet library that serves as a drop-in replacement for Excelize, with added full support for legacy .xls files (Excel 97-2003 BIFF8).

Feature go-spreadsheet Excelize
Read XLS (BIFF8)
Write XLS
Read XLSX/XLSM
Write XLSX/XLSM
Pure Go (no CGO)
Streaming reader
Streaming writer

Installation

go get github.com/antoema342/go-spreadsheet

Requires Go 1.22 or later.


Quick Start

import spreadsheet "github.com/antoema342/go-spreadsheet"

// Create a new XLSX file
f := spreadsheet.NewFile()
f.SetCellValue("Sheet1", "A1", "Hello, World!")
f.SaveAs("output.xlsx")

// Read an existing file (XLS or XLSX — auto-detected)
f, err := spreadsheet.OpenFile("report.xls")
if err != nil {
    log.Fatal(err)
}
defer f.Close()

val, _ := f.GetCellValue("Sheet1", "A1")
fmt.Println(val)

Migration from Excelize

Change a single import line:

- import "github.com/xuri/excelize/v2"
+ import spreadsheet "github.com/antoema342/go-spreadsheet"

The API is intentionally compatible — most existing Excelize code continues to compile and run without further modifications.


Reading Files

Reading XLSX
f, err := spreadsheet.OpenFile("data.xlsx")
if err != nil {
    log.Fatal(err)
}
defer f.Close()

rows, err := f.GetRows("Sheet1")
for _, row := range rows {
    fmt.Println(row)
}
Reading XLS (legacy Excel 97-2003)
f, err := spreadsheet.OpenFile("data.xls")   // same API — format is auto-detected
if err != nil {
    log.Fatal(err)
}
defer f.Close()

val, _ := f.GetCellValue("Sheet1", "B3")
fmt.Println(val)
Reading from an io.Reader
data, _ := os.ReadFile("report.xlsx")   // or .xls
f, err := spreadsheet.OpenReader(bytes.NewReader(data))

Writing Files

Writing XLSX
f := spreadsheet.NewFile()

f.SetCellValue("Sheet1", "A1", "Product")
f.SetCellValue("Sheet1", "B1", "Price")
f.SetCellValue("Sheet1", "A2", "Widget")
f.SetCellValue("Sheet1", "B2", 9.99)

if err := f.SaveAs("prices.xlsx"); err != nil {
    log.Fatal(err)
}
Writing XLS
// XLS files are written using the same API when loaded as XLS
f, _ := spreadsheet.OpenFile("template.xls")
f.SetCellValue("Sheet1", "A1", "Updated value")
f.Save("template.xls")

Streaming

Use the streaming API to process very large files without loading them fully into memory.

Stream Reader
f, _ := spreadsheet.OpenFile("large.xlsx")
rows, _ := f.Rows("Sheet1")

for rows.Next() {
    cols, _ := rows.Columns()
    fmt.Println(cols)
}
Stream Writer
f := spreadsheet.NewFile()
sw, _ := f.NewStreamWriter("Sheet1")

for i := 1; i <= 1_000_000; i++ {
    addr := fmt.Sprintf("A%d", i)
    sw.SetRow(addr, []any{i, "Row data", float64(i) * 1.5})
}
sw.Flush()
f.SaveAs("million_rows.xlsx")

Formulas

f := spreadsheet.NewFile()
f.SetCellValue("Sheet1", "B1", 10)
f.SetCellValue("Sheet1", "B2", 20)
f.SetCellFormula("Sheet1", "B3", "=SUM(B1:B2)")

formula, _ := f.GetCellFormula("Sheet1", "B3")
fmt.Println(formula) // =SUM(B1:B2)

Style

f := spreadsheet.NewFile()

style, _ := f.NewStyle(&spreadsheet.StyleConfig{
    Font: &spreadsheet.Font{
        Bold:   true,
        Size:   14,
        Family: "Arial",
        Color:  "FF000000",
    },
    Fill: &spreadsheet.Fill{
        Type:  "pattern",
        Color: "FFCCFFCC",
    },
    Alignment: &spreadsheet.Alignment{
        Horizontal: "center",
        WrapText:   true,
    },
})

f.SetCellValue("Sheet1", "A1", "Header")
f.SetCellStyle("Sheet1", "A1", "A1", style)
f.SaveAs("styled.xlsx")

Merge Cells

f := spreadsheet.NewFile()
f.SetCellValue("Sheet1", "A1", "Merged Header")
f.MergeCell("Sheet1", "A1", "D1")
f.SaveAs("merged.xlsx")

Images / Pictures

f := spreadsheet.NewFile()
f.AddPicture("Sheet1", "C3", "logo.png", &spreadsheet.GraphicOptions{
    ScaleX: 0.5,
    ScaleY: 0.5,
})
f.SaveAs("with_image.xlsx")

Sheet Operations

f := spreadsheet.NewFile()

// Create sheets
f.NewSheet("Summary")
f.NewSheet("Data")

// List sheets
sheets, _ := f.GetSheetList()
fmt.Println(sheets) // [Sheet1 Summary Data]

// Rename
f.SetSheetName("Sheet1", "Overview")

// Delete
f.DeleteSheet("Summary")

// Duplicate
f.DuplicateSheet(0, 1)

Freeze Pane

f := spreadsheet.NewFile()
f.FreezePane("Sheet1", "B2", 1, 1) // freeze first row and first column

FAQ

Q: Does it support password-protected files?
A: Reading password-protected XLS/XLSX is not currently supported; the API returns an appropriate error.

Q: Is it thread-safe?
A: A *File should not be shared across goroutines without external synchronisation (same as Excelize).

Q: What BIFF versions are supported for XLS?
A: BIFF8 (Excel 97-2003). Older BIFF2/3/4/5 formats can be partially read.

Q: Where is the .xlsm macro content?
A: The XLSM container is read and written as a standard OOXML file; VBA macros are preserved verbatim but are not executed or modified.


Benchmark

Run benchmarks:

go test ./benchmark/... -bench=. -benchmem

Typical results on Apple M1 (Go 1.22):

Benchmark ops/ns mem
NewFile ~400 ns/op 2 KB
SetCellValue ~200 ns/op 128 B
GetCellValue ~80 ns/op 0 B
WriteXLSX 1000 rows ~8 ms/op 1 MB
ReadXLSX 1000 rows ~5 ms/op 800 KB
StreamWriter 1 000 rows ~2 ms/op 400 KB

License

MIT © 2024 antoema342. See LICENSE.

Documentation

Overview

Package spreadsheet is a pure-Go drop-in replacement for Excelize that adds full support for legacy .xls files (Excel 97-2003 BIFF8) in addition to the modern .xlsx / .xlsm / .xltx format.

Quick start:

f, err := spreadsheet.OpenFile("book.xlsx")
if err != nil { log.Fatal(err) }
defer f.Close()

val, _ := f.GetCellValue("Sheet1", "A1")
fmt.Println(val)

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrColumnWidth defines an error for the column width isn't valid.
	ErrColumnWidth = errors.New("invalid column width")

	// ErrParameterInvalid defines an error for the parameter is invalid.
	ErrParameterInvalid = errors.New("parameter is invalid")

	// ErrStreamSetRow defines an error for the stream writer using the SetRow function.
	ErrStreamSetRow = errors.New("can't use SetRow in stream mode")

	// ErrUnknownEncryptMechanism defines an error for unknown encryption mechanism.
	ErrUnknownEncryptMechanism = errors.New("unknown encryption mechanism")

	// ErrUnsupportedChartType defines an error for the unsupported chart type.
	ErrUnsupportedChartType = errors.New("unsupported chart type")

	// ErrUnsupportedFileType defines an error for the unsupported file type.
	ErrUnsupportedFileType = errors.New("unsupported file type")

	// ErrWorkbookFileFormatUndefined defines an error for the workbook file format is undefined.
	ErrWorkbookFileFormatUndefined = errors.New("workbook file format is undefined")

	// ErrMaxRows defines an error for the maximum number of rows exceeded.
	ErrMaxRows = errors.New("max number of rows exceeded")

	// ErrMaxColumns defines an error for the maximum number of columns exceeded.
	ErrMaxColumns = errors.New("max number of columns exceeded")
)

Common errors returned by the spreadsheet package.

Functions

This section is empty.

Types

type Alignment

type Alignment = xmltypes.Alignment

Alignment holds text-alignment properties.

type Border

type Border = xmltypes.Border

Border holds border style properties.

type DocProps

type DocProps = xmltypes.DocProps

DocProps holds document-level properties.

type File

type File struct {

	// Path is the file path from which the document was loaded (empty for new files).
	Path string

	// Type indicates the underlying file format.
	Type FileType

	// WorkBook is the exposed workbook entity (both spellings for compat).
	WorkBook *xmltypes.WorkBookEntity
	Workbook *xmltypes.WorkBookEntity
	// contains filtered or unexported fields
}

File represents an open spreadsheet document. It transparently wraps either an .xls or an .xlsx file and exposes a unified Excelize-compatible API.

func NewFile

func NewFile() *File

NewFile creates a new empty XLSX spreadsheet document.

func OpenFile

func OpenFile(filename string) (*File, error)

OpenFile opens a spreadsheet document from the local filesystem. The format is determined from the file extension (.xls, .xlsx, .xlsm, .xlt, .xltx).

Example:

f, err := spreadsheet.OpenFile("report.xlsx")
if err != nil { log.Fatal(err) }
defer f.Close()

func OpenReader

func OpenReader(r io.Reader) (*File, error)

OpenReader opens a spreadsheet document from an io.Reader. The format is auto-detected from the stream's magic bytes.

Example:

f, err := spreadsheet.OpenReader(os.Stdin)

func (*File) AddPicture

func (f *File) AddPicture(sheet, cell, picture string, opts *GraphicOptions) error

AddPicture embeds a picture file at the given cell in a worksheet.

func (*File) AutoFilter

func (f *File) AutoFilter(sheet, hCell, vCell string) error

AutoFilter sets an auto-filter for the given range.

func (*File) Close

func (f *File) Close() error

Close releases any resources held by the open document.

func (*File) DeleteSheet

func (f *File) DeleteSheet(name string) error

DeleteSheet removes the named worksheet from the workbook.

func (*File) DuplicateSheet

func (f *File) DuplicateSheet(from, to int) error

DuplicateSheet duplicates the worksheet at index from and appends the copy.

func (*File) FreezePane

func (f *File) FreezePane(sheet, cell string, row, col int) error

FreezePane creates a freeze pane at the given row and column.

func (*File) GetCellFormula

func (f *File) GetCellFormula(sheet, axis string) (string, error)

GetCellFormula returns the formula stored in the given cell.

func (*File) GetCellValue

func (f *File) GetCellValue(sheet, axis string) (string, error)

GetCellValue returns the raw string value of the cell at axis (e.g. "A1").

func (*File) GetCols

func (f *File) GetCols(sheet string) ([][]string, error)

GetCols returns all columns of a worksheet as a 2-D slice.

func (*File) GetRows

func (f *File) GetRows(sheet string) ([][]string, error)

GetRows returns all rows of a worksheet as a 2-D slice.

func (*File) GetSheetIndex

func (f *File) GetSheetIndex(name string) (int, error)

GetSheetIndex returns the 0-based index of the named worksheet, or -1 if not found.

func (*File) GetSheetList

func (f *File) GetSheetList() ([]string, error)

GetSheetList returns the names of all worksheets in order.

func (*File) GetSheetName

func (f *File) GetSheetName(index int) (string, error)

GetSheetName returns the name of the worksheet at the given 0-based index.

func (*File) InsertCols

func (f *File) InsertCols(sheet, col string, n int) error

InsertCols inserts n columns before the given column letter.

func (*File) InsertRows

func (f *File) InsertRows(sheet string, row int) error

InsertRows inserts n empty rows after the given 1-based row index.

func (*File) MergeCell

func (f *File) MergeCell(sheet, hCell, vCell string) error

MergeCell merges cells from hCell to vCell in the given sheet.

func (*File) NewSheet

func (f *File) NewSheet(name string) (int, error)

NewSheet creates a new worksheet with the given name. Returns the 0-based index of the new sheet.

func (*File) NewStreamWriter

func (f *File) NewStreamWriter(sheet string) (*StreamWriter, error)

NewStreamWriter returns a streaming writer for the named worksheet.

func (*File) NewStyle

func (f *File) NewStyle(style *StyleConfig) (int, error)

NewStyle creates a new style from a StyleConfig and returns its integer index.

func (*File) ProtectSheet

func (f *File) ProtectSheet(sheet string, opts *SheetProtection) error

ProtectSheet applies password protection to a worksheet.

func (*File) RemoveCol

func (f *File) RemoveCol(sheet, col string) error

RemoveCol removes the given column from a worksheet.

func (*File) RemoveRow

func (f *File) RemoveRow(sheet string, row int) error

RemoveRow removes the 1-based row from the named worksheet.

func (*File) Rows

func (f *File) Rows(sheet string) (*Rows, error)

Rows returns a streaming row iterator for the named worksheet.

Example:

rows, _ := f.Rows("Sheet1")
for rows.Next() {
    cols, _ := rows.Columns()
    _ = cols
}

func (*File) Save

func (f *File) Save(path string) error

Save writes the document to the given path.

func (*File) SaveAs

func (f *File) SaveAs(path string) error

SaveAs saves the document to the given path (alias for Save).

func (*File) SetCellFormula

func (f *File) SetCellFormula(sheet, axis, formula string) error

SetCellFormula writes a formula string to the given cell.

func (*File) SetCellStyle

func (f *File) SetCellStyle(sheet, hCell, vCell string, styleID int) error

SetCellStyle applies a named style index to a range of cells from hCell to vCell.

func (*File) SetCellValue

func (f *File) SetCellValue(sheet, axis string, value any) error

SetCellValue sets the value of a cell. The value may be any Go type; it will be converted to its string representation.

func (*File) SetDocProps

func (f *File) SetDocProps(props *DocProps) error

SetDocProps sets document-level metadata properties.

func (*File) SetSheetName

func (f *File) SetSheetName(oldName, newName string) error

SetSheetName renames a worksheet from oldName to newName.

func (*File) UnmergeCell

func (f *File) UnmergeCell(sheet, hCell string) error

UnmergeCell removes a merge from the given range.

func (*File) UnprotectSheet

func (f *File) UnprotectSheet(sheet, password string) error

UnprotectSheet removes protection from a worksheet.

type FileType

type FileType int

FileType represents the type of a spreadsheet file.

const (
	// XLSX represents the Office Open XML (.xlsx/.xlsm/.xltx) format.
	XLSX FileType = iota
	// XLS represents the legacy BIFF8 (.xls) format.
	XLS
)

type Fill

type Fill = xmltypes.Fill

Fill holds fill/background style properties.

type Font

type Font = xmltypes.Font

Font holds font style properties.

type GraphicOptions

type GraphicOptions = xmltypes.GraphicOptions

GraphicOptions holds options for embedding pictures.

type Rows

type Rows struct {
	// contains filtered or unexported fields
}

Rows is a streaming row iterator for a worksheet. It reads one row at a time, suitable for very large files.

func (*Rows) Columns

func (rows *Rows) Columns() ([]string, error)

Columns returns the cell values for the current row.

func (*Rows) Next

func (rows *Rows) Next() bool

Next advances the iterator to the next row. Returns false when exhausted.

type SheetEntity

type SheetEntity = xmltypes.SheetEntity

SheetEntity represents a single sheet entry in the workbook. Kept for backward compatibility.

type SheetProtection

type SheetProtection = xmltypes.SheetProtection

SheetProtection holds sheet-protection settings.

type SheetsCollection

type SheetsCollection = xmltypes.SheetsCollection

SheetsCollection represents all sheets in a workbook. Kept for backward compatibility.

type StreamWriter

type StreamWriter struct {
	// contains filtered or unexported fields
}

StreamWriter provides a streaming write interface for large datasets. Use SetRow to append rows one at a time, then call Flush when done.

Example:

sw, _ := f.NewStreamWriter("Sheet1")
sw.SetRow("A1", []any{1, "Alice", 99.5})
sw.SetRow("A2", []any{2, "Bob",   87.0})
sw.Flush()

func (*StreamWriter) Flush

func (sw *StreamWriter) Flush() error

Flush commits all pending row data to the document. It must be called after all rows have been written.

func (*StreamWriter) SetRow

func (sw *StreamWriter) SetRow(axis string, values []any) error

SetRow writes a slice of values as a row starting at the given cell address. Values can be any Go type; they are converted to their string representations.

type StyleConfig

type StyleConfig = xmltypes.StyleConfig

StyleConfig holds all styling properties that can be applied to a cell.

type WorkBookEntity

type WorkBookEntity = xmltypes.WorkBookEntity

WorkBookEntity represents the main workbook structure.

Directories

Path Synopsis
Command examples demonstrates the go-spreadsheet library.
Command examples demonstrates the go-spreadsheet library.
internal
ole
Package ole implements a pure-Go reader for OLE2 Compound Document files.
Package ole implements a pure-Go reader for OLE2 Compound Document files.
ooxml
Package ooxml implements a pure-Go parser and writer for Office Open XML (OOXML) spreadsheet files (.xlsx, .xlsm, .xltx, .xltm).
Package ooxml implements a pure-Go parser and writer for Office Open XML (OOXML) spreadsheet files (.xlsx, .xlsm, .xltx, .xltm).
xmltypes
Package xmltypes defines shared types used across the go-spreadsheet library.
Package xmltypes defines shared types used across the go-spreadsheet library.
Package xls provides a pure-Go reader and writer for legacy Excel .xls files (BIFF5/BIFF8 format) via OLE2 compound document parsing.
Package xls provides a pure-Go reader and writer for legacy Excel .xls files (BIFF5/BIFF8 format) via OLE2 compound document parsing.
Package xlsx provides a pure-Go reader and writer for Office Open XML spreadsheet files (.xlsx, .xlsm, .xltx, .xltm).
Package xlsx provides a pure-Go reader and writer for Office Open XML spreadsheet files (.xlsx, .xlsm, .xltx, .xltm).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL