1# Table
2[](https://pkg.go.dev/github.com/jedib0t/go-pretty/v6/table)
3
4Pretty-print tables into ASCII/Unicode strings.
5
6 - Add Rows one-by-one or as a group (`AppendRow`/`AppendRows`)
7 - Add Header(s) and Footer(s) (`AppendHeader`/`AppendFooter`)
8 - Add a Separator manually after any Row (`AppendSeparator`)
9 - Auto Index Rows (1, 2, 3 ...) and Columns (A, B, C, ...) (`SetAutoIndex`)
10 - Auto Merge
11 - Cells in a Row (`RowConfig.AutoMerge`)
12 - Columns (`ColumnConfig.AutoMerge`)
13 - Limit the length of
14 - Rows (`SetAllowedRowLength`)
15 - Columns (`ColumnConfig.Width*`)
16 - Page results by a specified number of Lines (`SetPageSize`)
17 - Alignment - Horizontal & Vertical
18 - Auto (horizontal) Align (numeric columns aligned Right)
19 - Custom (horizontal) Align per column (`ColumnConfig.Align*`)
20 - Custom (vertical) VAlign per column with multi-line cell support (`ColumnConfig.VAlign*`)
21 - Mirror output to an `io.Writer` (ex. `os.StdOut`) (`SetOutputMirror`)
22 - Sort by one or more Columns (`SortBy`)
23 - Suppress/hide columns with no content (`SuppressEmptyColumns`)
24 - Customizable Cell rendering per Column (`ColumnConfig.Transformer*`)
25 - Hide any columns that you don't want displayed (`ColumnConfig.Hidden`)
26 - Reset Headers/Rows/Footers at will to reuse the same Table Writer (`Reset*`)
27 - Completely customizable styles (`SetStyle`/`Style`)
28 - Many ready-to-use styles: [style.go](style.go)
29 - Colorize Headers/Body/Footers using [../text/color.go](../text/color.go)
30 - Custom text-case for Headers/Body/Footers
31 - Enable separators between each row
32 - Render table without a Border
33 - and a lot more...
34 - Render as:
35 - (ASCII/Unicode) Table
36 - CSV
37 - HTML Table (with custom CSS Class)
38 - Markdown Table
39
40
41```
42+---------------------------------------------------------------------+
43| Game of Thrones +
44+-----+------------+-----------+--------+-----------------------------+
45| # | FIRST NAME | LAST NAME | SALARY | |
46+-----+------------+-----------+--------+-----------------------------+
47| 1 | Arya | Stark | 3000 | |
48| 20 | Jon | Snow | 2000 | You know nothing, Jon Snow! |
49| 300 | Tyrion | Lannister | 5000 | |
50+-----+------------+-----------+--------+-----------------------------+
51| | | TOTAL | 10000 | |
52+-----+------------+-----------+--------+-----------------------------+
53```
54
55A demonstration of all the capabilities can be found here:
56[../cmd/demo-table](../cmd/demo-table)
57
58If you want very specific examples, read ahead.
59
60# Examples
61
62All the examples below are going to start with the following block, although
63nothing except a single Row is mandatory for the `Render()` function to render
64something:
65```golang
66package main
67
68import (
69 "os"
70
71 "github.com/jedib0t/go-pretty/v6/table"
72)
73
74func main() {
75 t := table.NewWriter()
76 t.SetOutputMirror(os.Stdout)
77 t.AppendHeader(table.Row{"#", "First Name", "Last Name", "Salary"})
78 t.AppendRows([]table.Row{
79 {1, "Arya", "Stark", 3000},
80 {20, "Jon", "Snow", 2000, "You know nothing, Jon Snow!"},
81 })
82 t.AppendSeparator()
83 t.AppendRow([]interface{}{300, "Tyrion", "Lannister", 5000})
84 t.AppendFooter(table.Row{"", "", "Total", 10000})
85 t.Render()
86}
87```
88Running the above will result in:
89```
90+-----+------------+-----------+--------+-----------------------------+
91| # | FIRST NAME | LAST NAME | SALARY | |
92+-----+------------+-----------+--------+-----------------------------+
93| 1 | Arya | Stark | 3000 | |
94| 20 | Jon | Snow | 2000 | You know nothing, Jon Snow! |
95+-----+------------+-----------+--------+-----------------------------+
96| 300 | Tyrion | Lannister | 5000 | |
97+-----+------------+-----------+--------+-----------------------------+
98| | | TOTAL | 10000 | |
99+-----+------------+-----------+--------+-----------------------------+
100```
101
102## Styles
103
104You can customize almost every single thing about the table above. The previous
105example just defaulted to `StyleDefault` during `Render()`. You can use a
106ready-to-use style (as in [style.go](style.go)) or customize it as you want.
107
108### Ready-to-use Styles
109
110Table comes with a bunch of ready-to-use Styles that make the table look really
111good. Set or Change the style using:
112```golang
113 t.SetStyle(table.StyleLight)
114 t.Render()
115```
116to get:
117```
118┌─────┬────────────┬───────────┬────────┬─────────────────────────────┐
119│ # │ FIRST NAME │ LAST NAME │ SALARY │ │
120├─────┼────────────┼───────────┼────────┼─────────────────────────────┤
121│ 1 │ Arya │ Stark │ 3000 │ │
122│ 20 │ Jon │ Snow │ 2000 │ You know nothing, Jon Snow! │
123├─────┼────────────┼───────────┼────────┼─────────────────────────────┤
124│ 300 │ Tyrion │ Lannister │ 5000 │ │
125├─────┼────────────┼───────────┼────────┼─────────────────────────────┤
126│ │ │ TOTAL │ 10000 │ │
127└─────┴────────────┴───────────┴────────┴─────────────────────────────┘
128```
129
130Or if you want to use a full-color mode, and don't care for boxes, use:
131```golang
132 t.SetStyle(table.StyleColoredBright)
133 t.Render()
134```
135to get:
136
137<img src="images/table-StyleColoredBright.png" width="640px" alt="Colored Table"/>
138
139### Roll your own Style
140
141You can also roll your own style:
142```golang
143 t.SetStyle(table.Style{
144 Name: "myNewStyle",
145 Box: table.BoxStyle{
146 BottomLeft: "\\",
147 BottomRight: "/",
148 BottomSeparator: "v",
149 Left: "[",
150 LeftSeparator: "{",
151 MiddleHorizontal: "-",
152 MiddleSeparator: "+",
153 MiddleVertical: "|",
154 PaddingLeft: "<",
155 PaddingRight: ">",
156 Right: "]",
157 RightSeparator: "}",
158 TopLeft: "(",
159 TopRight: ")",
160 TopSeparator: "^",
161 UnfinishedRow: " ~~~",
162 },
163 Color: table.ColorOptions{
164 IndexColumn: text.Colors{text.BgCyan, text.FgBlack},
165 Footer: text.Colors{text.BgCyan, text.FgBlack},
166 Header: text.Colors{text.BgHiCyan, text.FgBlack},
167 Row: text.Colors{text.BgHiWhite, text.FgBlack},
168 RowAlternate: text.Colors{text.BgWhite, text.FgBlack},
169 },
170 Format: table.FormatOptions{
171 Footer: text.FormatUpper,
172 Header: text.FormatUpper,
173 Row: text.FormatDefault,
174 },
175 Options: table.Options{
176 DrawBorder: true,
177 SeparateColumns: true,
178 SeparateFooter: true,
179 SeparateHeader: true,
180 SeparateRows: false,
181 },
182 })
183```
184
185Or you can use one of the ready-to-use Styles, and just make a few tweaks:
186```golang
187 t.SetStyle(table.StyleLight)
188 t.Style().Color.Header = text.Colors{text.BgHiCyan, text.FgBlack}
189 t.Style().Color.IndexColumn = text.Colors{text.BgHiCyan, text.FgBlack}
190 t.Style().Format.Footer = text.FormatLower
191 t.Style().Options.DrawBorder = false
192```
193
194## Auto-Merge
195
196You can auto-merge cells horizontally and vertically, but you have request for
197it specifically for each row/column using `RowConfig` or `ColumnConfig`.
198
199```golang
200 rowConfigAutoMerge := table.RowConfig{AutoMerge: true}
201
202 t := table.NewWriter()
203 t.AppendHeader(table.Row{"Node IP", "Pods", "Namespace", "Container", "RCE", "RCE"}, rowConfigAutoMerge)
204 t.AppendHeader(table.Row{"", "", "", "", "EXE", "RUN"})
205 t.AppendRow(table.Row{"1.1.1.1", "Pod 1A", "NS 1A", "C 1", "Y", "Y"}, rowConfigAutoMerge)
206 t.AppendRow(table.Row{"1.1.1.1", "Pod 1A", "NS 1A", "C 2", "Y", "N"}, rowConfigAutoMerge)
207 t.AppendRow(table.Row{"1.1.1.1", "Pod 1A", "NS 1B", "C 3", "N", "N"}, rowConfigAutoMerge)
208 t.AppendRow(table.Row{"1.1.1.1", "Pod 1B", "NS 2", "C 4", "N", "N"}, rowConfigAutoMerge)
209 t.AppendRow(table.Row{"1.1.1.1", "Pod 1B", "NS 2", "C 5", "Y", "N"}, rowConfigAutoMerge)
210 t.AppendRow(table.Row{"2.2.2.2", "Pod 2", "NS 3", "C 6", "Y", "Y"}, rowConfigAutoMerge)
211 t.AppendRow(table.Row{"2.2.2.2", "Pod 2", "NS 3", "C 7", "Y", "Y"}, rowConfigAutoMerge)
212 t.AppendFooter(table.Row{"", "", "", 7, 5, 3})
213 t.SetAutoIndex(true)
214 t.SetColumnConfigs([]table.ColumnConfig{
215 {Number: 1, AutoMerge: true},
216 {Number: 2, AutoMerge: true},
217 {Number: 3, AutoMerge: true},
218 {Number: 4, AutoMerge: true},
219 {Number: 5, Align: text.AlignCenter, AlignFooter: text.AlignCenter, AlignHeader: text.AlignCenter},
220 {Number: 6, Align: text.AlignCenter, AlignFooter: text.AlignCenter, AlignHeader: text.AlignCenter},
221 })
222 t.SetOutputMirror(os.Stdout)
223 t.SetStyle(table.StyleLight)
224 t.Style().Options.SeparateRows = true
225 fmt.Println(t.Render())
226```
227to get:
228```
229┌───┬─────────┬────────┬───────────┬───────────┬───────────┐
230│ │ NODE IP │ PODS │ NAMESPACE │ CONTAINER │ RCE │
231│ │ │ │ │ ├─────┬─────┤
232│ │ │ │ │ │ EXE │ RUN │
233├───┼─────────┼────────┼───────────┼───────────┼─────┴─────┤
234│ 1 │ 1.1.1.1 │ Pod 1A │ NS 1A │ C 1 │ Y │
235├───┤ │ │ ├───────────┼─────┬─────┤
236│ 2 │ │ │ │ C 2 │ Y │ N │
237├───┤ │ ├───────────┼───────────┼─────┴─────┤
238│ 3 │ │ │ NS 1B │ C 3 │ N │
239├───┤ ├────────┼───────────┼───────────┼───────────┤
240│ 4 │ │ Pod 1B │ NS 2 │ C 4 │ N │
241├───┤ │ │ ├───────────┼─────┬─────┤
242│ 5 │ │ │ │ C 5 │ Y │ N │
243├───┼─────────┼────────┼───────────┼───────────┼─────┴─────┤
244│ 6 │ 2.2.2.2 │ Pod 2 │ NS 3 │ C 6 │ Y │
245├───┤ │ │ ├───────────┼───────────┤
246│ 7 │ │ │ │ C 7 │ Y │
247├───┼─────────┼────────┼───────────┼───────────┼─────┬─────┤
248│ │ │ │ │ 7 │ 5 │ 3 │
249└───┴─────────┴────────┴───────────┴───────────┴─────┴─────┘
250```
251
252## Paging
253
254You can limit then number of lines rendered in a single "Page". This logic
255can handle rows with multiple lines too. Here is a simple example:
256```golang
257 t.SetPageSize(1)
258 t.Render()
259```
260to get:
261```
262+-----+------------+-----------+--------+-----------------------------+
263| # | FIRST NAME | LAST NAME | SALARY | |
264+-----+------------+-----------+--------+-----------------------------+
265| 1 | Arya | Stark | 3000 | |
266+-----+------------+-----------+--------+-----------------------------+
267| | | TOTAL | 10000 | |
268+-----+------------+-----------+--------+-----------------------------+
269
270+-----+------------+-----------+--------+-----------------------------+
271| # | FIRST NAME | LAST NAME | SALARY | |
272+-----+------------+-----------+--------+-----------------------------+
273| 20 | Jon | Snow | 2000 | You know nothing, Jon Snow! |
274+-----+------------+-----------+--------+-----------------------------+
275| | | TOTAL | 10000 | |
276+-----+------------+-----------+--------+-----------------------------+
277
278+-----+------------+-----------+--------+-----------------------------+
279| # | FIRST NAME | LAST NAME | SALARY | |
280+-----+------------+-----------+--------+-----------------------------+
281| 300 | Tyrion | Lannister | 5000 | |
282+-----+------------+-----------+--------+-----------------------------+
283| | | TOTAL | 10000 | |
284+-----+------------+-----------+--------+-----------------------------+
285```
286
287## Sorting
288
289Sorting can be done on one or more columns. The following code will make the
290rows be sorted first by "First Name" and then by "Last Name" (in case of similar
291"First Name" entries).
292```golang
293 t.SortBy([]table.SortBy{
294 {Name: "First Name", Mode: table.Asc},
295 {Name: "Last Name", Mode: table.Asc},
296 })
297```
298
299## Wrapping (or) Row/Column Width restrictions
300
301You can restrict the maximum (text) width for a Row:
302```golang
303 t.SetAllowedRowLength(50)
304 t.Render()
305```
306to get:
307```
308+-----+------------+-----------+--------+------- ~
309| # | FIRST NAME | LAST NAME | SALARY | ~
310+-----+------------+-----------+--------+------- ~
311| 1 | Arya | Stark | 3000 | ~
312| 20 | Jon | Snow | 2000 | You kn ~
313+-----+------------+-----------+--------+------- ~
314| 300 | Tyrion | Lannister | 5000 | ~
315+-----+------------+-----------+--------+------- ~
316| | | TOTAL | 10000 | ~
317+-----+------------+-----------+--------+------- ~
318```
319
320## Column Control - Alignment, Colors, Width and more
321
322You can control a lot of things about individual cells/columns which overrides
323global properties/styles using the `SetColumnConfig()` interface:
324- Alignment (horizontal & vertical)
325- Colorization
326- Transform individual cells based on the content
327- Visibility
328- Width (minimum & maximum)
329
330```golang
331 nameTransformer := text.Transformer(func(val interface{}) string {
332 return text.Bold.Sprint(val)
333 })
334
335 t.SetColumnConfigs([]ColumnConfig{
336 {
337 Name: "First Name",
338 Align: text.AlignLeft,
339 AlignFooter: text.AlignLeft,
340 AlignHeader: text.AlignLeft,
341 Colors: text.Colors{text.BgBlack, text.FgRed},
342 ColorsHeader: text.Colors{text.BgRed, text.FgBlack, text.Bold},
343 ColorsFooter: text.Colors{text.BgRed, text.FgBlack},
344 Hidden: false,
345 Transformer: nameTransformer,
346 TransformerFooter: nameTransformer,
347 TransformerHeader: nameTransformer,
348 VAlign: text.VAlignMiddle,
349 VAlignFooter: text.VAlignTop,
350 VAlignHeader: text.VAlignBottom,
351 WidthMin: 6,
352 WidthMax: 64,
353 }
354 })
355```
356
357## Render As ...
358
359Tables can be rendered in other common formats such as:
360
361### ... CSV
362
363```golang
364 t.RenderCSV()
365```
366to get:
367```
368,First Name,Last Name,Salary,
3691,Arya,Stark,3000,
37020,Jon,Snow,2000,"You know nothing\, Jon Snow!"
371300,Tyrion,Lannister,5000,
372,,Total,10000,
373```
374
375### ... HTML Table
376
377```golang
378 t.Style().HTML = table.HTMLOptions{
379 CSSClass: "game-of-thrones",
380 EmptyColumn: " ",
381 EscapeText: true,
382 Newline: "<br/>",
383 }
384 t.RenderHTML()
385```
386to get:
387```html
388<table class="game-of-thrones">
389 <thead>
390 <tr>
391 <th align="right">#</th>
392 <th>First Name</th>
393 <th>Last Name</th>
394 <th align="right">Salary</th>
395 <th> </th>
396 </tr>
397 </thead>
398 <tbody>
399 <tr>
400 <td align="right">1</td>
401 <td>Arya</td>
402 <td>Stark</td>
403 <td align="right">3000</td>
404 <td> </td>
405 </tr>
406 <tr>
407 <td align="right">20</td>
408 <td>Jon</td>
409 <td>Snow</td>
410 <td align="right">2000</td>
411 <td>You know nothing, Jon Snow!</td>
412 </tr>
413 <tr>
414 <td align="right">300</td>
415 <td>Tyrion</td>
416 <td>Lannister</td>
417 <td align="right">5000</td>
418 <td> </td>
419 </tr>
420 </tbody>
421 <tfoot>
422 <tr>
423 <td align="right"> </td>
424 <td> </td>
425 <td>Total</td>
426 <td align="right">10000</td>
427 <td> </td>
428 </tr>
429 </tfoot>
430</table>
431```
432
433### ... Markdown Table
434
435```golang
436 t.RenderMarkdown()
437```
438to get:
439```markdown
440| # | First Name | Last Name | Salary | |
441| ---:| --- | --- | ---:| --- |
442| 1 | Arya | Stark | 3000 | |
443| 20 | Jon | Snow | 2000 | You know nothing, Jon Snow! |
444| 300 | Tyrion | Lannister | 5000 | |
445| | | Total | 10000 | |
446```
View as plain text