GithubHelp home page GithubHelp logo

tablewriter's Introduction

ASCII Table Writer

ci Total views Godoc

Generate ASCII table on the fly ... Installation is simple as

go get github.com/olekukonko/tablewriter

Features

  • Automatic Padding
  • Support Multiple Lines
  • Supports Alignment
  • Support Custom Separators
  • Automatic Alignment of numbers & percentage
  • Write directly to http , file etc via io.Writer
  • Read directly from CSV file
  • Optional row line via SetRowLine
  • Normalise table header
  • Make CSV Headers optional
  • Enable or disable table border
  • Set custom footer support
  • Optional identical cells merging
  • Set custom caption
  • Optional reflowing of paragraphs in multi-line cells.

Example 1 - Basic

data := [][]string{
    []string{"A", "The Good", "500"},
    []string{"B", "The Very very Bad Man", "288"},
    []string{"C", "The Ugly", "120"},
    []string{"D", "The Gopher", "800"},
}

table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"Name", "Sign", "Rating"})

for _, v := range data {
    table.Append(v)
}
table.Render() // Send output
Output 1
+------+-----------------------+--------+
| NAME |         SIGN          | RATING |
+------+-----------------------+--------+
|  A   |       The Good        |    500 |
|  B   | The Very very Bad Man |    288 |
|  C   |       The Ugly        |    120 |
|  D   |      The Gopher       |    800 |
+------+-----------------------+--------+

Example 2 - Without Border / Footer / Bulk Append

data := [][]string{
    []string{"1/1/2014", "Domain name", "2233", "$10.98"},
    []string{"1/1/2014", "January Hosting", "2233", "$54.95"},
    []string{"1/4/2014", "February Hosting", "2233", "$51.00"},
    []string{"1/4/2014", "February Extra Bandwidth", "2233", "$30.00"},
}

table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"Date", "Description", "CV2", "Amount"})
table.SetFooter([]string{"", "", "Total", "$146.93"}) // Add Footer
table.EnableBorder(false)                                // Set Border to false
table.AppendBulk(data)                                // Add Bulk Data
table.Render()
Output 2

    DATE   |       DESCRIPTION        |  CV2  | AMOUNT
-----------+--------------------------+-------+----------
  1/1/2014 | Domain name              |  2233 | $10.98
  1/1/2014 | January Hosting          |  2233 | $54.95
  1/4/2014 | February Hosting         |  2233 | $51.00
  1/4/2014 | February Extra Bandwidth |  2233 | $30.00
-----------+--------------------------+-------+----------
                                        TOTAL | $146 93
                                      --------+----------

Example 3 - CSV

table, _ := tablewriter.NewCSV(os.Stdout, "testdata/test_info.csv", true)
table.SetAlignment(tablewriter.ALIGN_LEFT)   // Set Alignment
table.Render()
Output 3
+----------+--------------+------+-----+---------+----------------+
|  FIELD   |     TYPE     | NULL | KEY | DEFAULT |     EXTRA      |
+----------+--------------+------+-----+---------+----------------+
| user_id  | smallint(5)  | NO   | PRI | NULL    | auto_increment |
| username | varchar(10)  | NO   |     | NULL    |                |
| password | varchar(100) | NO   |     | NULL    |                |
+----------+--------------+------+-----+---------+----------------+

Example 4 - Custom Separator

table, _ := tablewriter.NewCSV(os.Stdout, "testdata/test.csv", true)
table.SetRowLine(true)         // Enable row line

// Change table lines
table.SetCenterSeparator("*")
table.SetColumnSeparator("╪")
table.SetRowSeparator("-")

table.SetAlignment(tablewriter.ALIGN_LEFT)
table.Render()
Output 4
*------------*-----------*---------*
╪ FIRST NAME ╪ LAST NAME ╪   SSN   ╪
*------------*-----------*---------*
╪ John       ╪ Barry     ╪ 123456  ╪
*------------*-----------*---------*
╪ Kathy      ╪ Smith     ╪ 687987  ╪
*------------*-----------*---------*
╪ Bob        ╪ McCornick ╪ 3979870 ╪
*------------*-----------*---------*

Example 5 - Markdown Format

data := [][]string{
	[]string{"1/1/2014", "Domain name", "2233", "$10.98"},
	[]string{"1/1/2014", "January Hosting", "2233", "$54.95"},
	[]string{"1/4/2014", "February Hosting", "2233", "$51.00"},
	[]string{"1/4/2014", "February Extra Bandwidth", "2233", "$30.00"},
}

table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"Date", "Description", "CV2", "Amount"})
table.SetBorders(tablewriter.Border{Left: true, Top: false, Right: true, Bottom: false})
table.SetCenterSeparator("|")
table.AppendBulk(data) // Add Bulk Data
table.Render()
Output 5
|   DATE   |       DESCRIPTION        | CV2  | AMOUNT |
|----------|--------------------------|------|--------|
| 1/1/2014 | Domain name              | 2233 | $10.98 |
| 1/1/2014 | January Hosting          | 2233 | $54.95 |
| 1/4/2014 | February Hosting         | 2233 | $51.00 |
| 1/4/2014 | February Extra Bandwidth | 2233 | $30.00 |

Example 6 - Identical cells merging

data := [][]string{
  []string{"1/1/2014", "Domain name", "1234", "$10.98"},
  []string{"1/1/2014", "January Hosting", "2345", "$54.95"},
  []string{"1/4/2014", "February Hosting", "3456", "$51.00"},
  []string{"1/4/2014", "February Extra Bandwidth", "4567", "$30.00"},
}

table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"Date", "Description", "CV2", "Amount"})
table.SetFooter([]string{"", "", "Total", "$146.93"})
table.SetAutoMergeCells(true)
table.SetRowLine(true)
table.AppendBulk(data)
table.Render()
Output 6
+----------+--------------------------+-------+---------+
|   DATE   |       DESCRIPTION        |  CV2  | AMOUNT  |
+----------+--------------------------+-------+---------+
| 1/1/2014 | Domain name              |  1234 | $10.98  |
+          +--------------------------+-------+---------+
|          | January Hosting          |  2345 | $54.95  |
+----------+--------------------------+-------+---------+
| 1/4/2014 | February Hosting         |  3456 | $51.00  |
+          +--------------------------+-------+---------+
|          | February Extra Bandwidth |  4567 | $30.00  |
+----------+--------------------------+-------+---------+
|                                       TOTAL | $146 93 |
+----------+--------------------------+-------+---------+

Example 7 - Identical cells merging (specify the column index to merge)

data := [][]string{
  []string{"1/1/2014", "Domain name", "1234", "$10.98"},
  []string{"1/1/2014", "January Hosting", "1234", "$10.98"},
  []string{"1/4/2014", "February Hosting", "3456", "$51.00"},
  []string{"1/4/2014", "February Extra Bandwidth", "4567", "$30.00"},
}

table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"Date", "Description", "CV2", "Amount"})
table.SetFooter([]string{"", "", "Total", "$146.93"})
table.SetAutoMergeCellsByColumnIndex([]int{2, 3})
table.SetRowLine(true)
table.AppendBulk(data)
table.Render()
Output 7
+----------+--------------------------+-------+---------+
|   DATE   |       DESCRIPTION        |  CV2  | AMOUNT  |
+----------+--------------------------+-------+---------+
| 1/1/2014 | Domain name              |  1234 | $10.98  |
+----------+--------------------------+       +         +
| 1/1/2014 | January Hosting          |       |         |
+----------+--------------------------+-------+---------+
| 1/4/2014 | February Hosting         |  3456 | $51.00  |
+----------+--------------------------+-------+---------+
| 1/4/2014 | February Extra Bandwidth |  4567 | $30.00  |
+----------+--------------------------+-------+---------+
|                                       TOTAL | $146.93 |
+----------+--------------------------+-------+---------+

Table with color

data := [][]string{
	[]string{"1/1/2014", "Domain name", "2233", "$10.98"},
	[]string{"1/1/2014", "January Hosting", "2233", "$54.95"},
	[]string{"1/4/2014", "February Hosting", "2233", "$51.00"},
	[]string{"1/4/2014", "February Extra Bandwidth", "2233", "$30.00"},
}

table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"Date", "Description", "CV2", "Amount"})
table.SetFooter([]string{"", "", "Total", "$146.93"}) // Add Footer
table.EnableBorder(false)                                // Set Border to false

table.SetHeaderColor(tablewriter.Colors{tablewriter.Bold, tablewriter.BgGreenColor},
	tablewriter.Colors{tablewriter.FgHiRedColor, tablewriter.Bold, tablewriter.BgBlackColor},
	tablewriter.Colors{tablewriter.BgRedColor, tablewriter.FgWhiteColor},
	tablewriter.Colors{tablewriter.BgCyanColor, tablewriter.FgWhiteColor})

table.SetColumnColor(tablewriter.Colors{tablewriter.Bold, tablewriter.FgHiBlackColor},
	tablewriter.Colors{tablewriter.Bold, tablewriter.FgHiRedColor},
	tablewriter.Colors{tablewriter.Bold, tablewriter.FgHiBlackColor},
	tablewriter.Colors{tablewriter.Bold, tablewriter.FgBlackColor})

table.SetFooterColor(tablewriter.Colors{}, tablewriter.Colors{},
	tablewriter.Colors{tablewriter.Bold},
	tablewriter.Colors{tablewriter.FgHiRedColor})

table.AppendBulk(data)
table.Render()

Table with color Output

Table with Color

Example - 8 Table Cells with Color

Individual Cell Colors from func Rich take precedence over Column Colors

data := [][]string{
	[]string{"Test1Merge", "HelloCol2 - 1", "HelloCol3 - 1", "HelloCol4 - 1"},
	[]string{"Test1Merge", "HelloCol2 - 2", "HelloCol3 - 2", "HelloCol4 - 2"},
	[]string{"Test1Merge", "HelloCol2 - 3", "HelloCol3 - 3", "HelloCol4 - 3"},
	[]string{"Test2Merge", "HelloCol2 - 4", "HelloCol3 - 4", "HelloCol4 - 4"},
	[]string{"Test2Merge", "HelloCol2 - 5", "HelloCol3 - 5", "HelloCol4 - 5"},
	[]string{"Test2Merge", "HelloCol2 - 6", "HelloCol3 - 6", "HelloCol4 - 6"},
	[]string{"Test2Merge", "HelloCol2 - 7", "HelloCol3 - 7", "HelloCol4 - 7"},
	[]string{"Test3Merge", "HelloCol2 - 8", "HelloCol3 - 8", "HelloCol4 - 8"},
	[]string{"Test3Merge", "HelloCol2 - 9", "HelloCol3 - 9", "HelloCol4 - 9"},
	[]string{"Test3Merge", "HelloCol2 - 10", "HelloCol3 -10", "HelloCol4 - 10"},
}

table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"Col1", "Col2", "Col3", "Col4"})
table.SetFooter([]string{"", "", "Footer3", "Footer4"})
table.EnableBorder(false)

table.SetHeaderColor(tablewriter.Colors{tablewriter.Bold, tablewriter.BgGreenColor},
	tablewriter.Colors{tablewriter.FgHiRedColor, tablewriter.Bold, tablewriter.BgBlackColor},
	tablewriter.Colors{tablewriter.BgRedColor, tablewriter.FgWhiteColor},
	tablewriter.Colors{tablewriter.BgCyanColor, tablewriter.FgWhiteColor})

table.SetColumnColor(tablewriter.Colors{tablewriter.Bold, tablewriter.FgHiBlackColor},
	tablewriter.Colors{tablewriter.Bold, tablewriter.FgHiRedColor},
	tablewriter.Colors{tablewriter.Bold, tablewriter.FgHiBlackColor},
	tablewriter.Colors{tablewriter.Bold, tablewriter.FgBlackColor})

table.SetFooterColor(tablewriter.Colors{}, tablewriter.Colors{},
	tablewriter.Colors{tablewriter.Bold},
	tablewriter.Colors{tablewriter.FgHiRedColor})

colorData1 := []string{"TestCOLOR1Merge", "HelloCol2 - COLOR1", "HelloCol3 - COLOR1", "HelloCol4 - COLOR1"}
colorData2 := []string{"TestCOLOR2Merge", "HelloCol2 - COLOR2", "HelloCol3 - COLOR2", "HelloCol4 - COLOR2"}

for i, row := range data {
	if i == 4 {
		table.Rich(colorData1, []tablewriter.Colors{tablewriter.Colors{}, tablewriter.Colors{tablewriter.Normal, tablewriter.FgCyanColor}, tablewriter.Colors{tablewriter.Bold, tablewriter.FgWhiteColor}, tablewriter.Colors{}})
		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}})
	}
	table.Append(row)
}

table.SetAutoMergeCells(true)
table.Render()
Table cells with color Output

Table cells with Color

Example 9 - Set table caption

data := [][]string{
    []string{"A", "The Good", "500"},
    []string{"B", "The Very very Bad Man", "288"},
    []string{"C", "The Ugly", "120"},
    []string{"D", "The Gopher", "800"},
}

table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"Name", "Sign", "Rating"})
table.SetCaption(true, "Movie ratings.")

for _, v := range data {
    table.Append(v)
}
table.Render() // Send output

Note: Caption text will wrap with total width of rendered table.

Output 9
+------+-----------------------+--------+
| NAME |         SIGN          | RATING |
+------+-----------------------+--------+
|  A   |       The Good        |    500 |
|  B   | The Very very Bad Man |    288 |
|  C   |       The Ugly        |    120 |
|  D   |      The Gopher       |    800 |
+------+-----------------------+--------+
Movie ratings.

Example 10 - Set NoWhiteSpace and TablePadding option

data := [][]string{
    {"node1.example.com", "Ready", "compute", "1.11"},
    {"node2.example.com", "Ready", "compute", "1.11"},
    {"node3.example.com", "Ready", "compute", "1.11"},
    {"node4.example.com", "NotReady", "compute", "1.11"},
}

table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"Name", "Status", "Role", "Version"})
table.SetAutoWrapText(false)
table.SetAutoFormatHeaders(true)
table.SetHeaderAlignment(tablewriter.ALIGN_LEFT)
table.SetAlignment(tablewriter.ALIGN_LEFT)
table.SetCenterSeparator("")
table.SetColumnSeparator("")
table.SetRowSeparator("")
table.SetHeaderLine(false)
table.EnableBorder(false)
table.SetTablePadding("\t") // pad with tabs
table.SetNoWhiteSpace(true)
table.AppendBulk(data) // Add Bulk Data
table.Render()
Output 10
NAME             	STATUS  	ROLE   	VERSION 
node1.example.com	Ready   	compute	1.11   	
node2.example.com	Ready   	compute	1.11   	
node3.example.com	Ready   	compute	1.11   	
node4.example.com	NotReady	compute	1.11   	

Render table into a string

Instead 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:

package main

import (
    "strings"
    "fmt"

    "github.com/olekukonko/tablewriter"
)

func main() {
    tableString := &strings.Builder{}
    table := tablewriter.NewWriter(tableString)

    /*
     * Code to fill the table
     */

    table.Render()

    fmt.Println(tableString.String())
}

TODO

  • Import Directly from CSV - done
  • Support for SetFooter - done
  • Support for SetBorder - done
  • Support table with uneven rows - done
  • Support custom alignment
  • General Improvement & Optimisation
  • NewHTML Parse table from HTML

tablewriter's People

Contributors

adrdev10 avatar agentydragon avatar ansrivas avatar asellappen avatar ashmckenzie avatar chyroc avatar crackcomm avatar csababa avatar damilola-bello avatar eryx avatar hellerve avatar johejo avatar keronsen avatar knqyf263 avatar knz avatar ldmberman avatar mattn avatar mitsuwa avatar mmatczuk avatar mvo5 avatar olekukonko avatar pwaller avatar sanketsudake avatar shreddedbacon avatar sylr avatar szyn avatar tamird avatar tobstarr avatar wakeuptsai avatar yageek avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tablewriter's Issues

Trouble using SetColumnAlignment

Hi all,

I have a table and am trying to set column alignments as follows:

table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"Sym", "Latest", "Open", "Close", "Change", "%Change", "Vol (m)", "Time"})

table.SetColumnAlignment([]int{tablewriter.ALIGN_RIGHT, tablewriter.ALIGN_RIGHT, tablewriter.ALIGN_RIGHT, tablewriter.ALIGN_RIGHT, tablewriter.ALIGN_RIGHT, tablewriter.ALIGN_RIGHT, tablewriter.ALIGN_RIGHT})

but it doesn't seem to be having any effect. (The reason this is important is that I've got color-coded numbers that are being left-justified and I really want them right justified.)

Any ideas on what I'm doing wrong?

Missing comma in footer for float values

Hi,

When I print a float value in a footer, comma just disappears. You have exact same trouble in Output 2 of your README : https://github.com/olekukonko/tablewriter/blob/master/README.md#output-2

    DATE   |       DESCRIPTION        |  CV2  | AMOUNT
+----------+--------------------------+-------+---------+
  1/1/2014 | Domain name              |  2233 | $10.98
  1/1/2014 | January Hosting          |  2233 | $54.95
  1/4/2014 | February Hosting         |  2233 | $51.00
  1/4/2014 | February Extra Bandwidth |  2233 | $30.00
+----------+--------------------------+-------+---------+
                                        TOTAL | $146 93
                                      +-------+---------+]

Regards,

Feature request: enable newlines within a cell

hi,

I have this use case where I need to list several things in a cell like so:

- item1
- item2
- item3

because it belongs to one row.

are there any plans to implement newlines within a cell?

Request: Ability to override SPACE character

It would cool if the SPACE character were overridable so that you could use it for really tight formatting. Currently, when the border is turned off, you still get non-printing characters on each side of the far left and far right columns.

Request: colspan support

Please consider adding the ability to create a table with rows that spans multiple columns like this:

+-----+-------------------------------+------------+
|  #  |             TITLE             |    DATE    |
+-----+-------------------------------+------------+
| 999 | This a column in a single row | 2014-03-07 |
+-----+-------------------------------+------------+
| This is a row that spans multiple columns        |
+-----+-------------------------------+------------+

Sorting by row?

Hello!

Loving using this, except I'd like to sort by a column in a row. Now I'm a golang noob, so it may just be how I'm approaching it. But once I've done a table.AppendBulk(foo) it would be nice to be able to call table.SortRowHEADER) so all the data under that particular header is how the table is sorted.

Using your example to demonstrate:

Example 2 - Without Border / Footer / Bulk Append

data := [][]string{
    []string{"1/1/2014", "Domain name", "2233", "$10.98"},
    []string{"1/1/2014", "January Hosting", "2233", "$54.95"},
    []string{"1/4/2014", "February Hosting", "2233", "$51.00"},
    []string{"1/4/2014", "February Extra Bandwidth", "2233", "$30.00"},
}

table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"Date", "Description", "CV2", "Amount"})
table.SetFooter([]string{"", "", "Total", "$146.93"}) // Add Footer
table.SetBorder(false)                                // Set Border to false
table.AppendBulk(data)                                // Add Bulk Data
PROPOSED ====> table.SortRow("Description")           // Sort by the data in Description
table.Render()
Output 2

    DATE   |       DESCRIPTION        |  CV2  | AMOUNT
+----------+--------------------------+-------+---------+
  1/1/2014 | Domain name              |  2233 | $10.98
  1/4/2014 | February Extra Bandwidth |  2233 | $30.00
  1/4/2014 | February Hosting         |  2233 | $51.00
  1/1/2014 | January Hosting          |  2233 | $54.95
+----------+--------------------------+-------+---------+
                                        TOTAL | $146 93
                                      +-------+---------+

instead of

    DATE   |       DESCRIPTION        |  CV2  | AMOUNT
+----------+--------------------------+-------+---------+
  1/1/2014 | Domain name              |  2233 | $10.98
  1/1/2014 | January Hosting          |  2233 | $54.95
  1/4/2014 | February Hosting         |  2233 | $51.00
  1/4/2014 | February Extra Bandwidth |  2233 | $30.00
+----------+--------------------------+-------+---------+
                                        TOTAL | $146 93
                                      +-------+---------+

This could be done by Date, CV2 or even Amount. I'm not experienced enough to provide a PR quite yet, but was wondering if this was on your list of things todo™ or is this doable with golang's sort.Strings() in a way that I as of yet haven't been able to figure out?

Thanks :)

feature request: an alternative to Append which does not trim spaces

If a value inserted in a table contains spaces at the beginning or at the end this is currently stripped by Append. This is inconvenient if the client app is trying to use white space to show something useful, for example indentation in source code with one line per row.

To address this there should be a flag to Append or a new API AppendRaw which does not trim the argument.

Non-ascii characters not printed well

Some characters not in the ASCII set occupies more than one space when printed in the console, so the resulting output table may not appear elegant if some of the rows contain non-ASCII content.

Left or Right-aligned Headers

I noticed that that the headers are only CENTERED-aligned.
I want to be able to LEFT-aligned my headers. How do I do that?
Even if I set t.SetAutoFormatHeaders(false), its still CENTER-aligned.

Support bool type

Hi,
If a bool type is present, <bool Value> appears, instead of the actual value (I would expect True or False to appear)

Flush

Wondering how I can stream a table to the console, instead of building the whole thing and calling Render...

how can I add multiple footer for summary of multiple things

I just found that I am able to get the first footer row displayed though I have set a few footer. Is it possible I could set a few footer?


	t.SetHeader([]string{"Title", "Description", "Code", "Error"})
	t.SetFooter([]string{"", "", "Total Ok:", ""})
	t.SetFooter([]string{"", "", "Total Failed:", ""})

Request: Render() Option - Continually Overwrite Previous Output

Request functionality for table output to render on-top of previous in terminal.

Use case example would be to display a table of polled metrics refreshed in each iteration of a for{} loop.

This would be best implemented in the API as a flag to Render() which would set the \r option in any calls to fmt.Printf().

README documenting missing features

The README has an example for table colour formatting, where it includes the following snippet as a code example:

/// ... excerpt only, for brevity
table.SetHeaderAttributes(tablewriter.Add(tablewriter.Bold, tablewriter.BgGreenColor),
			  tablewriter.Add(tablewriter.FgHiRedColor, tablewriter.Bold, tablewriter.BgBlackColor),
			  tablewriter.Add(tablewriter.BgRedColor, tablewriter.FgWhiteColor),
			  tablewriter.Add(tablewriter.BgCyanColor, tablewriter.FgWhiteColor))

table.SetColumnAttributes(tablewriter.Add(tablewriter.Bold, tablewriter.FgHiBlackColor),
			  tablewriter.Add(tablewriter.Bold, tablewriter.FgHiRedColor),
			  tablewriter.Add(tablewriter.Bold, tablewriter.FgHiBlackColor),
			  tablewriter.Add(tablewriter.Bold, tablewriter.FgBlackColor))

However when using the code my IDE warns me that SetColumnAttributes does not exist, and indeed I can't see it in the source code. Is this an upcoming feature that is not yet available?

ANSI colours

Using ANSI colour codes in the header strings appears to mess up, i assume, the width calculations. Colour codes in the border strings and row columns appears to be fine.

Broken autoWrapText

I have 3 columns table as follows, the 3rd column may have multiple lines long text.
image
But when text is long or terminal window shrink, it appears as:
image

I had default table setting (which turned autowrap on).
Why it looks like that? How can I fix it to always auto wrap the 3rd column so it won't cause all other rows being affected?

Rendering failed with go 1.3

We have tests failing after upgrading to go 1.3:

dependencies_test.go:66: Expected ouput:
+---------------+--------------+--------+--------+------------+
| DEPENDENCIES  | REQUIREMENTS | LOCKED | STATUS | ADVISORIES |
+---------------+--------------+--------+--------+------------+
| gemnasium-gem | >=1.0.0      |        | green  |            |
| rails         | =3.1.12      |        | red    |            |
+---------------+--------------+--------+--------+------------+


Got:
+--------------+--------+--------+------------+---------------+
| DEPENDENCIES  | REQUIREMENTS | LOCKED | STATUS | ADVISORIES |
+--------+--------+------------+---------------+--------------+
| gemnasium-gem | >=1.0.0      |        | green  |            |
| rails         | =3.1.12      |        | red    |            |
+--------+------------+---------------+--------------+--------+

It works fine with go 1.2.2

Thanks

The table is not formatted correctly when accented characters are used (UTF-8)

This issue was spotted in LXD, but isn't specific to it.

When fields in the table contain accented characters or other special characters, the table is not formatted correctly.
This is in a Linux terminal, with UTF-8.

Example result of an lxc command (in Portuguese):

$ lxc image list
+--------+--------------------+----------+-----------------------------------------------+--------+----------+------------------------------+
| ALIAS  | IMPRESSÃO DIGITAL | PÚBLICO |                  DESCRIÇÃO                  |  ARCH  | TAMANHO  |         UPLOAD DATE          |
+--------+--------------------+----------+-----------------------------------------------+--------+----------+------------------------------+
| xenial | d23ee1f4fd28       | não     | ubuntu 16.04 LTS amd64 (release) (20160516.1) | x86_64 | 138.85MB | May 26, 2016 at 8:04pm (UTC) |
+--------+--------------------+----------+-----------------------------------------------+--------+----------+------------------------------+

Notice that several | characters are not aligned.

Accented and special characters in UTF-8 span multiple chars/bytes.
You should take that into account when calculating the length of strings to display them (according to the utf8 manpage, just count all chars whose most significant bits are not 10).

RFE Automerge per column

Hi, thanks for the great library :).

I think it would be very useful the possibility to do the automerge only with some columns instead of them all.

Thanks again for the great library!

trim line space

my application list files using tablewriter, here is the output.

   2               -  2018-05-06 16:09:44  archive/                   \n

there are many space between "archive/" and “\n" new line, which hinders me to use with xargs like " BaiduPCS-Go ls / |xargs -I '{}' BaiduPCS-Go download --save {}".
so I want to trim line end whitespace.

   2               -  2018-05-06 16:09:44  archive/\n

Contributors Needed

Hello,

Have been busy with so many projects lately and don't have time to update this project. I will appreciate if dedicated like minds who understand and use this lib can offer their assistance.

Thanks
Oleku

SetCaption function seems inconsistent

Hi

Although the SetCaption function specifies the actual text as a variadic argument, only the first element is actually used/displayed due to the IF test in the actual function, and if there is more than one element the entire captionText arg is ignored. Is this deliberate?

func (t *Table) SetCaption(caption bool, captionText ...string) {
	t.caption = caption
	if len(captionText) == 1 {
		t.captionText = captionText[0]
	}
}

csv output

Is there a way to write csv as output file ?

Tree View

The library is called tablewriter but I'd like to view something in a tree or a graph on terminal - can this be done? is this coming anytime soon?

Make uppercase header formatting optional?

Thank you for working on this library! It was really easy to set up and use.

I'm wondering if you have any thoughts on making the headers formatting optional? I'm working on a command line tool to display the contents of our data store on appstax.com, and as the column names are case sensitive, it's a bit misleading to show the headers in all caps.

Let me know what you think. I can take a look myself and send you a pull request if you'd like that.

Allow arbitrary separators

It would be good if we allowed the insertion of arbitrary separators so that data in the table can be grouped.

The row formatter / column width computation should handle tabs gracefully

so we're using tablewriter over here at CockroachDB (thanks for your work!) and we're trying to format our schema definition statements inside table cells. These contain only ASCII with newlines, spaces and... tabs.

Right now if the row data contains tab characters the tabs are printed-as is and cause misalignments.

The row formatter should either replace tabs with spaces or adjust the row width computation based on tabs (and tab positions). Ideally tabs should stay properly aligned across multiple rows; and thus the code should keep track of tab stops.

For now we're working around the issue on our side ( cockroachdb/cockroach#7048 ) by replacing tabs by spaces, but this kills tab alignment across rows. Let us know when you plan to do something about it.

Ability to set per-column widths

I was working on formatting some text today and ran into a case where one column has a large amount of text and wraps before the width of the screen.

Assuming a table with 4 columns, is it possible to say "columns 1, 2, and 3 never wrap, column 4 use the rest of the screen width and then wrap?"

If that doesn't make sense, please let me know and I can try to explain it better.

feature request: custom column alignments

Currently anything that starts with a number is padded left and thus right-aligned.
This causes irregular output when a column containing strings happens to contain a string starting with decimal digits.

It would be good to be able to specify alignment for the entire column, for when the alignment type is known beforehand.

Needed to solve cockroachdb/cockroach#10042.

Feature request: stream rendering

Add support for rows streaming rendering.

i.e.

infinite loop calls table.Append(...)

table renders new rows it self on each call or on timeout or batched

Request: don't print a space before the table

Current:

table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{
	"LEFT", "MIDDLE", "RIGHT",
})
table.AppendBulk(data)
table.SetHeaderLine(false)
table.SetRowSeparator("")
table.SetColumnSeparator("")
table.SetCenterSeparator("")
table.SetAlignment(tablewriter.ALIGN_LEFT)
table.SetHeaderAlignment(tablewriter.ALIGN_LEFT)
table.SetBorders(tablewriter.Border{
	Bottom: false,
	Left:   false,
	Right:  false,
	Top:    false,
})
table.Render()

Output:

  LEFT  MIDDLE  RIGHT  
  left  middle  right 

I'd like to eliminate the space on the left side.

Feature request: coloured output

Having coloured output (probably optional) to give certain table elements a different colour, or headings in a different colour.
This would improve readability on some larger tables by quite a bit and might even be clearer, for example when you have a table with names and a simple yes/no column you could colour the names red or green.

Just a suggestion, as usual.

Header in CSV table is broken

panic: assignment to entry in nil map

goroutine 1 [running]:
panic(0xfb8e0, 0xc420010990)
        /usr/local/Cellar/go/1.7/libexec/src/runtime/panic.go:500 +0x1a1
github.com/olekukonko/tablewriter.(*Table).parseDimension(0xc42008e400, 0x11a10f, 0x4, 0x0, 0xffffffffffffffff, 0x40, 0xf1940, 0xc42000e501)
        /Users/pires/Work/Projects/go/src/github.com/olekukonko/tablewriter/table.go:488 +0x10b
github.com/olekukonko/tablewriter.(*Table).SetHeader(0xc42008e400, 0xc42003bd18, 0x3, 0x3)
        /Users/pires/Work/Projects/go/src/github.com/olekukonko/tablewriter/table.go:121 +0x87
main.main()

Example code:

table, _ := tablewriter.NewCSV(os.Stdout, "intersects.csv", true)
table.SetHeader([]string{"a", "b", "c"})
table.Render()

Is this abandonware?

It'd be helpful to understand why tablewriter PR's don't seem to get much love.

If olekukonko isn't able to (or interested in?) maintain this package it'd be helpful to know so other plans can be made.

Thank you,
Jay

Ansi modified strings break wrapping

Firstly, this is an awesome library, really really great.

There seems to be a small bug when trying to wrap text with colourising modifications in the string (e.g. \033[32m My string \033[00m)

If I turn of Autowrap then things are fine, but if I keep it on, it wraps in really strange places. Looking at the Wrap utilities, they take into account len(v) where v is the length of the string. But in other places you use DisplayWidth() which takes into account an ANSI regex:

var ansi = regexp.MustCompile("\033\\[(?:[0-9]{1,3}(?:;[0-9]{1,3})*)?[m|K]")

I'm not sure if its related, but just thought I'd point it out - I'm not using AutoWrap if I have string colouring.

Thanks, and again, great project!

ANSI-colored words get wrapped, but should probably not

Hi,

I encountered the problem that a two word column with each beeing an ANSI color sequence got word wrapped in a column, but see the attached example:

image

This is the code to generate this:

package main

import (
        "os"

        "github.com/olekukonko/tablewriter"
)

func main() {
        data := [][]string{
                []string{"a b", "without color"},
                []string{"\033[31ma\033[0m b", "left term colored"},
                []string{"m \033[32mb\033[0m", "right term color"},
                []string{"\033[31ma\033[0m \033[32mb\033[0m", "both terms color"},
                []string{"\033[31ma b\033[0m", "wrap inside ansi color term"},
                []string{"super long text", "super long plain string"},
        }

        table := tablewriter.NewWriter(os.Stdout)
        table.SetHeader([]string{"Icon", "Text"})

        for _, v := range data {
                table.Append(v)
        }
        table.Render()
}

Is this a bug or do I use something wrong? I'm using HEAD (b8a9be0)

New lines in column text are ignored

Columns with text that contains new lines does not render correctly.

Example:

table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"#", "Title", "Reported On"})
table.Append([]string{fmt.Sprintf("%d", 2), "This is some text\n\nWith multiple\n\nlines.", "2014-04-07"})
table.Render

This produces the following output:

+---+--------------------------------+-------------+
| # |             TITLE              | REPORTED ON |
+---+--------------------------------+-------------+
| 2 | This is some text  With        | 2014-04-07  |
|    | multiple  lines.               |             |
+---+--------------------------------+-------------+

I would expect it to output something similar to this:

+---+--------------------------------+-------------+
| # |             TITLE              | REPORTED ON |
+---+--------------------------------+-------------+
| 2 | This is some text              | 2014-04-07  |
|   |                                |             |
|   | With multiple                  |             |
|   |                                |             |
|   | lines.                         |             |
+---+--------------------------------+-------------+

Make `table` public

Currently the table struct is private so that none of the functions on it are exported into the documentation (like AppendBulk etc.) This means that in order to see the public methods on the table struct, you have to look at the source code.

If table were made public (e.g. by renaming to Table, or by implementing a public interface), this would vastly improve the usefulness of the documentation.

feature request: []string to []interface{}

Append([]string) -> Append([]interface{}) This allows much more fluid table writes.

Given:

foo := struct{
    Foo   string
    Fizz   int
    Buzz float32
}{
   Foo: "bar",
   Fizz: 123,
   Buzz: 3.14,
}
tw := tablewriter.NewWriter(os.Stdout)
tw.SetHeader([]string{"foo", "fizz", "buzz"})

this allows for

tw.Append([]interface{}{
  foo.Foo,
  foo.Fizz,
  foo.Buzz,
})

rather than

tw.Append([]string{}{
  foo.Foo,
  strconv.Itoa(foo.Fizz),
  strconv.FormatFloat(foo.Buzz, 'f', 2, 64),
})

This can be achieved easily by leveraging fmt.Sprint. This will cause an API break, however. All code utilizing tablewriter would require Append([]string{}) to be converted to Append([]interface{}{}).

I'll begin a branch with this change. If you do not want to break API, then I can a new method call AppendInterface or something of that nature.

Request: Add functionality for converting Golang []map[string]string to table

Functionality for generating table from an array of identical map[string]string objects. For example, if the returned JSON had the structure:

[
  { "item1" : "value1",
    "item2" : "value2"
     ...
  },
  { "item1" : "value3",
    "item2" : "value4"
     ...
  },
  ...
]

I would like to generate a table:
+--------+---------+
| item1 | item2 |
+--------+---------+
| value1 | value2 |
| value3 | value4 |
+--------+---------+

Incorrect line padding for non-ASCII character texts

Reproduce with the following script:

package main

import (
	"os"

	"github.com/olekukonko/tablewriter"
)

func main() {
	data := [][]string{
		[]string{"Random text 1", "Zufälliger Text 1"},
		[]string{"The Lion <♌>", "Der Löwe <♌>"},
		[]string{"Random text 2", "Zufälliger Text 2"},
	}

	table := tablewriter.NewWriter(os.Stdout)
	header := []string{"Term", "Translation"}
	table.SetHeader(header)
	table.SetBorder(false)
	const width = 100
	table.SetColWidth(width / len(header))
	table.AppendBulk(data)
	table.Render()
}

Actual result:

      TERM      |    TRANSLATION
+---------------+-------------------+
  Random text 1 | Zufälliger Text 1
  The Lion <♌> | Der Löwe <♌>         <- Incorrect padding here
  Random text 2 | Zufälliger Text 2

Expected result:

      TERM      |    TRANSLATION
+---------------+-------------------+
  Random text 1 | Zufälliger Text 1
  The Lion <♌>  | Der Löwe <♌>         <- Correct padding here
  Random text 2 | Zufälliger Text 2

Most likely caused by relying on len(bytes) instead of len(runes) somewhere.

Request: Add optional title to top of table spanning all columns

Thank you for the tablewriter library. It's been such a handy resource for a text-based interface project.

Would it be possible to add an optional title banner across the top of a table spanning all columns similar to the optional footer?

I'm happy to submit a pull request with the change. I'd need a little guidance on this as thus far I've gotten a little lost in the code in trying to understand how it could be added.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.