table: Tables for terminals
This is a Go module for rendering tables in the terminal.

Features
- โ Headers/footers
- โฉ Text wrapping
- ๐ Auto-merging of cells
- โ Customisable line/border characters
- ๐ Customisable line/border colours
- โฏ Individually enable/disable borders, row lines
- โ Set alignments on a per-column basis, with separate settings for headers/footers
- ๐ Intelligently wrap/pad/measure ANSI coloured input
- ๐ฏ Support for double-width unicode characters
- ๐ Load data from CSV files
Check out the documentation for full features/usage.
Examples
Example: Basic
package main
import (
"os"
"github.com/aquasecurity/table"
)
func main() {
t := table.New(os.Stdout)
t.SetHeaders("ID", "Fruit", "Stock")
t.AddRow("1", "Apple", "14")
t.AddRow("2", "Banana", "88,041")
t.AddRow("3", "Cherry", "342")
t.AddRow("4", "Dragonfruit", "1")
t.Render()
}
Output
โโโโโโฌโโโโโโโโโโโโโโฌโโโโโโโโโ
โ ID โ Fruit โ Stock โ
โโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโค
โ 1 โ Apple โ 14 โ
โโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโค
โ 2 โ Banana โ 88,041 โ
โโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโค
โ 3 โ Cherry โ 342 โ
โโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโค
โ 4 โ Dragonfruit โ 1 โ
โโโโโโดโโโโโโโโโโโโโโดโโโโโโโโโ
Example: No Row Lines
package main
import (
"os"
"github.com/aquasecurity/table"
)
func main() {
t := table.New(os.Stdout)
t.SetRowLines(false)
t.SetHeaders("ID", "Fruit", "Stock")
t.AddRow("1", "Apple", "14")
t.AddRow("2", "Banana", "88,041")
t.AddRow("3", "Cherry", "342")
t.AddRow("4", "Dragonfruit", "1")
t.Render()
}
Output
โโโโโโฌโโโโโโโโโโโโโโฌโโโโโโโโโ
โ ID โ Fruit โ Stock โ
โโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโค
โ 1 โ Apple โ 14 โ
โ 2 โ Banana โ 88,041 โ
โ 3 โ Cherry โ 342 โ
โ 4 โ Dragonfruit โ 1 โ
โโโโโโดโโโโโโโโโโโโโโดโโโโโโโโโ
Example: No Borders
package main
import (
"os"
"github.com/aquasecurity/table"
)
func main() {
t := table.New(os.Stdout)
t.SetBorders(false)
t.SetHeaders("ID", "Fruit", "Stock")
t.AddRow("1", "Apple", "14")
t.AddRow("2", "Banana", "88,041")
t.AddRow("3", "Cherry", "342")
t.AddRow("4", "Dragonfruit", "1")
t.Render()
}
Output
ID โ Fruit โ Stock
โโโโโผโโโโโโโโโโโโโโผโโโโโโโโ
1 โ Apple โ 14
โโโโโผโโโโโโโโโโโโโโผโโโโโโโโ
2 โ Banana โ 88,041
โโโโโผโโโโโโโโโโโโโโผโโโโโโโโ
3 โ Cherry โ 342
โโโโโผโโโโโโโโโโโโโโผโโโโโโโโ
4 โ Dragonfruit โ 1
Example: No Borders Or Row Lines
package main
import (
"os"
"github.com/aquasecurity/table"
)
func main() {
t := table.New(os.Stdout)
t.SetRowLines(false)
t.SetBorders(false)
t.SetHeaders("ID", "Fruit", "Stock")
t.AddRow("1", "Apple", "14")
t.AddRow("2", "Banana", "88,041")
t.AddRow("3", "Cherry", "342")
t.AddRow("4", "Dragonfruit", "1")
t.Render()
}
Output
ID โ Fruit โ Stock
โโโโโผโโโโโโโโโโโโโโผโโโโโโโโ
1 โ Apple โ 14
2 โ Banana โ 88,041
3 โ Cherry โ 342
4 โ Dragonfruit โ 1
Example: Specific Borders
package main
import (
"os"
"github.com/aquasecurity/table"
)
func main() {
t := table.New(os.Stdout)
t.SetRowLines(false)
t.SetBorderLeft(true)
t.SetBorderRight(false)
t.SetBorderTop(true)
t.SetBorderBottom(false)
t.SetHeaders("ID", "Fruit", "Stock")
t.AddRow("1", "Apple", "14")
t.AddRow("2", "Banana", "88,041")
t.AddRow("3", "Cherry", "342")
t.AddRow("4", "Dragonfruit", "1")
t.Render()
}
Output
โโโโโโฌโโโโโโโโโโโโโโฌโโโโโโโโ
โ ID โ Fruit โ Stock
โโโโโโผโโโโโโโโโโโโโโผโโโโโโโโ
โ 1 โ Apple โ 14
โ 2 โ Banana โ 88,041
โ 3 โ Cherry โ 342
โ 4 โ Dragonfruit โ 1
package main
import (
"os"
"github.com/aquasecurity/table"
)
func main() {
t := table.New(os.Stdout)
t.SetHeaders("ID", "Fruit", "Stock")
t.SetFooters("ID", "Fruit", "Stock")
t.AddRow("1", "Apple", "14")
t.AddRow("2", "Banana", "88,041")
t.AddRow("3", "Cherry", "342")
t.AddRow("4", "Dragonfruit", "1")
t.Render()
}
Output
โโโโโโฌโโโโโโโโโโโโโโฌโโโโโโโโโ
โ ID โ Fruit โ Stock โ
โโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโค
โ 1 โ Apple โ 14 โ
โโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโค
โ 2 โ Banana โ 88,041 โ
โโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโค
โ 3 โ Cherry โ 342 โ
โโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโค
โ 4 โ Dragonfruit โ 1 โ
โโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโค
โ ID โ Fruit โ Stock โ
โโโโโโดโโโโโโโโโโโโโโดโโโโโโโโโ
Example: Padding
package main
import (
"os"
"github.com/aquasecurity/table"
)
func main() {
t := table.New(os.Stdout)
t.SetPadding(5)
t.SetHeaders("ID", "Fruit", "Stock")
t.AddRow("1", "Apple", "14")
t.AddRow("2", "Banana", "88,041")
t.AddRow("3", "Cherry", "342")
t.AddRow("4", "Dragonfruit", "1")
t.Render()
}
Output
โโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโ
โ ID โ Fruit โ Stock โ
โโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโค
โ 1 โ Apple โ 14 โ
โโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโค
โ 2 โ Banana โ 88,041 โ
โโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโค
โ 3 โ Cherry โ 342 โ
โโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโค
โ 4 โ Dragonfruit โ 1 โ
โโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโ
Example: Alignment
package main
import (
"os"
"github.com/aquasecurity/table"
)
func main() {
t := table.New(os.Stdout)
t.SetAlignment(table.AlignLeft, table.AlignCenter, table.AlignRight)
t.SetHeaders("ID", "Fruit", "Stock")
t.AddRow("1", "Apple", "14")
t.AddRow("2", "Banana", "88,041")
t.AddRow("3", "Cherry", "342")
t.AddRow("4", "Dragonfruit", "1")
t.Render()
}
Output
โโโโโโฌโโโโโโโโโโโโโโฌโโโโโโโโโ
โ ID โ Fruit โ Stock โ
โโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโค
โ 1 โ Apple โ 14 โ
โโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโค
โ 2 โ Banana โ 88,041 โ
โโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโค
โ 3 โ Cherry โ 342 โ
โโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโค
โ 4 โ Dragonfruit โ 1 โ
โโโโโโดโโโโโโโโโโโโโโดโโโโโโโโโ
Example: Rounded Corners
package main
import (
"os"
"github.com/aquasecurity/table"
)
func main() {
t := table.New(os.Stdout)
t.SetDividers(table.UnicodeRoundedDividers)
t.SetHeaders("ID", "Fruit", "Stock")
t.AddRow("1", "Apple", "14")
t.AddRow("2", "Banana", "88,041")
t.AddRow("3", "Cherry", "342")
t.AddRow("4", "Dragonfruit", "1")
t.Render()
}
Output
โญโโโโโฌโโโโโโโโโโโโโโฌโโโโโโโโโฎ
โ ID โ Fruit โ Stock โ
โโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโค
โ 1 โ Apple โ 14 โ
โโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโค
โ 2 โ Banana โ 88,041 โ
โโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโค
โ 3 โ Cherry โ 342 โ
โโโโโโผโโโโโโโโโโโโโโผโโโโโโโโโค
โ 4 โ Dragonfruit โ 1 โ
โฐโโโโโดโโโโโโโโโโโโโโดโโโโโโโโโฏ
Example: Custom Dividers
package main
import (
"os"
"github.com/aquasecurity/table"
)
func main() {
t := table.New(os.Stdout)
t.SetDividers(table.Dividers{
ALL: "@",
NES: "@",
NSW: "@",
NEW: "@",
ESW: "@",
NE: "@",
NW: "@",
SW: "@",
ES: "@",
EW: "~",
NS: "!",
})
t.SetHeaders("ID", "Fruit", "Stock")
t.AddRow("1", "Apple", "14")
t.AddRow("2", "Banana", "88,041")
t.AddRow("3", "Cherry", "342")
t.AddRow("4", "Dragonfruit", "1")
t.Render()
}
Output
@~~~~@~~~~~~~~~~~~~@~~~~~~~~@
! ID ! Fruit ! Stock !
@~~~~@~~~~~~~~~~~~~@~~~~~~~~@
! 1 ! Apple ! 14 !
@~~~~@~~~~~~~~~~~~~@~~~~~~~~@
! 2 ! Banana ! 88,041 !
@~~~~@~~~~~~~~~~~~~@~~~~~~~~@
! 3 ! Cherry ! 342 !
@~~~~@~~~~~~~~~~~~~@~~~~~~~~@
! 4 ! Dragonfruit ! 1 !
@~~~~@~~~~~~~~~~~~~@~~~~~~~~@
Example: Auto Merge Cells
package main
import (
"os"
"time"
"github.com/aquasecurity/table"
)
func main() {
t := table.New(os.Stdout)
t.SetAutoMerge(true)
t.SetHeaders("System", "Status", "Last Check")
t.AddRow("Life Support", "OK", time.Now().Format(time.Stamp))
t.AddRow("Nuclear Generator", "OK", time.Now().Add(-time.Minute).Format(time.Stamp))
t.AddRow("Weapons Systems", "FAIL", time.Now().Format(time.Stamp))
t.AddRow("Shields", "OK", time.Now().Format(time.Stamp))
t.Render()
}
Output
โโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโฌโโโโโโโโโโโโโโโโโโ
โ System โ Status โ Last Check โ
โโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโโโโโโโโโค
โ Life Support โ OK โ May 13 17:34:32 โ
โโโโโโโโโโโโโโโโโโโโโค โโโโโโโโโโโโโโโโโโโค
โ Nuclear Generator โ โ May 13 17:33:32 โ
โโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโโโโโโโโโค
โ Weapons Systems โ FAIL โ May 13 17:34:32 โ
โโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโค โ
โ Shields โ OK โ โ
โโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโดโโโโโโโโโโโโโโโโโโ
Example: Load Data From Csv
package main
import (
"os"
"github.com/aquasecurity/table"
)
func main() {
f, err := os.Open("./_examples/12-load-data-from-csv/data.csv")
if err != nil {
panic(err)
}
t := table.New(os.Stdout)
if err := t.LoadCSV(f, true); err != nil {
panic(err)
}
t.Render()
}
Output
โโโโโโฌโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Id โ Date โ Message โ
โโโโโโผโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ 1 โ 2022-05-12 โ Hello world! โ
โโโโโโผโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ 2 โ 2022-05-12 โ These messages are loaded from a CSV file. โ
โโโโโโผโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ 3 โ 2022-05-13 โ Incredible! โ
โโโโโโดโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
package main
import (
"os"
"github.com/aquasecurity/table"
)
func main() {
t := table.New(os.Stdout)
t.SetDividers(table.MarkdownDividers)
t.SetBorderTop(false)
t.SetBorderBottom(false)
t.SetRowLines(false)
t.SetHeaders("ID", "Fruit", "Stock")
t.AddRow("1", "Apple", "14")
t.AddRow("2", "Banana", "88,041")
t.AddRow("3", "Cherry", "342")
t.AddRow("4", "Dragonfruit", "1")
t.Render()
}
Output
| ID | Fruit | Stock |
|----|-------------|--------|
| 1 | Apple | 14 |
| 2 | Banana | 88,041 |
| 3 | Cherry | 342 |
| 4 | Dragonfruit | 1 |
package main
import (
"os"
"github.com/aquasecurity/table"
)
func main() {
t := table.New(os.Stdout)
t.SetHeaders("Namespace", "Resource", "Vulnerabilities", "Misconfigurations")
t.AddHeaders("Namespace", "Resource", "Critical", "High", "Medium", "Low", "Unknown", "Critical", "High", "Medium", "Low", "Unknown")
t.SetHeaderColSpans(0, 1, 1, 5, 5)
t.SetAutoMergeHeaders(true)
t.AddRow("default", "Deployment/app", "2", "5", "7", "8", "0", "0", "3", "5", "19", "0")
t.AddRow("default", "Ingress/test", "-", "-", "-", "-", "-", "1", "0", "2", "17", "0")
t.AddRow("default", "Service/test", "0", "0", "0", "1", "0", "3", "0", "4", "9", "0")
t.Render()
}
Output
โโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Namespace โ Resource โ Vulnerabilities โ Misconfigurations โ
โ โ โโโโโโโโโโโโฌโโโโโโโฌโโโโโโโโโฌโโโโโโฌโโโโโโโโโโผโโโโโโโโโโโฌโโโโโโโฌโโโโโโโโโฌโโโโโโฌโโโโโโโโโโค
โ โ โ Critical โ High โ Medium โ Low โ Unknown โ Critical โ High โ Medium โ Low โ Unknown โ
โโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโผโโโโโโโโโผโโโโโโผโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโผโโโโโโโโโผโโโโโโผโโโโโโโโโโค
โ default โ Deployment/app โ 2 โ 5 โ 7 โ 8 โ 0 โ 0 โ 3 โ 5 โ 19 โ 0 โ
โโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโผโโโโโโโโโผโโโโโโผโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโผโโโโโโโโโผโโโโโโผโโโโโโโโโโค
โ default โ Ingress/test โ - โ - โ - โ - โ - โ 1 โ 0 โ 2 โ 17 โ 0 โ
โโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโผโโโโโโโโโผโโโโโโผโโโโโโโโโโผโโโโโโโโโโโผโโโโโโโผโโโโโโโโโผโโโโโโผโโโโโโโโโโค
โ default โ Service/test โ 0 โ 0 โ 0 โ 1 โ 0 โ 3 โ 0 โ 4 โ 9 โ 0 โ
โโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโดโโโโโโโโโโโดโโโโโโโดโโโโโโโโโดโโโโโโดโโโโโโโโโโดโโโโโโโโโโโดโโโโโโโดโโโโโโโโโดโโโโโโดโโโโโโโโโโ
Example: Double-width Unicode
package main
import (
"os"
"github.com/aquasecurity/table"
)
func main() {
t := table.New(os.Stdout)
t.SetHeaders("A", "B", "C")
t.AddRow("๐ฅ unicode ๐ฅ characters ๐ฅ", "2", "3")
t.AddRow("4", "5", "6")
t.Render()
}
Output

Example: ANSI Colours
package main
import (
"os"
"github.com/aquasecurity/table"
"github.com/liamg/tml"
)
func main() {
t := table.New(os.Stdout)
t.SetHeaders("ID", "Fruit", "Stock", "Description")
t.SetHeaderStyle(table.StyleBold)
t.SetLineStyle(table.StyleBlue)
t.SetDividers(table.UnicodeRoundedDividers)
t.AddRow("1", tml.Sprintf("<green>Apple</green>"), "14", tml.Sprintf("An apple is an edible fruit produced by an apple tree (<italic>Malus domestica</italic>). "))
t.AddRow("2", tml.Sprintf("<yellow>Banana</yellow>"), "88,041", "A banana is an elongated, edible fruit - botanically a berry.")
t.AddRow("3", tml.Sprintf("<red>Cherry</red>"), "342", "A cherry is the fruit of many plants of the genus Prunus, and is a fleshy drupe (stone fruit). ")
t.AddRow("4", tml.Sprintf("<magenta>Dragonfruit</magenta>"), "1", "A dragonfruit is the fruit of several different cactus species indigenous to the Americas.")
t.Render()
}
Output
