The main tablewriter package provides the core table creation and manipulation API, including the Table struct, configuration builders, option functions, and CSV import utilities.
import "github.com/olekukonko/tablewriter"import (
"github.com/olekukonko/tablewriter"
"github.com/olekukonko/tablewriter/tw"
)import (
"os"
"github.com/olekukonko/tablewriter"
"github.com/olekukonko/tablewriter/tw"
)
// Create a basic table
table := tablewriter.NewTable(os.Stdout)
table.Header("Name", "Age", "City")
table.Append("Alice", 30, "NYC")
table.Append("Bob", 25, "LA")
table.Render()Create new table instances with various input sources and configurations.
Creates a new table instance with optional configuration options.
func NewTable(w io.Writer, opts ...Option) *TableParameters:
w io.Writer - Destination for table outputopts ...Option - Variable number of configuration optionsReturns: *Table - Initialized table instance
Example:
// Basic table
table := tablewriter.NewTable(os.Stdout)
// Table with options
table := tablewriter.NewTable(os.Stdout,
tablewriter.WithAutoHide(tw.On),
tablewriter.WithMaxWidth(80),
tablewriter.WithRenderer(renderer.NewBlueprint()),
)Creates a table with default settings (backward compatibility with v0.0.5).
func NewWriter(w io.Writer) *TableParameters:
w io.Writer - Output writerReturns: *Table - Table with default configuration
Creates a table from a CSV file.
func NewCSV(writer io.Writer, fileName string, hasHeader bool, opts ...Option) (*Table, error)Parameters:
writer io.Writer - Output destinationfileName string - Path to CSV filehasHeader bool - Whether CSV has header rowopts ...Option - Configuration optionsReturns:
*Table - Table instance populated with CSV dataerror - Error if file cannot be read or parsedExample:
table, err := tablewriter.NewCSV(os.Stdout, "data.csv", true,
tablewriter.WithAutoHide(tw.On),
)
if err != nil {
log.Fatal(err)
}
table.Render()Creates a table from a CSV reader, allowing customization of CSV parsing.
func NewCSVReader(writer io.Writer, csvReader *csv.Reader, hasHeader bool, opts ...Option) (*Table, error)Parameters:
writer io.Writer - Output destinationcsvReader *csv.Reader - CSV reader instance (from encoding/csv)hasHeader bool - Whether CSV has header rowopts ...Option - Configuration optionsReturns:
*Table - Table instance populated with CSV dataerror - Error if CSV cannot be parsedExample:
file, _ := os.Open("data.csv")
defer file.Close()
csvReader := csv.NewReader(file)
csvReader.Comma = ';' // Custom delimiter
table, err := tablewriter.NewCSVReader(os.Stdout, csvReader, true)
if err != nil {
log.Fatal(err)
}
table.Render()The Table struct provides methods for data manipulation, rendering, and configuration.
Adds data to a single row in the table. Call multiple times to add multiple rows.
func (t *Table) Append(rows ...interface{}) errorParameters:
rows ...interface{} - Variable number of cell values for a single rowReturns: error - Error if data cannot be processed
Example:
table.Append("Alice", 30, "NYC")
table.Append("Bob", 25, "LA")Adds multiple rows from a slice of data. Supports slices of slices, structs, or maps.
func (t *Table) Bulk(rows interface{}) errorParameters:
rows interface{} - Slice of rows (each row can be []string, []interface{}, struct, map, etc.)Returns: error - Error if data cannot be processed
Example:
data := [][]string{
{"Alice", "30", "NYC"},
{"Bob", "25", "LA"},
}
table.Bulk(data)
// Or with structs
type Person struct {
Name string
Age int
City string
}
people := []Person{
{"Alice", 30, "NYC"},
{"Bob", 25, "LA"},
}
table.Bulk(people)Sets table header content.
func (t *Table) Header(elements ...any)Parameters:
elements ...any - Variable number of header cell valuesExample:
table.Header("Name", "Age", "City")Sets table footer content.
func (t *Table) Footer(elements ...any)Parameters:
elements ...any - Variable number of footer cell valuesExample:
table.Footer("Total", "100", "")Triggers table rendering to output.
func (t *Table) Render() errorReturns: error - Error if rendering fails
Example:
if err := table.Render(); err != nil {
log.Fatal(err)
}Starts streaming mode for real-time table rendering.
func (t *Table) Start() errorReturns: error - Error if streaming cannot be initialized
Example:
table := tablewriter.NewTable(os.Stdout,
tablewriter.WithStreaming(tw.StreamConfig{Enable: true}),
)
table.Header("Name", "Age")
table.Start()
table.Append("Alice", 30)
table.Append("Bob", 25)
table.Close()Closes streaming mode and renders footer if present.
func (t *Table) Close() errorReturns: error - Error if closing fails
Clears all data and rendering state from the table.
func (t *Table) Reset()Example:
table.Reset()
// Table is now empty and ready for new dataUpdates configuration via a function callback.
func (t *Table) Configure(fn func(cfg *Config)) *TableParameters:
fn func(cfg *Config) - Function that modifies the configurationReturns: *Table - Table instance for chaining
Example:
table.Configure(func(cfg *tablewriter.Config) {
cfg.MaxWidth = 100
cfg.Debug = true
})Updates table with configuration options.
func (t *Table) Options(opts ...Option) *TableParameters:
opts ...Option - Variable number of configuration optionsReturns: *Table - Table instance for chaining
Example:
table.Options(
tablewriter.WithMaxWidth(80),
tablewriter.WithAutoHide(tw.On),
)Returns current configuration.
func (t *Table) Config() ConfigReturns: Config - Current table configuration
Retrieves current renderer instance.
func (t *Table) Renderer() tw.RendererReturns: tw.Renderer - Current renderer
Retrieves logger instance.
func (t *Table) Logger() *ll.LoggerReturns: *ll.Logger - Logger instance
Retrieves debug trace logs.
func (t *Table) Debug() *bytes.BufferReturns: *bytes.Buffer - Debug trace buffer
Returns total number of lines rendered (requires line counter).
func (t *Table) Lines() intReturns: int - Total lines rendered
Example:
table := tablewriter.NewTable(os.Stdout,
tablewriter.WithLineCounter(),
)
table.Header("Name", "Age")
table.Append("Alice", 30)
table.Render()
fmt.Printf("Total lines: %d\n", table.Lines())Returns all active counter instances.
func (t *Table) Counters() []tw.CounterReturns: []tw.Counter - Slice of counter instances
Sets table caption with positioning (legacy method).
func (t *Table) Caption(caption tw.Caption) *TableParameters:
caption tw.Caption - Caption configurationReturns: *Table - Table instance for chaining
Example:
table.Caption(tw.Caption{
Text: "Employee List",
Spot: tw.SpotBottomCenter,
Align: tw.AlignCenter,
})Trims whitespace from string based on configuration.
func (t *Table) Trimmer(str string) stringParameters:
str string - Input stringReturns: string - Trimmed string
The Config struct and ConfigBuilder provide comprehensive table configuration.
Complete table configuration structure.
type Config struct {
MaxWidth int // Maximum table width
Header tw.CellConfig // Header cell configuration
Row tw.CellConfig // Row cell configuration
Footer tw.CellConfig // Footer cell configuration
Debug bool // Debug logging flag
Stream tw.StreamConfig // Streaming configuration
Behavior tw.Behavior // Behavior settings
Widths tw.CellWidth // Width constraints
Counter tw.Counter // Counter instance
}Fields:
MaxWidth int - Maximum width for entire table (0 = unlimited)Header tw.CellConfig - Complete header cell configurationRow tw.CellConfig - Complete row cell configurationFooter tw.CellConfig - Complete footer cell configurationDebug bool - Enable debug loggingStream tw.StreamConfig - Streaming mode settingsBehavior tw.Behavior - Table behavior settings (auto-hide, trim, etc.)Widths tw.CellWidth - Global and per-column width constraintsCounter tw.Counter - Counter for tracking metricsExample:
cfg := tablewriter.Config{
MaxWidth: 100,
Debug: true,
Behavior: tw.Behavior{
AutoHide: tw.On,
TrimSpace: tw.On,
},
}
table := tablewriter.NewTable(os.Stdout,
tablewriter.WithConfig(cfg),
)Creates a ConfigBuilder with default settings for fluent configuration.
func NewConfigBuilder() *ConfigBuilderReturns: *ConfigBuilder - New config builder instance
Example:
cfg := tablewriter.NewConfigBuilder().
WithMaxWidth(100).
WithDebug(true).
WithAutoHide(tw.On).
Header().
Alignment().WithGlobal(tw.AlignCenter).Build().
Build().
Row().
Alignment().WithGlobal(tw.AlignLeft).Build().
Build().
Build()
table := tablewriter.NewTable(os.Stdout,
tablewriter.WithConfig(cfg),
)Fluent interface builder for Config.
type ConfigBuilder struct {
// Internal state (not exported)
}Methods:
func (b *ConfigBuilder) Build() Config
func (b *ConfigBuilder) Header() *HeaderConfigBuilder
func (b *ConfigBuilder) Row() *RowConfigBuilder
func (b *ConfigBuilder) Footer() *FooterConfigBuilder
func (b *ConfigBuilder) Behavior() *BehaviorConfigBuilder
func (b *ConfigBuilder) ForColumn(col int) *ColumnConfigBuilder
func (b *ConfigBuilder) WithTrimSpace(state tw.State) *ConfigBuilder
func (b *ConfigBuilder) WithDebug(debug bool) *ConfigBuilder
func (b *ConfigBuilder) WithAutoHide(state tw.State) *ConfigBuilder
func (b *ConfigBuilder) WithMaxWidth(width int) *ConfigBuilder
func (b *ConfigBuilder) WithFooterAlignment(align tw.Align) *ConfigBuilder
func (b *ConfigBuilder) WithFooterAutoFormat(autoFormat tw.State) *ConfigBuilder
func (b *ConfigBuilder) WithFooterAutoWrap(autoWrap int) *ConfigBuilder
func (b *ConfigBuilder) WithFooterGlobalPadding(padding tw.Padding) *ConfigBuilder
func (b *ConfigBuilder) WithFooterMaxWidth(maxWidth int) *ConfigBuilder
func (b *ConfigBuilder) WithFooterMergeMode(mergeMode int) *ConfigBuilder // Deprecated
func (b *ConfigBuilder) WithHeaderAlignment(align tw.Align) *ConfigBuilder
func (b *ConfigBuilder) WithHeaderAutoFormat(autoFormat tw.State) *ConfigBuilder
func (b *ConfigBuilder) WithHeaderAutoWrap(autoWrap int) *ConfigBuilder
func (b *ConfigBuilder) WithHeaderGlobalPadding(padding tw.Padding) *ConfigBuilder
func (b *ConfigBuilder) WithHeaderMaxWidth(maxWidth int) *ConfigBuilder
func (b *ConfigBuilder) WithHeaderMergeMode(mergeMode int) *ConfigBuilder // Deprecated
func (b *ConfigBuilder) WithRowAlignment(align tw.Align) *ConfigBuilder
func (b *ConfigBuilder) WithRowAutoFormat(autoFormat tw.State) *ConfigBuilder
func (b *ConfigBuilder) WithRowAutoWrap(autoWrap int) *ConfigBuilder
func (b *ConfigBuilder) WithRowGlobalPadding(padding tw.Padding) *ConfigBuilder
func (b *ConfigBuilder) WithRowMaxWidth(maxWidth int) *ConfigBuilder
func (b *ConfigBuilder) WithRowMergeMode(mergeMode int) *ConfigBuilder // DeprecatedOption functions provide functional configuration for tables. All return Option type.
Control table rendering behavior.
func WithAutoHide(state tw.State) Option
func WithTrimSpace(state tw.State) Option
func WithTrimLine(state tw.State) Option
func WithBehavior(behavior tw.Behavior) Option
func WithDebug(debug bool) OptionExamples:
// Auto-hide empty columns
tablewriter.WithAutoHide(tw.On)
// Trim leading/trailing spaces from cells
tablewriter.WithTrimSpace(tw.On)
// Collapse empty visual lines
tablewriter.WithTrimLine(tw.On)
// Enable debug logging
tablewriter.WithDebug(true)
// Complete behavior configuration
tablewriter.WithBehavior(tw.Behavior{
AutoHide: tw.On,
TrimSpace: tw.On,
TrimLine: tw.On,
})Control column and table widths.
func WithMaxWidth(width int) Option
func WithColumnMax(width int) Option
func WithWidths(width tw.CellWidth) Option
func WithColumnWidths(widths tw.Mapper[int, int]) Option
func WithHeaderMaxWidth(maxWidth int) Option
func WithRowMaxWidth(maxWidth int) Option
func WithFooterMaxWidth(maxWidth int) OptionExamples:
// Set maximum table width
tablewriter.WithMaxWidth(80)
// Set global maximum column width
tablewriter.WithColumnMax(20)
// Set per-column widths
tablewriter.WithColumnWidths(tw.Mapper[int, int]{
0: 15, // Column 0: 15 chars
1: 10, // Column 1: 10 chars
2: 25, // Column 2: 25 chars
})
// Set header cell max width
tablewriter.WithHeaderMaxWidth(30)Configure header appearance and behavior.
func WithHeader(headers []string) Option
func WithHeaderAlignment(align tw.Align) Option
func WithHeaderAutoWrap(wrap int) Option
func WithHeaderAutoFormat(state tw.State) Option
func WithHeaderConfig(config tw.CellConfig) Option
func WithHeaderAlignmentConfig(alignment tw.CellAlignment) Option
func WithHeaderFilter(filter tw.CellFilter) Option
func WithHeaderCallbacks(callbacks tw.CellCallbacks) Option
func WithHeaderPaddingPerColumn(padding []tw.Padding) Option
func WithHeaderControl(control tw.Control) Option
func WithHeaderMergeMode(mergeMode int) Option // Deprecated
func WithHeaderMaxWidth(maxWidth int) OptionExamples:
// Set headers
tablewriter.WithHeader([]string{"Name", "Age", "City"})
// Center align headers
tablewriter.WithHeaderAlignment(tw.AlignCenter)
// Truncate header text if too long
tablewriter.WithHeaderAutoWrap(tw.WrapTruncate)
// Auto-format headers (Title Case)
tablewriter.WithHeaderAutoFormat(tw.On)
// Hide headers
tablewriter.WithHeaderControl(tw.Control{Hide: tw.On})
// Per-column header alignment
tablewriter.WithHeaderAlignmentConfig(tw.CellAlignment{
Global: tw.AlignCenter,
PerColumn: []tw.Align{tw.AlignLeft, tw.AlignCenter, tw.AlignRight},
})Configure row appearance and behavior.
func WithRowAlignment(align tw.Align) Option
func WithRowAutoWrap(wrap int) Option
func WithRowAutoFormat(state tw.State) Option
func WithRowConfig(config tw.CellConfig) Option
func WithRowAlignmentConfig(alignment tw.CellAlignment) Option
func WithRowFilter(filter tw.CellFilter) Option
func WithRowCallbacks(callbacks tw.CellCallbacks) Option
func WithRowPaddingPerColumn(padding []tw.Padding) Option
func WithRowMergeMode(mergeMode int) Option // Deprecated
func WithRowMaxWidth(maxWidth int) OptionExamples:
// Left align rows
tablewriter.WithRowAlignment(tw.AlignLeft)
// Wrap row text normally
tablewriter.WithRowAutoWrap(tw.WrapNormal)
// Per-column row alignment
tablewriter.WithRowAlignmentConfig(tw.CellAlignment{
PerColumn: []tw.Align{tw.AlignLeft, tw.AlignRight, tw.AlignCenter},
})
// Row filter (modify cell content)
tablewriter.WithRowFilter(tw.CellFilter{
Global: func(row []string) []string {
// Convert all cells to uppercase
for i, cell := range row {
row[i] = strings.ToUpper(cell)
}
return row
},
})Configure footer appearance and behavior.
func WithFooter(footers []string) Option
func WithFooterConfig(config tw.CellConfig) Option
func WithFooterAlignmentConfig(alignment tw.CellAlignment) Option
func WithFooterAutoWrap(wrap int) Option
func WithFooterAutoFormat(state tw.State) Option
func WithFooterFilter(filter tw.CellFilter) Option
func WithFooterCallbacks(callbacks tw.CellCallbacks) Option
func WithFooterPaddingPerColumn(padding []tw.Padding) Option
func WithFooterControl(control tw.Control) Option
func WithFooterMergeMode(mergeMode int) Option // Deprecated
func WithFooterMaxWidth(maxWidth int) OptionExamples:
// Set footers
tablewriter.WithFooter([]string{"Total", "150", ""})
// Right align footers
tablewriter.WithFooterAlignmentConfig(tw.CellAlignment{
Global: tw.AlignRight,
})
// Hide footers
tablewriter.WithFooterControl(tw.Control{Hide: tw.On})Configure table rendering and appearance.
func WithRenderer(f tw.Renderer) Option
func WithRendition(rendition tw.Rendition) Option
func WithSymbols(symbols tw.Symbols) Option
func WithPadding(padding tw.Padding) Option
func WithAlignment(alignment tw.Alignment) OptionExamples:
// Use HTML renderer
tablewriter.WithRenderer(renderer.NewHTML())
// Use Markdown renderer
tablewriter.WithRenderer(renderer.NewMarkdown())
// Use Colorized renderer
tablewriter.WithRenderer(renderer.NewColorized())
// Set border symbols
tablewriter.WithSymbols(tw.NewSymbols(tw.StyleRounded))
// Set global padding
tablewriter.WithPadding(tw.Padding{
Left: " ",
Right: " ",
})
// Set per-column alignment
tablewriter.WithAlignment(tw.Alignment{
tw.AlignLeft,
tw.AlignCenter,
tw.AlignRight,
})
// Configure rendition (borders, symbols, settings)
tablewriter.WithRendition(tw.Rendition{
Borders: tw.Border{
Left: tw.On,
Right: tw.On,
Top: tw.On,
Bottom: tw.On,
},
Symbols: tw.NewSymbols(tw.StyleDouble),
})Configure streaming mode for real-time rendering.
func WithStreaming(c tw.StreamConfig) OptionExample:
tablewriter.WithStreaming(tw.StreamConfig{
Enable: true,
StrictColumns: true,
})Configure how data is converted and processed.
func WithStringer(stringer interface{}) Option
func WithStringerCache() Option
func WithStringerCacheCustom(cache twcache.Cache[reflect.Type, reflect.Value]) OptionExamples:
// Custom stringer function
tablewriter.WithStringer(func(v interface{}) string {
return fmt.Sprintf("%v", v)
})
// Enable default stringer cache
tablewriter.WithStringerCache()Configure display width calculations.
func WithEastAsian(state tw.State) Option
func WithLogger(logger *ll.Logger) OptionExamples:
// Enable East Asian width calculations (CJK characters)
tablewriter.WithEastAsian(tw.On)
// Custom logger
tablewriter.WithLogger(customLogger)Track rendering metrics.
func WithCounters(counters ...tw.Counter) Option
func WithLineCounter() OptionExamples:
// Add line counter
tablewriter.WithLineCounter()
// Custom counter
tablewriter.WithCounters(myCustomCounter)Apply complete configuration.
func WithConfig(cfg Config) OptionExample:
cfg := tablewriter.Config{
MaxWidth: 100,
Debug: true,
}
tablewriter.WithConfig(cfg)The following APIs are deprecated and should be replaced with modern alternatives.
func WithBorders(borders tw.Border) Option // Use WithRendition
func WithRendererSettings(settings tw.Settings) Option // Use WithRendition
func WithTableMax(width int) Option // Use WithMaxWidth
func WithCondition(cond *runewidth.Condition) Option // Use WithEastAsianMigration examples:
// Old (deprecated)
tablewriter.WithBorders(tw.Border{Top: tw.On, Bottom: tw.On})
// New (recommended)
tablewriter.WithRendition(tw.Rendition{
Borders: tw.Border{Top: tw.On, Bottom: tw.On},
})
// Old (deprecated)
tablewriter.WithTableMax(80)
// New (recommended)
tablewriter.WithMaxWidth(80)type Behavior = tw.Behavior // Use tw.Behavior directly
type Settings = tw.Settings // Use tw.Settings directlyfunc (b *ConfigBuilder) WithFooterMergeMode(mergeMode int) *ConfigBuilder // Use .Footer().Merging().WithMode()
func (b *ConfigBuilder) WithHeaderMergeMode(mergeMode int) *ConfigBuilder // Use .Header().Merging().WithMode()
func (b *ConfigBuilder) WithRowMergeMode(mergeMode int) *ConfigBuilder // Use .Row().Merging().WithMode()func (ff *FooterFormattingBuilder) WithAlignment(align tw.Align) *FooterFormattingBuilder // Use .Footer().Alignment().WithGlobal()
func (hf *HeaderFormattingBuilder) WithAlignment(align tw.Align) *HeaderFormattingBuilder // Use .Header().Alignment().WithGlobal()
func (rf *RowFormattingBuilder) WithAlignment(align tw.Align) *RowFormattingBuilder // Use .Row().Alignment().WithGlobal()Migration example:
// Old (deprecated)
cfg := tablewriter.NewConfigBuilder().
WithHeaderMergeMode(tw.MergeHorizontal).
Build()
// New (recommended)
cfg := tablewriter.NewConfigBuilder().
Header().
Merging().WithMode(tw.MergeHorizontal).Build().
Build().
Build()Function type for configuring Table instances.
type Option func(target *Table)Main table structure for creating and rendering tables.
type Table struct {
// Internal fields (not exported)
}Exported Methods: See "Table Methods" section above.
Constants are imported from the tw package:
// States
tw.On // Enable feature
tw.Off // Disable feature
tw.Unknown // Default/unset state
// Alignment
tw.AlignLeft // Left align
tw.AlignCenter // Center align
tw.AlignRight // Right align
tw.AlignNone // No alignment
tw.Skip // Skip alignment for column
// Wrapping modes
tw.WrapNone // No wrapping
tw.WrapNormal // Normal word wrapping
tw.WrapTruncate // Truncate with ellipsis
tw.WrapBreak // Break long words
// Merge modes
tw.MergeNone // No merging
tw.MergeVertical // Merge vertically
tw.MergeHorizontal // Merge horizontally
tw.MergeBoth // Merge both directions
tw.MergeHierarchical // Hierarchical merging
// Border styles (via tw.NewSymbols)
tw.StyleASCII
tw.StyleLight
tw.StyleHeavy
tw.StyleDouble
tw.StyleRounded
tw.StyleMarkdown
// ... and 40+ more stylespackage main
import (
"os"
"github.com/olekukonko/tablewriter"
"github.com/olekukonko/tablewriter/renderer"
"github.com/olekukonko/tablewriter/tw"
)
func main() {
// Create table with comprehensive configuration
table := tablewriter.NewTable(os.Stdout,
tablewriter.WithMaxWidth(100),
tablewriter.WithAutoHide(tw.On),
tablewriter.WithTrimSpace(tw.On),
tablewriter.WithRenderer(renderer.NewBlueprint()),
tablewriter.WithSymbols(tw.NewSymbols(tw.StyleRounded)),
tablewriter.WithHeaderAlignment(tw.AlignCenter),
tablewriter.WithHeaderAutoFormat(tw.On),
tablewriter.WithRowAlignment(tw.AlignLeft),
tablewriter.WithRowAutoWrap(tw.WrapNormal),
tablewriter.WithLineCounter(),
tablewriter.WithDebug(false),
)
// Add headers
table.Header("Name", "Age", "City", "Department")
// Add data rows
table.Append("Alice Johnson", 30, "New York", "Engineering")
table.Append("Bob Smith", 25, "Los Angeles", "Marketing")
table.Append("Charlie Brown", 35, "Chicago", "Sales")
// Add footer
table.Footer("Total", "90", "", "")
// Render table
if err := table.Render(); err != nil {
log.Fatal(err)
}
// Get line count
fmt.Printf("\nTotal lines rendered: %d\n", table.Lines())
}