xlsxlite

package module
v0.1.4 Latest Latest
Warning

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

Go to latest
Published: Mar 20, 2026 License: MIT Imports: 10 Imported by: 1

README

xlsxlite

CI

A lightweight, memory-efficient XLSX read/write library for Go. The core library has zero external dependencies — stdlib only. An optional gcs subpackage adds Google Cloud Storage support.

Why?

Most Go XLSX libraries load entire worksheet XML DOMs into memory. A 7MB XLSX can consume ~1GB of RAM; 1M rows can exceed 3.6GB allocations. That's fine for small files, but breaks down for large-scale ETL, report generation, or memory-constrained environments (like your GKE pods).

xlsxlite takes a streaming approach:

DOM-based libraries xlsxlite
Architecture Full DOM in memory Streaming XML read/write
Dependencies Multiple 0 for core (stdlib only); gcs subpackage adds cloud.google.com/go/storage
Features Full (charts, formulas, images, pivot tables) Essential (cells, styles, merges, col widths, freeze panes)
Write pattern Random access (any cell, any order) Sequential (row-by-row, streaming)
Read pattern Full DOM or streaming option Streaming iterator only
Memory model
DOM-based:  Load entire XML → Build struct tree → Hold in memory → Write all at once
xlsxlite:   Stream XML token-by-token → Process one row → Discard → Next row

Write-side memory is O(unique strings) rather than O(total cells). Read-side memory is O(shared string table + 1 row).

Install

go get github.com/louvri/xlsxlite

For optional Google Cloud Storage support (separate module, won't pollute your dependency tree unless you import it):

go get github.com/louvri/xlsxlite/gcs

Quick Start

Writing
package main

import (
    "os"
    "github.com/louvri/xlsxlite"
)

func main() {
    f, _ := os.Create("report.xlsx")
    defer f.Close()

    w := xlsxlite.NewWriter(f)

    // Register styles before writing rows
    ss := w.StyleSheet()
    headerStyle := ss.AddStyle(xlsxlite.Style{
        Font: &xlsxlite.Font{Bold: true, Size: 12, Color: "FFFFFFFF"},
        Fill: &xlsxlite.Fill{Type: "pattern", Pattern: "solid", FgColor: "FF4472C4"},
        Alignment: &xlsxlite.Alignment{Horizontal: "center"},
    })

    // Create sheet with configuration
    sw, _ := w.NewSheet(xlsxlite.SheetConfig{
        Name:      "Sales Report",
        ColWidths: map[int]float64{0: 25, 1: 15, 2: 15},
        FreezeRow: 1,
        MergeCells: []xlsxlite.MergeCell{
            {StartCol: 0, StartRow: 1, EndCol: 2, EndRow: 1},
        },
    })

    // Write header row with styles
    sw.WriteRow(xlsxlite.Row{
        Cells: []xlsxlite.Cell{
            xlsxlite.StyledCell("Product", headerStyle),
            xlsxlite.StyledCell("Revenue", headerStyle),
            xlsxlite.StyledCell("Units", headerStyle),
        },
    })

    // Stream data rows — memory stays flat regardless of row count
    for i := 0; i < 1_000_000; i++ {
        sw.WriteRow(xlsxlite.MakeRow("Widget", 29.99, 150))
    }

    sw.Close() // finalize sheet
    w.Close()  // finalize XLSX package
}
Reading
package main

import (
    "fmt"
    "github.com/louvri/xlsxlite"
)

func main() {
    reader, _ := xlsxlite.OpenFile("report.xlsx")
    defer reader.Close()

    fmt.Println("Sheets:", reader.SheetNames())
    fmt.Println("Count:", reader.SheetCount())

    iter, _ := reader.OpenSheet("Sales Report")
    defer iter.Close()

    for iter.Next() {
        row := iter.Row()
        for _, cell := range row.Cells {
            fmt.Printf("%v\t", cell.Value)
        }
        fmt.Println()
    }

    if err := iter.Err(); err != nil {
        fmt.Println("Error:", err)
    }
}

You can also open sheets by index:

iter, err := reader.OpenSheetByIndex(0) // 0-based

Or read from any io.ReaderAt (e.g. *bytes.Reader):

reader, err := xlsxlite.OpenReader(readerAt, size)
Google Cloud Storage

The gcs subpackage provides helpers for reading/writing XLSX files directly from/to GCS:

import "github.com/louvri/xlsxlite/gcs"

// Reading — downloads object into memory, then streams rows
reader, err := gcs.OpenFile(ctx, client, "my-bucket", "reports/data.xlsx")

// Writing — streams directly to GCS object
w, closeFn, err := gcs.CreateFile(ctx, client, "my-bucket", "reports/output.xlsx")
// ... write sheets and rows ...
w.Close()      // finalize XLSX
closeFn()      // complete GCS upload

API Reference

Cell constructors
xlsxlite.StringCell("hello")              // string (shared string, no type coercion)
xlsxlite.NumberCell(42.5)                  // float64
xlsxlite.IntCell(100)                      // int
xlsxlite.BoolCell(true)                    // bool
xlsxlite.DateCell(time.Now(), dateStyleID) // date with style
xlsxlite.StyledCell("value", styleID)      // any value with style (type auto-detected)
xlsxlite.EmptyCell()                       // empty cell (padding)
xlsxlite.MakeRow("a", 1, true, nil)       // mixed types in one row

MakeRow accepts: string, float64, float32, int, int64, bool, Cell, nil. Any other type is converted to a string via fmt.Sprintf.

Cell values on read

When reading cells, values are returned as Go types based on the XLSX cell type:

XLSX type Cell.Type Cell.Value Go type
Shared/inline string CellTypeString string
Number CellTypeNumber float64
Boolean CellTypeBool bool
Date (detected via style) CellTypeDate time.Time
Empty CellTypeEmpty nil
Leading zeros (phone numbers, zip codes, etc.)

Many XLSX libraries auto-detect numeric-looking strings and store them as numbers, which strips leading zeros. xlsxlite does no auto-type coercion — the Go type determines the cell type directly:

// Safe: stored as a shared string, leading zeros preserved
xlsxlite.MakeRow("0812345678")
xlsxlite.StringCell("00501")

// Unsafe: stored as a number, leading zero is gone
xlsxlite.MakeRow(812345678)
xlsxlite.IntCell(501)

If your value is a string in Go, it stays a string in the XLSX. No surprises.

Styles

Register styles before writing rows. Identical styles are deduplicated automatically.

ss := w.StyleSheet()
id := ss.AddStyle(xlsxlite.Style{
    Font:         &xlsxlite.Font{Name: "Arial", Size: 11, Bold: true, Color: "FF000000"},
    Fill:         &xlsxlite.Fill{Type: "pattern", Pattern: "solid", FgColor: "FFFFFF00"},
    Border:       &xlsxlite.Border{Bottom: xlsxlite.BorderEdge{Style: "thin", Color: "FF000000"}},
    Alignment:    &xlsxlite.Alignment{Horizontal: "center", Vertical: "center", WrapText: true},
    NumberFormat: "yyyy-mm-dd",
})

All style fields are optional — nil pointers and empty strings are omitted. Colors use ARGB hex format (e.g. "FF000000" for black, "FFFFFFFF" for white).

Sheet configuration
xlsxlite.SheetConfig{
    Name:       "My Sheet",
    ColWidths:  map[int]float64{0: 20, 1: 15},  // 0-based col index → width
    MergeCells: []xlsxlite.MergeCell{
        {StartCol: 0, StartRow: 1, EndCol: 3, EndRow: 1}, // cols are 0-based, rows are 1-based
    },
    FreezeRow:  1,  // freeze first N rows
    FreezeCol:  2,  // freeze first N columns
}
Row options
// Custom row height
sw.WriteRow(xlsxlite.Row{
    Cells:  []xlsxlite.Cell{xlsxlite.StringCell("tall row")},
    Height: 30.0, // height in points
})

// Skip row numbers (e.g. for sparse data)
sw.WriteRow(xlsxlite.Row{
    Cells:    []xlsxlite.Cell{xlsxlite.StringCell("row 10")},
    RowIndex: 10, // 1-based, overrides auto-increment
})
Coordinate helpers
xlsxlite.ColIndexToLetter(0)          // "A"
xlsxlite.ColIndexToLetter(26)         // "AA"
xlsxlite.LetterToColIndex("AA")       // 26
xlsxlite.CellRef(0, 1)               // "A1" (0-based col, 1-based row)
xlsxlite.ParseCellRef("B3")          // col=1, row=3, err=nil
xlsxlite.RangeRef(0, 1, 3, 5)        // "A1:D5"
Date helpers
serial := xlsxlite.TimeToExcelSerial(time.Now()) // time.Time → Excel serial number
t := xlsxlite.ExcelSerialToTime(45823)           // Excel serial number → time.Time
File helpers
// Write to disk
w, f, err := xlsxlite.CreateFile("output.xlsx")
defer f.Close()
// ... write sheets ...
w.Close()

// Read from disk
reader, err := xlsxlite.OpenFile("input.xlsx")
defer reader.Close()

Security

xlsxlite includes protections against common attack vectors in XLSX processing:

  • Zip bomb / decompression bomb: All zip entry reads are capped at 256 MB (MaxDecompressedSize)
  • Shared string table DoS: Limited to 10M entries (MaxSharedStrings)
  • Column expansion DoS: Capped at 16,384 columns (MaxColumns, Excel's own limit)
  • XML injection: All user-provided values written to XML attributes are escaped
  • Path traversal: Relationship targets with .. or absolute paths are rejected
  • GCS download size: Capped at 512 MB (MaxGCSDownloadSize)

Benchmarks

Measured on Apple M4 Pro, Go 1.25.0, go test -bench=. -benchmem -count=3 -benchtime=5s:

goos: darwin
goarch: arm64
cpu: Apple M4 Pro

BenchmarkWrite100kRows-12     51    116ms/op     52MB/op     800k allocs/op
BenchmarkRead100kRows-12      19    305ms/op    319MB/op     7.7M allocs/op
BenchmarkWrite1MRows-12        5   1134ms/op    499MB/op     7.0M allocs/op
  • Write 100k rows: 116ms, 52 MB allocations (3 cells per row × 100k rows)
  • Read 100k rows: 305ms, 319 MB allocations (dominated by shared string table)
  • Write 1M rows: 1.13s, 499 MB allocations — scales linearly
  • 100k rows file size: 1.7 MB (compressed ZIP)

What's NOT included (by design)

  • Formula calculation engine
  • Charts, sparklines, pivot tables
  • Images / drawings
  • Encryption / decryption
  • Conditional formatting
  • Data validation
  • Comments / rich text

If you need these features, use a full-featured XLSX library. If you need to stream millions of rows with styling and minimal memory, use xlsxlite.

CLI Tool

A bash script is included for quick inspection of any XLSX file:

./scripts/xlsxread.sh path/to/file.xlsx

Example output:

  File:              data.xlsx
  Open time:         4.7ms
  Sheets:            1

═══ Sheet 0: "ExcelJS sheet" ═══

         [str]      [str]          [str]                                     [num]             [num]
  ─────────────────────────────────────────────────────────────────────────────────────────────────────────
  1      branch_no  branch_name    detail_address                            longitude         latitude
  2      TH_BTH01   TH NONGSA      Ruko kopkarlak no 6, Batam Kota           1.10205262111752  104.075602236687
  3      TH_BTH02   TH BATU AJI    Ruko Cemara Asri Blok BB8 No. 10 Tembesi  1.04129828830344  103.989648220723
  4      TH_BTH03   TH LUBUK BAJA  Jl. Pembangunan Citra Mas Blok A No 8, …  1.13631267303236  104.007846409705
  5      TH_BTH04   TH SEKUPANG    RUKO KHARISMA BUSINESS CENTER BLOK C NO…  1.11091211704821  103.949332371163

  Rows:              537
  Max columns:       5
  Non-empty cells:   2685
  Read time:         5.2ms

  Total elapsed:     10.2ms

It displays a table with column type headers ([str], [num], [bool], [date]), the first 5 sample rows (up to 10 columns, values truncated at 40 chars), followed by summary stats and timing.

Project structure

xlsxlite/
├── types.go              # Core types: Cell, Row, Style, Font, Fill, Border, etc.
├── coords.go             # Coordinate helpers: CellRef, ParseCellRef, ColIndexToLetter
├── helpers.go            # File helpers and cell constructors: OpenFile, MakeRow, etc.
├── reader.go             # Streaming XLSX reader with row iterator
├── writer.go             # Streaming XLSX writer with shared string dedup
├── styles.go             # Style management with deduplication
├── gcs/
│   └── gcs.go            # Google Cloud Storage read/write helpers
├── scripts/
│   └── xlsxread.sh       # Bash script for inspecting XLSX files
├── internal/
│   └── xlsxread/main.go  # Reader tool implementation
├── .github/
│   └── workflows/
│       └── ci.yml        # Lint, test, benchmark, and auto-release on merge
├── xlsxlite_test.go      # Unit tests (55 tests)
└── bench_test.go         # Benchmarks

License

MIT

Documentation

Overview

Package xlsxlite is a lightweight, memory-efficient XLSX read/write library.

Unlike DOM-based libraries that load entire worksheet XML into memory, xlsxlite uses streaming XML parsing (encoding/xml.Decoder) for reading and streaming XML writing for output. This keeps memory usage proportional to a single row rather than the entire file, enabling processing of arbitrarily large spreadsheets.

Design principles:

  • Zero external dependencies (stdlib only)
  • Streaming read via row iterator (cursor pattern)
  • Streaming write via row-by-row flush
  • Shared string table with chunked/indexed access for reads
  • Style support: fonts, fills, borders, alignment, number formats
  • Merge cells, column widths, row heights
  • No formula engine, no charts, no images (keeps it lean)

Index

Constants

View Source
const (
	// MaxColumns is the maximum number of columns supported (Excel's limit: XFD = 16384).
	MaxColumns = 16384
	// MaxSharedStrings is the maximum number of shared strings allowed when reading.
	MaxSharedStrings = 10_000_000
	// MaxDecompressedSize is the maximum decompressed size of any single zip entry (256 MB).
	MaxDecompressedSize = 256 << 20
	// MaxGCSDownloadSize is the maximum size for GCS file downloads (512 MB).
	MaxGCSDownloadSize = 512 << 20
)

Variables

This section is empty.

Functions

func CellRef

func CellRef(col, row int) string

CellRef creates a cell reference like "A1" from 0-based col and 1-based row.

func ColIndexToLetter

func ColIndexToLetter(col int) string

ColIndexToLetter converts a 0-based column index to Excel column letters. 0 → "A", 25 → "Z", 26 → "AA", etc.

func ExcelSerialToTime

func ExcelSerialToTime(serial float64) time.Time

ExcelSerialToTime converts an Excel serial date number back to time.Time. Used internally by the reader to convert numeric cells with date styles.

func LetterToColIndex

func LetterToColIndex(letters string) int

LetterToColIndex converts Excel column letters to a 0-based column index. "A" → 0, "Z" → 25, "AA" → 26, etc.

func ParseCellRef

func ParseCellRef(ref string) (col, row int, err error)

ParseCellRef parses a cell reference like "A1" into a 0-based column index and 1-based row number. Returns an error for invalid references.

func RangeRef

func RangeRef(startCol, startRow, endCol, endRow int) string

RangeRef creates a range reference like "A1:D5" from 0-based column indices and 1-based row numbers.

func TimeToExcelSerial

func TimeToExcelSerial(t time.Time) float64

TimeToExcelSerial converts a time.Time to an Excel serial date number. The serial number represents days since December 30, 1899 (Excel's epoch).

Types

type Alignment

type Alignment struct {
	Horizontal string // "left", "center", "right", "fill", "justify"
	Vertical   string // "top", "center", "bottom"
	WrapText   bool
}

Alignment describes cell alignment.

type Border

type Border struct {
	Left   BorderEdge
	Right  BorderEdge
	Top    BorderEdge
	Bottom BorderEdge
}

Border describes all four borders of a cell.

type BorderEdge

type BorderEdge struct {
	Style string // "thin", "medium", "thick", "dashed", etc.
	Color string // ARGB hex
}

BorderEdge describes one edge of a cell border.

type Cell

type Cell struct {
	Value   any // string, float64, bool, time.Time, or nil
	Type    CellType
	StyleID int // index into the styles table; 0 = default
}

Cell represents a single cell value with optional style. The Value field holds the Go value (string, float64, int, int64, float32, bool, time.Time, or nil). The Type field must match the value's kind. Use the cell constructors (StringCell, NumberCell, etc.) or MakeRow for convenience.

func BoolCell

func BoolCell(v bool) Cell

BoolCell creates a boolean cell.

func DateCell

func DateCell(v any, styleID int) Cell

DateCell creates a date cell with the given style. The styleID should reference a style with a date NumberFormat (e.g. "yyyy-mm-dd") so Excel displays it as a date instead of a raw serial number.

func EmptyCell

func EmptyCell() Cell

EmptyCell returns an empty cell (useful for padding in rows).

func IntCell

func IntCell(v int) Cell

IntCell creates a numeric cell from an int value.

func NumberCell

func NumberCell(v float64) Cell

NumberCell creates a numeric cell from a float64 value.

func StringCell

func StringCell(v string) Cell

StringCell creates a string cell. The value is stored as a shared string in the XLSX file. No type coercion is performed, so leading zeros and numeric-looking strings are preserved as-is.

func StyledCell

func StyledCell(v any, styleID int) Cell

StyledCell creates a cell with a specific style. The cell type is auto-detected from the Go value type: string → CellTypeString, float64/float32/int/int64 → CellTypeNumber, bool → CellTypeBool, anything else → CellTypeEmpty.

type CellType

type CellType int

CellType represents the data type of a cell.

const (
	CellTypeEmpty        CellType = iota // empty or nil cell
	CellTypeString                       // string value (stored as shared string)
	CellTypeNumber                       // numeric value (float64, int, int64, or float32)
	CellTypeBool                         // boolean value
	CellTypeDate                         // date/time value (stored as Excel serial number)
	CellTypeInlineString                 // inline string (not shared)
)

type Fill

type Fill struct {
	Type    string // "pattern" or "none"
	Pattern string // "solid", "gray125", etc.
	FgColor string // ARGB hex
	BgColor string // ARGB hex
}

Fill describes a cell fill/background. Set Type to "pattern" and Pattern to "solid" for a solid color fill. FgColor and BgColor are ARGB hex strings.

type Font

type Font struct {
	Name      string
	Size      float64
	Bold      bool
	Italic    bool
	Underline bool
	Color     string // ARGB hex, e.g. "FF000000"
}

Font describes a font style. All fields are optional; zero values are omitted from the output. Color is an ARGB hex string (e.g. "FF000000" for black).

type MergeCell

type MergeCell struct {
	StartCol int // 0-based column
	StartRow int // 1-based row
	EndCol   int // 0-based column
	EndRow   int // 1-based row
}

MergeCell represents a merged cell range. Columns are 0-based, rows are 1-based (matching Excel conventions).

type Reader

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

Reader reads XLSX files using streaming XML parsing. The shared string table is loaded into memory (unavoidable for random access), but worksheet rows are read one-at-a-time via a streaming XML decoder.

func OpenFile

func OpenFile(path string) (*Reader, error)

OpenFile opens an XLSX file from disk for streaming reading. The caller must call Reader.Close when done to release the underlying file handle.

func OpenReader

func OpenReader(r io.ReaderAt, size int64) (*Reader, error)

OpenReader opens an XLSX file for streaming reading from an io.ReaderAt (e.g. *os.File, *bytes.Reader). It parses the workbook structure, loads the shared string table, and reads style definitions. Use OpenFile for a simpler file-based API.

func (*Reader) Close

func (r *Reader) Close() error

Close releases any resources held by the Reader. If the Reader was created via OpenFile, this closes the underlying file.

func (*Reader) OpenSheet

func (r *Reader) OpenSheet(name string) (*RowIterator, error)

OpenSheet returns a RowIterator for the sheet with the given name. The caller must call RowIterator.Close when done reading.

func (*Reader) OpenSheetByIndex

func (r *Reader) OpenSheetByIndex(index int) (*RowIterator, error)

OpenSheetByIndex returns a RowIterator for the sheet at the given 0-based index. The caller must call RowIterator.Close when done reading.

func (*Reader) SetCloser added in v0.1.3

func (r *Reader) SetCloser(c io.Closer)

SetCloser sets the closer that will be called when Reader.Close is invoked. This is used by helpers (e.g. gcs.OpenFileLowMem) to attach cleanup logic such as deleting temporary files.

func (*Reader) SheetCount

func (r *Reader) SheetCount() int

SheetCount returns the number of sheets.

func (*Reader) SheetNames

func (r *Reader) SheetNames() []string

SheetNames returns the names of all sheets in workbook order.

type Row

type Row struct {
	Cells    []Cell
	Height   float64 // custom row height; 0 = default
	RowIndex int     // 1-based row number
}

Row represents a single row of cells. Set RowIndex to override the auto-incremented row number (1-based). Set Height to apply a custom row height in points.

func MakeRow

func MakeRow(values ...any) Row

MakeRow is a convenience to create a Row from a variadic list of values. Accepted types: string, float64, float32, int, int64, bool, Cell, and nil. Strings are stored as shared strings with no type coercion (leading zeros are preserved). Any other type is converted to a string via fmt.Sprintf.

type RowIterator

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

RowIterator streams rows from a worksheet one at a time. Use Next to advance, Row to get the current row, and Err to check for errors. The caller must call Close when done to release the underlying zip entry reader.

func (*RowIterator) Close

func (it *RowIterator) Close() error

Close releases resources held by the iterator. It is safe to call Close multiple times. After Close, Next will always return false.

func (*RowIterator) Err

func (it *RowIterator) Err() error

Err returns the first error encountered during iteration, or nil if iteration completed successfully.

func (*RowIterator) Next

func (it *RowIterator) Next() bool

Next advances to the next row. Returns false when there are no more rows or an error occurred. After Next returns false, call Err to check for errors.

func (*RowIterator) Row

func (it *RowIterator) Row() *Row

Row returns the current row. Only valid after Next() returns true.

type SheetConfig

type SheetConfig struct {
	Name       string
	ColWidths  map[int]float64 // 0-based col index → width
	MergeCells []MergeCell
	FreezeRow  int // freeze panes: first N rows
	FreezeCol  int // freeze panes: first N cols
}

SheetConfig holds configuration for a worksheet. Pass this to Writer.NewSheet to create a new sheet with the given settings.

type SheetWriter

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

SheetWriter writes rows to a single worksheet in streaming fashion. Rows are flushed immediately on WriteRow, so memory usage is O(1) per row.

func (*SheetWriter) Close

func (sw *SheetWriter) Close() error

Close finalizes the sheet XML (closes sheetData, writes merge cells, etc.). Must be called before creating another sheet or closing the Writer.

func (*SheetWriter) WriteRow

func (sw *SheetWriter) WriteRow(row Row) error

WriteRow writes a single row and immediately flushes it to the zip entry. Rows must be written in sequential order. If Row.RowIndex is set (> 0), it overrides the auto-incremented row number, allowing gaps between rows.

type Style

type Style struct {
	Font         *Font
	Fill         *Fill
	Border       *Border
	Alignment    *Alignment
	NumberFormat string // custom format string, e.g. "yyyy-mm-dd"
}

Style combines font, fill, border, alignment and number format. All fields are optional (nil pointers and empty strings are omitted). Register styles via StyleSheet.AddStyle before writing rows.

type StyleSheet

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

StyleSheet manages Excel styles and generates styles.xml content. Styles in XLSX are composed of 4 independent tables (fonts, fills, borders, numFmts) and a cross-reference table (cellXfs) that combines indices from each.

func NewStyleSheet

func NewStyleSheet() *StyleSheet

NewStyleSheet creates a StyleSheet with the defaults required by Excel: one font (Calibri 11), two fills (none + gray125), one border (empty), and one default cell format. This is called automatically by NewWriter.

func (*StyleSheet) AddStyle

func (ss *StyleSheet) AddStyle(s Style) int

AddStyle registers a Style and returns its 0-based index for use in Cell.StyleID. Identical styles are deduplicated — calling AddStyle with the same parameters multiple times returns the same index.

type Writer

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

Writer creates XLSX files using streaming writes. Rows are flushed to the underlying zip entry immediately, so memory usage stays proportional to a single row regardless of file size.

func CreateFile

func CreateFile(path string) (*Writer, *os.File, error)

CreateFile creates a new XLSX file on disk for streaming writing. Returns the Writer and the underlying os.File. Call Writer.Close() first to finalize the XLSX package, then close the file.

func NewWriter

func NewWriter(w io.Writer) *Writer

NewWriter creates a new streaming XLSX writer that writes to w. Typical workflow: register styles via StyleSheet(), create sheets via NewSheet(), write rows via SheetWriter.WriteRow(), then call Close() to finalize.

func (*Writer) Close

func (w *Writer) Close() error

Close finalizes the entire XLSX package by writing styles, shared strings, workbook, content types, and relationships, then closes the underlying zip writer. All SheetWriters must be closed before calling this method.

func (*Writer) NewSheet

func (w *Writer) NewSheet(config SheetConfig) (*SheetWriter, error)

NewSheet begins a new worksheet. You must call SheetWriter.Close() when done writing rows to this sheet before starting another.

func (*Writer) StyleSheet

func (w *Writer) StyleSheet() *StyleSheet

StyleSheet returns the style sheet for registering styles. Styles must be registered before writing rows that reference them.

Directories

Path Synopsis
gcs module
internal
xlsxread command

Jump to

Keyboard shortcuts

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