• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

csv2table/H05-Dec-2019-

testdata/H05-Dec-2019-

.gitignoreH A D05-Dec-2019256

.travis.ymlH A D05-Dec-2019109

LICENSE.mdH A D05-Dec-20191 KiB

README.mdH A D05-Dec-201913.6 KiB

csv.goH A D05-Dec-20191.3 KiB

go.modH A D05-Dec-201996

go.sumH A D05-Dec-2019177

table.goH A D05-Dec-201920.6 KiB

table_test.goH A D05-Dec-201939.5 KiB

table_with_color.goH A D05-Dec-20192.5 KiB

util.goH A D05-Dec-20192.2 KiB

wrap.goH A D05-Dec-20192.6 KiB

wrap_test.goH A D05-Dec-20191.4 KiB

README.md

1ASCII Table Writer
2=========
3
4[![Build Status](https://travis-ci.org/olekukonko/tablewriter.png?branch=master)](https://travis-ci.org/olekukonko/tablewriter)
5[![Total views](https://img.shields.io/sourcegraph/rrc/github.com/olekukonko/tablewriter.svg)](https://sourcegraph.com/github.com/olekukonko/tablewriter)
6[![Godoc](https://godoc.org/github.com/olekukonko/tablewriter?status.svg)](https://godoc.org/github.com/olekukonko/tablewriter)
7
8Generate ASCII table on the fly ...  Installation is simple as
9
10    go get github.com/olekukonko/tablewriter
11
12
13#### Features
14- Automatic Padding
15- Support Multiple Lines
16- Supports Alignment
17- Support Custom Separators
18- Automatic Alignment of numbers & percentage
19- Write directly to http , file etc via `io.Writer`
20- Read directly from CSV file
21- Optional row line via `SetRowLine`
22- Normalise table header
23- Make CSV Headers optional
24- Enable or disable table border
25- Set custom footer support
26- Optional identical cells merging
27- Set custom caption
28- Optional reflowing of paragrpahs in multi-line cells.
29
30#### Example   1 - Basic
31```go
32data := [][]string{
33    []string{"A", "The Good", "500"},
34    []string{"B", "The Very very Bad Man", "288"},
35    []string{"C", "The Ugly", "120"},
36    []string{"D", "The Gopher", "800"},
37}
38
39table := tablewriter.NewWriter(os.Stdout)
40table.SetHeader([]string{"Name", "Sign", "Rating"})
41
42for _, v := range data {
43    table.Append(v)
44}
45table.Render() // Send output
46```
47
48##### Output  1
49```
50+------+-----------------------+--------+
51| NAME |         SIGN          | RATING |
52+------+-----------------------+--------+
53|  A   |       The Good        |    500 |
54|  B   | The Very very Bad Man |    288 |
55|  C   |       The Ugly        |    120 |
56|  D   |      The Gopher       |    800 |
57+------+-----------------------+--------+
58```
59
60#### Example 2 - Without Border / Footer / Bulk Append
61```go
62data := [][]string{
63    []string{"1/1/2014", "Domain name", "2233", "$10.98"},
64    []string{"1/1/2014", "January Hosting", "2233", "$54.95"},
65    []string{"1/4/2014", "February Hosting", "2233", "$51.00"},
66    []string{"1/4/2014", "February Extra Bandwidth", "2233", "$30.00"},
67}
68
69table := tablewriter.NewWriter(os.Stdout)
70table.SetHeader([]string{"Date", "Description", "CV2", "Amount"})
71table.SetFooter([]string{"", "", "Total", "$146.93"}) // Add Footer
72table.SetBorder(false)                                // Set Border to false
73table.AppendBulk(data)                                // Add Bulk Data
74table.Render()
75```
76
77##### Output 2
78```
79
80    DATE   |       DESCRIPTION        |  CV2  | AMOUNT
81-----------+--------------------------+-------+----------
82  1/1/2014 | Domain name              |  2233 | $10.98
83  1/1/2014 | January Hosting          |  2233 | $54.95
84  1/4/2014 | February Hosting         |  2233 | $51.00
85  1/4/2014 | February Extra Bandwidth |  2233 | $30.00
86-----------+--------------------------+-------+----------
87                                        TOTAL | $146 93
88                                      --------+----------
89
90```
91
92
93#### Example 3 - CSV
94```go
95table, _ := tablewriter.NewCSV(os.Stdout, "testdata/test_info.csv", true)
96table.SetAlignment(tablewriter.ALIGN_LEFT)   // Set Alignment
97table.Render()
98```
99
100##### Output 3
101```
102+----------+--------------+------+-----+---------+----------------+
103|  FIELD   |     TYPE     | NULL | KEY | DEFAULT |     EXTRA      |
104+----------+--------------+------+-----+---------+----------------+
105| user_id  | smallint(5)  | NO   | PRI | NULL    | auto_increment |
106| username | varchar(10)  | NO   |     | NULL    |                |
107| password | varchar(100) | NO   |     | NULL    |                |
108+----------+--------------+------+-----+---------+----------------+
109```
110
111#### Example 4  - Custom Separator
112```go
113table, _ := tablewriter.NewCSV(os.Stdout, "testdata/test.csv", true)
114table.SetRowLine(true)         // Enable row line
115
116// Change table lines
117table.SetCenterSeparator("*")
118table.SetColumnSeparator("╪")
119table.SetRowSeparator("-")
120
121table.SetAlignment(tablewriter.ALIGN_LEFT)
122table.Render()
123```
124
125##### Output 4
126```
127*------------*-----------*---------*
128╪ FIRST NAME ╪ LAST NAME ╪   SSN   ╪
129*------------*-----------*---------*
130╪ John       ╪ Barry     ╪ 123456  ╪
131*------------*-----------*---------*
132╪ Kathy      ╪ Smith     ╪ 687987  ╪
133*------------*-----------*---------*
134╪ Bob        ╪ McCornick ╪ 3979870 ╪
135*------------*-----------*---------*
136```
137
138#### Example 5 - Markdown Format
139```go
140data := [][]string{
141	[]string{"1/1/2014", "Domain name", "2233", "$10.98"},
142	[]string{"1/1/2014", "January Hosting", "2233", "$54.95"},
143	[]string{"1/4/2014", "February Hosting", "2233", "$51.00"},
144	[]string{"1/4/2014", "February Extra Bandwidth", "2233", "$30.00"},
145}
146
147table := tablewriter.NewWriter(os.Stdout)
148table.SetHeader([]string{"Date", "Description", "CV2", "Amount"})
149table.SetBorders(tablewriter.Border{Left: true, Top: false, Right: true, Bottom: false})
150table.SetCenterSeparator("|")
151table.AppendBulk(data) // Add Bulk Data
152table.Render()
153```
154
155##### Output 5
156```
157|   DATE   |       DESCRIPTION        | CV2  | AMOUNT |
158|----------|--------------------------|------|--------|
159| 1/1/2014 | Domain name              | 2233 | $10.98 |
160| 1/1/2014 | January Hosting          | 2233 | $54.95 |
161| 1/4/2014 | February Hosting         | 2233 | $51.00 |
162| 1/4/2014 | February Extra Bandwidth | 2233 | $30.00 |
163```
164
165#### Example 6  - Identical cells merging
166```go
167data := [][]string{
168  []string{"1/1/2014", "Domain name", "1234", "$10.98"},
169  []string{"1/1/2014", "January Hosting", "2345", "$54.95"},
170  []string{"1/4/2014", "February Hosting", "3456", "$51.00"},
171  []string{"1/4/2014", "February Extra Bandwidth", "4567", "$30.00"},
172}
173
174table := tablewriter.NewWriter(os.Stdout)
175table.SetHeader([]string{"Date", "Description", "CV2", "Amount"})
176table.SetFooter([]string{"", "", "Total", "$146.93"})
177table.SetAutoMergeCells(true)
178table.SetRowLine(true)
179table.AppendBulk(data)
180table.Render()
181```
182
183##### Output 6
184```
185+----------+--------------------------+-------+---------+
186|   DATE   |       DESCRIPTION        |  CV2  | AMOUNT  |
187+----------+--------------------------+-------+---------+
188| 1/1/2014 | Domain name              |  1234 | $10.98  |
189+          +--------------------------+-------+---------+
190|          | January Hosting          |  2345 | $54.95  |
191+----------+--------------------------+-------+---------+
192| 1/4/2014 | February Hosting         |  3456 | $51.00  |
193+          +--------------------------+-------+---------+
194|          | February Extra Bandwidth |  4567 | $30.00  |
195+----------+--------------------------+-------+---------+
196|                                       TOTAL | $146 93 |
197+----------+--------------------------+-------+---------+
198```
199
200
201#### Table with color
202```go
203data := [][]string{
204	[]string{"1/1/2014", "Domain name", "2233", "$10.98"},
205	[]string{"1/1/2014", "January Hosting", "2233", "$54.95"},
206	[]string{"1/4/2014", "February Hosting", "2233", "$51.00"},
207	[]string{"1/4/2014", "February Extra Bandwidth", "2233", "$30.00"},
208}
209
210table := tablewriter.NewWriter(os.Stdout)
211table.SetHeader([]string{"Date", "Description", "CV2", "Amount"})
212table.SetFooter([]string{"", "", "Total", "$146.93"}) // Add Footer
213table.SetBorder(false)                                // Set Border to false
214
215table.SetHeaderColor(tablewriter.Colors{tablewriter.Bold, tablewriter.BgGreenColor},
216	tablewriter.Colors{tablewriter.FgHiRedColor, tablewriter.Bold, tablewriter.BgBlackColor},
217	tablewriter.Colors{tablewriter.BgRedColor, tablewriter.FgWhiteColor},
218	tablewriter.Colors{tablewriter.BgCyanColor, tablewriter.FgWhiteColor})
219
220table.SetColumnColor(tablewriter.Colors{tablewriter.Bold, tablewriter.FgHiBlackColor},
221	tablewriter.Colors{tablewriter.Bold, tablewriter.FgHiRedColor},
222	tablewriter.Colors{tablewriter.Bold, tablewriter.FgHiBlackColor},
223	tablewriter.Colors{tablewriter.Bold, tablewriter.FgBlackColor})
224
225table.SetFooterColor(tablewriter.Colors{}, tablewriter.Colors{},
226	tablewriter.Colors{tablewriter.Bold},
227	tablewriter.Colors{tablewriter.FgHiRedColor})
228
229table.AppendBulk(data)
230table.Render()
231```
232
233#### Table with color Output
234![Table with Color](https://cloud.githubusercontent.com/assets/6460392/21101956/bbc7b356-c0a1-11e6-9f36-dba694746efc.png)
235
236#### Example - 7 Table Cells with Color
237
238Individual Cell Colors from `func Rich` take precedence over Column Colors
239
240```go
241data := [][]string{
242	[]string{"Test1Merge", "HelloCol2 - 1", "HelloCol3 - 1", "HelloCol4 - 1"},
243	[]string{"Test1Merge", "HelloCol2 - 2", "HelloCol3 - 2", "HelloCol4 - 2"},
244	[]string{"Test1Merge", "HelloCol2 - 3", "HelloCol3 - 3", "HelloCol4 - 3"},
245	[]string{"Test2Merge", "HelloCol2 - 4", "HelloCol3 - 4", "HelloCol4 - 4"},
246	[]string{"Test2Merge", "HelloCol2 - 5", "HelloCol3 - 5", "HelloCol4 - 5"},
247	[]string{"Test2Merge", "HelloCol2 - 6", "HelloCol3 - 6", "HelloCol4 - 6"},
248	[]string{"Test2Merge", "HelloCol2 - 7", "HelloCol3 - 7", "HelloCol4 - 7"},
249	[]string{"Test3Merge", "HelloCol2 - 8", "HelloCol3 - 8", "HelloCol4 - 8"},
250	[]string{"Test3Merge", "HelloCol2 - 9", "HelloCol3 - 9", "HelloCol4 - 9"},
251	[]string{"Test3Merge", "HelloCol2 - 10", "HelloCol3 -10", "HelloCol4 - 10"},
252}
253
254table := tablewriter.NewWriter(os.Stdout)
255table.SetHeader([]string{"Col1", "Col2", "Col3", "Col4"})
256table.SetFooter([]string{"", "", "Footer3", "Footer4"})
257table.SetBorder(false)
258
259table.SetHeaderColor(tablewriter.Colors{tablewriter.Bold, tablewriter.BgGreenColor},
260	tablewriter.Colors{tablewriter.FgHiRedColor, tablewriter.Bold, tablewriter.BgBlackColor},
261	tablewriter.Colors{tablewriter.BgRedColor, tablewriter.FgWhiteColor},
262	tablewriter.Colors{tablewriter.BgCyanColor, tablewriter.FgWhiteColor})
263
264table.SetColumnColor(tablewriter.Colors{tablewriter.Bold, tablewriter.FgHiBlackColor},
265	tablewriter.Colors{tablewriter.Bold, tablewriter.FgHiRedColor},
266	tablewriter.Colors{tablewriter.Bold, tablewriter.FgHiBlackColor},
267	tablewriter.Colors{tablewriter.Bold, tablewriter.FgBlackColor})
268
269table.SetFooterColor(tablewriter.Colors{}, tablewriter.Colors{},
270	tablewriter.Colors{tablewriter.Bold},
271	tablewriter.Colors{tablewriter.FgHiRedColor})
272
273colorData1 := []string{"TestCOLOR1Merge", "HelloCol2 - COLOR1", "HelloCol3 - COLOR1", "HelloCol4 - COLOR1"}
274colorData2 := []string{"TestCOLOR2Merge", "HelloCol2 - COLOR2", "HelloCol3 - COLOR2", "HelloCol4 - COLOR2"}
275
276for i, row := range data {
277	if i == 4 {
278		table.Rich(colorData1, []tablewriter.Colors{tablewriter.Colors{}, tablewriter.Colors{tablewriter.Normal, tablewriter.FgCyanColor}, tablewriter.Colors{tablewriter.Bold, tablewriter.FgWhiteColor}, tablewriter.Colors{}})
279		table.Rich(colorData2, []tablewriter.Colors{tablewriter.Colors{tablewriter.Normal, tablewriter.FgMagentaColor}, tablewriter.Colors{}, tablewriter.Colors{tablewriter.Bold, tablewriter.BgRedColor}, tablewriter.Colors{tablewriter.FgHiGreenColor, tablewriter.Italic, tablewriter.BgHiCyanColor}})
280	}
281	table.Append(row)
282}
283
284table.SetAutoMergeCells(true)
285table.Render()
286
287```
288
289##### Table cells with color Output
290![Table cells with Color](https://user-images.githubusercontent.com/9064687/63969376-bcd88d80-ca6f-11e9-9466-c3d954700b25.png)
291
292#### Example 8 - Set table caption
293```go
294data := [][]string{
295    []string{"A", "The Good", "500"},
296    []string{"B", "The Very very Bad Man", "288"},
297    []string{"C", "The Ugly", "120"},
298    []string{"D", "The Gopher", "800"},
299}
300
301table := tablewriter.NewWriter(os.Stdout)
302table.SetHeader([]string{"Name", "Sign", "Rating"})
303table.SetCaption(true, "Movie ratings.")
304
305for _, v := range data {
306    table.Append(v)
307}
308table.Render() // Send output
309```
310
311Note: Caption text will wrap with total width of rendered table.
312
313##### Output 7
314```
315+------+-----------------------+--------+
316| NAME |         SIGN          | RATING |
317+------+-----------------------+--------+
318|  A   |       The Good        |    500 |
319|  B   | The Very very Bad Man |    288 |
320|  C   |       The Ugly        |    120 |
321|  D   |      The Gopher       |    800 |
322+------+-----------------------+--------+
323Movie ratings.
324```
325
326#### Example 8 - Set NoWhiteSpace and TablePadding option
327```go
328data := [][]string{
329    {"node1.example.com", "Ready", "compute", "1.11"},
330    {"node2.example.com", "Ready", "compute", "1.11"},
331    {"node3.example.com", "Ready", "compute", "1.11"},
332    {"node4.example.com", "NotReady", "compute", "1.11"},
333}
334
335table := tablewriter.NewWriter(os.Stdout)
336table.SetHeader([]string{"Name", "Status", "Role", "Version"})
337table.SetAutoWrapText(false)
338table.SetAutoFormatHeaders(true)
339table.SetHeaderAlignment(ALIGN_LEFT)
340table.SetAlignment(ALIGN_LEFT)
341table.SetCenterSeparator("")
342table.SetColumnSeparator("")
343table.SetRowSeparator("")
344table.SetHeaderLine(false)
345table.SetBorder(false)
346table.SetTablePadding("\t") // pad with tabs
347table.SetNoWhiteSpace(true)
348table.AppendBulk(data) // Add Bulk Data
349table.Render()
350```
351
352##### Output 8
353```
354NAME             	STATUS  	ROLE   	VERSION
355node1.example.com	Ready   	compute	1.11
356node2.example.com	Ready   	compute	1.11
357node3.example.com	Ready   	compute	1.11
358node4.example.com	NotReady	compute	1.11
359```
360
361#### Render table into a string
362
363Instead of rendering the table to `io.Stdout` you can also render it into a string. Go 1.10 introduced the `strings.Builder` type which implements the `io.Writer` interface and can therefore be used for this task. Example:
364
365```go
366package main
367
368import (
369    "strings"
370    "fmt"
371
372    "github.com/olekukonko/tablewriter"
373)
374
375func main() {
376    tableString := &strings.Builder{}
377    table := tablewriter.NewWriter(tableString)
378
379    /*
380     * Code to fill the table
381     */
382
383    table.Render()
384
385    fmt.Println(tableString.String())
386}
387```
388
389#### TODO
390- ~~Import Directly from CSV~~  - `done`
391- ~~Support for `SetFooter`~~  - `done`
392- ~~Support for `SetBorder`~~  - `done`
393- ~~Support table with uneven rows~~ - `done`
394- ~~Support custom alignment~~
395- General Improvement & Optimisation
396- `NewHTML` Parse table from HTML
397