Gotabulate - Easily pretty-print your tabular data with Go

Gotabulate - Easily pretty-print tabular data

GoDoc Build Status

Summary

Go-Tabulate - Generic Go Library for easy pretty-printing of tabular data.

Installation

go get github.com/bndr/gotabulate

Description

Supported data types:

  • 2D Array of Int, Int64, Float64, String, interface{}
  • Map of String, interface{} (Keys will be used as header)

Usage

// Create Some Fake Rows
row_1 := []interface{}{"john", 20, "ready"}
row_2 := []interface{}{"bndr", 23, "ready"}

// Create an object from 2D interface array
t := gotabulate.Create([][]interface{}{row_1, row_2})

// Set the Headers (optional)
t.SetHeaders([]string{"age", "status"})

// Set the Empty String (optional)
t.SetEmptyString("None")

// Set Align (Optional)
t.SetAlign("right")

// Print the result: grid, or simple
fmt.Println(t.Render("grid"))

+---------+--------+-----------+
|         |    age |    status |
+=========+========+===========+
|    john |     20 |     ready |
+---------+--------+-----------+
|    bndr |     23 |     ready |
+---------+--------+-----------+

Example with String

// Some Strings
string_1 := []string{"TV", "1000$", "Sold"}
string_2 := []string{"PC", "50%", "on Hold"}

// Create Object
tabulate := gotabulate.Create([][]string{string_1, string_2})

// Set Headers
tabulate.SetHeaders([]string{"Type", "Cost", "Status"})

// Render
fmt.Println(tabulate.Render("simple"))

---------  ----------  ------------
    Type        Cost        Status
---------  ----------  ------------
      TV       1000$          Sold

      PC         50%       on Hold
---------  ----------  ------------

Example with String Wrapping

tabulate := gotabulate.Create([][]string{[]string{"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus laoreet vestibulum pretium. Nulla et ornare elit. Cum sociis natoque penatibus et magnis",
	"Vivamus laoreet vestibulum pretium. Nulla et ornare elit. Cum sociis natoque penatibus et magnis", "zzLorem ipsum", " test", "test"}, []string{"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus laoreet vestibulum pretium. Nulla et ornare elit. Cum sociis natoque penatibus et magnis",
	"Vivamus laoreet vestibulum pretium. Nulla et ornare elit. Cum sociis natoque penatibus et magnis", "zzLorem ipsum", " test", "test"}, STRING_ARRAY, []string{"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus laoreet vestibulum pretium. Nulla et ornare elit. Cum sociis natoque penatibus et magnis",
	"Vivamus laoreet vestibulum pretium. Nulla et ornare elit. Cum sociis natoque penatibus et magnis", "zzLorem ipsum", " test", "test"}, STRING_ARRAY})

tabulate.SetHeaders([]string{"Header 1", "header 2", "header 3", "header 4"})
// Set Max Cell Size
tabulate.SetMaxCellSize(16)

// Turn On String Wrapping
tabulate.SetWrapStrings(true)

// Render the table
fmt.Println(tabulate.Render("grid"))

+---------------------+---------------------+----------------+-------------+-------------+
|                     |            Header 1 |       header 2 |    header 3 |    header 4 |
+=====================+=====================+================+=============+=============+
|    Lorem ipsum dolo |    Vivamus laoreet  |    Lorem ipsum |        test |        test |
|    r sit amet, cons |    vestibulum preti |                |             |             |
|    ectetur adipisci |    um. Nulla et orn |                |             |             |
|    ng elit. Vivamus |    are elit. Cum so |                |             |             |
|     laoreet vestibu |    ciis natoque pen |                |             |             |
|    lum pretium. Nul |    atibus et magnis |                |             |             |
|    la et ornare eli |                     |                |             |             |
|    t. Cum sociis na |                     |                |             |             |
|    toque penatibus  |                     |                |             |             |
|           et magnis |                     |                |             |             |
+---------------------+---------------------+----------------+-------------+-------------+
|    Lorem ipsum dolo |    Vivamus laoreet  |    Lorem ipsum |        test |        test |
|    r sit amet, cons |    vestibulum preti |                |             |             |
|    ectetur adipisci |    um. Nulla et orn |                |             |             |
|    ng elit. Vivamus |    are elit. Cum so |                |             |             |
|     laoreet vestibu |    ciis natoque pen |                |             |             |
|    lum pretium. Nul |    atibus et magnis |                |             |             |
|    la et ornare eli |                     |                |             |             |
|    t. Cum sociis na |                     |                |             |             |
|    toque penatibus  |                     |                |             |             |
|           et magnis |                     |                |             |             |
+---------------------+---------------------+----------------+-------------+-------------+
|         test string |       test string 2 |           test |         row |        bndr |
+---------------------+---------------------+----------------+-------------+-------------+
|    Lorem ipsum dolo |    Vivamus laoreet  |    Lorem ipsum |        test |        test |
|    r sit amet, cons |    vestibulum preti |                |             |             |
|    ectetur adipisci |    um. Nulla et orn |                |             |             |
|    ng elit. Vivamus |    are elit. Cum so |                |             |             |
|     laoreet vestibu |    ciis natoque pen |                |             |             |
|    lum pretium. Nul |    atibus et magnis |                |             |             |
|    la et ornare eli |                     |                |             |             |
|    t. Cum sociis na |                     |                |             |             |
|    toque penatibus  |                     |                |             |             |
|           et magnis |                     |                |             |             |
+---------------------+---------------------+----------------+-------------+-------------+
|         test string |       test string 2 |           test |         row |        bndr |
+---------------------+---------------------+----------------+-------------+-------------+

Examples

t := gotabulate.Create([][]string{STRING_ARRAY, STRING_ARRAY})

t.SetHeaders(HEADERS) // If not headers are set, the first row will be used.

t.SetEmptyString("None") // Set what will be printed in the empty cell

rendered_string := t.Render("simple") // Render() will return a string

Simple Table
----------------------  ----------------------  ----------------------  -------------  -------------
             Header 1                Header 2                Header 3       Header 4       Header 5 
----------------------  ----------------------  ----------------------  -------------  -------------
          test string           test string 2                    test            row           bndr 

          test string           test string 2                    test            row           bndr 

    4th element empty       4th element empty       4th element empty           None           None 
----------------------  ----------------------  ----------------------  -------------  -------------

Grid Table (Align Right)
+-------------+-------------+-------------+-------------+-------------+
|    Header 1 |    Header 2 |    Header 3 |    Header 4 |    Header 5 |
+=============+=============+=============+=============+=============+
|       10.01 |      12.002 |      -123.5 |    20.00005 |        1.01 |
+-------------+-------------+-------------+-------------+-------------+
|       10.01 |      12.002 |      -123.5 |    20.00005 |        1.01 |
+-------------+-------------+-------------+-------------+-------------+
|       10.01 |      12.002 |      -123.5 |    20.00005 |        None |
+-------------+-------------+-------------+-------------+-------------+

Padded Headers:
+----------------------+----------------------+----------------------+-------------+-------------+
|                      |             Header 1 |             header 2 |    header 3 |    header 4 |
+======================+======================+======================+=============+=============+
|          test string |        test string 2 |                 test |         row |        bndr |
+----------------------+----------------------+----------------------+-------------+-------------+
|          test string |        test string 2 |                 test |         row |        bndr |
+----------------------+----------------------+----------------------+-------------+-------------+
|    4th element empty |    4th element empty |    4th element empty |        None |        None |
+----------------------+----------------------+----------------------+-------------+-------------+

Align Center:
+-------------+-------------+-------------+-------------+-------------+
|   Header 1  |   Header 2  |   Header 3  |   Header 4  |   Header 5  |
+=============+=============+=============+=============+=============+
|    10.01    |    12.002   |    -123.5   |   20.00005  |     1.01    |
+-------------+-------------+-------------+-------------+-------------+
|    10.01    |    12.002   |    -123.5   |   20.00005  |     1.01    |
+-------------+-------------+-------------+-------------+-------------+
|    10.01    |    12.002   |    -123.5   |   20.00005  |     1.01    |
+-------------+-------------+-------------+-------------+-------------+

Align Left:
+-------------+-------------+-------------+-------------+-------------+
| Header 1    | Header 2    | Header 3    | Header 4    | Header 5    |
+=============+=============+=============+=============+=============+
| 10.01       | 12.002      | -123.5      | 20.00005    | 1.01        |
+-------------+-------------+-------------+-------------+-------------+
| 10.01       | 12.002      | -123.5      | 20.00005    | 1.01        |
+-------------+-------------+-------------+-------------+-------------+
| 10.01       | 12.002      | -123.5      | 20.00005    | 1.01        |
+-------------+-------------+-------------+-------------+-------------+

Status

Beta version. There may be edge cases that I have missed, so if your tables don't render properly please open up an issue.

Contribute

All Contributions are welcome. The todo list is on the bottom of this README. Feel free to send a pull request.

License

Apache License 2.0

TODO

  • Add more examples
  • Better Documentation
  • Implement more data table formats
  • Decimal point alignment for floats

Acknowledgement

Inspired by Python package tabulate

Owner
Vadim Kravcenko
CTO @ Mindnow AG
Vadim Kravcenko
Comments
  • it is not good support for chinese, and so other language. I think it must get the length of string is wrong

    it is not good support for chinese, and so other language. I think it must get the length of string is wrong

    +-------------------------+-------------------------+-------------+-----------------------+-----------------------+-----------------------+ | 前10产品销量比 | 前10品牌销量比 | 销量 | 销售的产品数 | 销售的品牌数 | 销售的分类数 | +=========================+=========================+=============+=======================+=======================+=======================+ | 0.64 | 0.68 | 3173299 | 2690 | 153 | 109 | +-------------------------+-------------------------+-------------+-----------------------+-----------------------+-----------------------+ | 0.68 | 0.58 | 26524137 | 5326 | 236 | 350 | +-------------------------+-------------------------+-------------+-----------------------+-----------------------+-----------------------+

  • Add Titles to tables

    Add Titles to tables

    SetTitle("my table name")

    also able to add optional alignment to titles with

    SetTitle("my table name", "right")

    And can still hide the top line above the title by adding "aboveTitle" to hide lines

  • Question about formating data

    Question about formating data

    I have used this library in the past, however have had general issues with formatting data into a table under a for loop i want to print the output of this

    			var row_total = 0
    			fmt.Println("|Ether-Shark| ", RED, "SETTING CONFIG -> ", BLU, formatDate, " Searching filepath -> ", options.filepath, " For PCAP files")
    			for _, filename := range find(options.filepath, ".pcap") {
    				row_total += 1
    				row_total := []interface{}{filename}
    				t := gotabulate.Create([][]interface{}{row_total})
    				t.SetHeaders([]string{"Filepath and Names found"})
    				t.SetEmptyString("None")
    				t.SetAlign("right")
    			}
    			fmt.Println(t)
    

    but i can not do that, simply because of the error as the t is undefined outside of the loop, what i am trying to do is add a count of all the files detected in that for loop, and adding it to a table then outputting it, when i try to do it it prints like this

    |                          Filepath and Names found |
    +===================================================+
    |    Pcap_Examples/HTTP - Basic Authentication.pcap |
    +---------------------------------------------------+
    
    +----------------------------------------------------+
    |                           Filepath and Names found |
    +====================================================+
    |    Pcap_Examples/HTTP - Digest Authentication.pcap |
    +----------------------------------------------------+
    
    

    but i would like to have it out like this

    +-----------------------------+
    |    Filepath and Names found |
    +=============================+
    |      Pcap_Examples/Ftp.pcap |
    |  a filepath / to pcap /              |
    | row 2                                     |
    | row3                                      |
    | etc                                        |
    
    +-----------------------------+
    
    

    is there anyway you can help me with formating the data to a table like that?

  • Added ability to hide the line between rows entirely

    Added ability to hide the line between rows entirely

    The "simple" rendering still leaves a blank line in between each row. This allows the user to remove that blank line for an even more compact table

  • fixed crash due to running Update on an empty data set

    fixed crash due to running Update on an empty data set

    When calling Render on an empty data set with WrapStrings set there is a crash due to an index out of range error. The pull request just adds a simple little check to short circuit out of the function if data is empty.

  • Added ability to do smart wrapping

    Added ability to do smart wrapping

    You can designate smart wrapping delimiters and concatenation strings.

    For example if a cell had the text "Hello friends, my name is bob" with a width of 10, it generate the following: Hello frie nds, my na me is bob

    But with smart wrapping in this pull it generates the following: Hello Friends, my name is bob

  • Support Multi-byte

    Support Multi-byte

    package main
    
    import (
        "fmt"
        "github.com/bndr/gotabulate"
    )
    
    func main() {
        tabulate := gotabulate.Create([][]string{
            {"朝", "おはようございます"},
            {"昼", "こんにちわ"},
            {"夜", "こんばんわ"},
            {"夜", "Hello World!"},
        })
        tabulate.SetHeaders([]string{"時間帯", "挨拶"})
        tabulate.SetMaxCellSize(15)
        tabulate.SetWrapStrings(true)
        fmt.Println(tabulate.Render("grid"))
    }
    

    This should be displayed as below.

  • Panic on grid with single column

    Panic on grid with single column

    If we attempt to tabulate on a grid with a single column and a single entry it panics with the following:

    panic: runtime error: index out of range [recovered] panic: runtime error: index out of range

    goroutine 29 [running]: panic(0x7ae320, 0xc82000a0c0) /usr/lib/go-1.6/src/runtime/panic.go:481 +0x3e6 testing.tRunner.func1(0xc82015dd40) /usr/lib/go-1.6/src/testing/testing.go:467 +0x192 panic(0x7ae320, 0xc82000a0c0) /usr/lib/go-1.6/src/runtime/panic.go:443 +0x4e9 _/tmp/gotabulate.(_Tabulate).wrapCellData(0xc820179200, 0x0, 0x0, 0x0) /tmp/gotabulate/tabulate.go:357 +0x701 _/tmp/gotabulate.(_Tabulate).Render(0xc820179200, 0xc820049ef8, 0x1, 0x1, 0x0, 0x0) /tmp/gotabulate/tabulate.go:213 +0x241 _/tmp/gotabulate.TestSingleColumn(0xc82015dd40) /tmp/gotabulate/tabulate_test.go:205 +0x20b testing.tRunner(0xc82015dd40, 0xa16408) /usr/lib/go-1.6/src/testing/testing.go:473 +0x98 created by testing.RunTests /usr/lib/go-1.6/src/testing/testing.go:582 +0x892

    The test case I created that demonstrates this is the following: func TestSingleColumn(t *testing.T) { tab := Create([][]string{ {"test"}, }) tab.SetMaxCellSize(20) tab.SetWrapStrings(true) tab.Render("grid") }

  • support option to remove space line between each data row

    support option to remove space line between each data row

    When we use gotabulate 'Simple Table' in our container image build project isula-build to list images managerd by the daemon, the space line between each item is too sparse. This lead to a full screen page list fewer items as follows:

    isula-build ctr-img images
    ----------------------------------------------  -----------  -----------------  ------------------------  ------------
     REPOSITORY                                      TAG          IMAGE ID           CREATED                   SIZE
    ----------------------------------------------  -----------  -----------------  ------------------------  ------------
     <none>                                          <none>       23e3d8bb12ff       2020-11-24 08:11:15       1.45 MB
    
     lzk                                             latest       f19434180a1c       2020-11-18 10:54:24       1.44 MB
    
     <none>                                          <none>       b6b74a847ff3       2020-11-18 10:54:19       1.44 MB
    ----------------------------------------------  -----------  -----------------  ------------------------  ------------
    

    If there exist an option which can control remove those space line, more items can be display and I think also useful in other scenarios. The result in our project can be:

    isula-build ctr-img images
    ----------------------------------------------  -----------  -----------------  ------------------------  ------------
     REPOSITORY                                      TAG          IMAGE ID           CREATED                   SIZE
    ----------------------------------------------  -----------  -----------------  ------------------------  ------------
     <none>                                          <none>       23e3d8bb12ff       2020-11-24 08:11:15       1.45 MB
     lzk                                             latest       f19434180a1c       2020-11-18 10:54:24       1.44 MB
     <none>                                          <none>       b6b74a847ff3       2020-11-18 10:54:19       1.44 MB
    ----------------------------------------------  -----------  -----------------  ------------------------  ------------
    

    or

    isula-build ctr-img images
    +----------------------------------------------+-----------+-----------------+------------------------+------------+
    | REPOSITORY                                   | TAG       | IMAGE ID        | CREATED                | SIZE       |
    +==============================================+===========+=================+========================+============+
    | <none>                                       | <none>    | 23e3d8bb12ff    | 2020-11-24 08:11:15    | 1.45 MB    |
    | <none>                                       | <none>    | 71173ee82707    | 2020-11-24 08:09:43    | 1.44 MB    |
    | <none>                                       | <none>    | 5d5db30060ff    | 2020-11-24 08:05:46    | 1.44 MB    |
    | <none>                                       | <none>    | bde817fd2249    | 2020-11-20 11:56:34    | 1.44 MB    |
    | <none>                                       | <none>    | 034e08b6cade    | 2020-11-20 11:53:06    | 1.44 MB    |
    | lzk                                          | latest    | f19434180a1c    | 2020-11-18 10:54:24    | 1.44 MB    |
    | <none>                                       | <none>    | b6b74a847ff3    | 2020-11-18 10:54:19    | 1.44 MB    |
    | <none>                                       | <none>    | 174ad5b1cf49    | 2020-11-16 10:06:29    | 1.44 MB    |
    | <none>                                       | <none>    | f28a219985c1    | 2020-11-16 08:20:17    | 1.44 MB    |
    +----------------------------------------------+-----------+-----------------+------------------------+------------+
    

    For above use it looks more reasonable. In the end, thanks for this project.

  • Creating a new TableFormat

    Creating a new TableFormat

    The docstring for the TableFormats map states that the user can add and entry to the map if they want to create a new one. However, the fields for the Line and Row structs are not exported. Is there a way to create a new TableFormat from outside of the gotabulate package?

  • Trying to  create a CSV tableformat

    Trying to create a CSV tableformat

    I had an issue but I figured it out... Now if I can figure out how to remove this issue I'd do that.

    Btw. gotabulate is fantastic!! I wrote a tool to query databases, and this allows me to format the output so that it looks nice and neat.

Go-banner-printer - This library is to simply print a ASCII banner when you start the application

This library is to simply print a ASCII banner when you start the application.

Jan 18, 2022
Easily to convert JSON data to Markdown Table

Easily to convert JSON data to Markdown Table

Oct 28, 2022
parse and generate XML easily in go

etree The etree package is a lightweight, pure go package that expresses XML in the form of an element tree. Its design was inspired by the Python Ele

Dec 19, 2022
:zap: Transfer files over wifi from your computer to your mobile device by scanning a QR code without leaving the terminal.
:zap: Transfer files over wifi from your computer to your mobile device by scanning a QR code without leaving the terminal.

$ qrcp Transfer files over Wi-Fi from your computer to a mobile device by scanning a QR code without leaving the terminal. You can support development

Dec 28, 2022
Extract structured data from web sites. Web sites scraping.
Extract structured data from web sites. Web sites scraping.

Dataflow kit Dataflow kit ("DFK") is a Web Scraping framework for Gophers. It extracts data from web pages, following the specified CSS Selectors. You

Jan 7, 2023
Encoding and decoding for fixed-width formatted data

fixedwidth Package fixedwidth provides encoding and decoding for fixed-width formatted Data. go get github.com/ianlopshire/go-fixedwidth Usage Struct

Dec 16, 2022
Faker is a Go library that generates fake data for you.
Faker is a Go library that generates fake data for you.

Faker is a Go library that generates fake data for you. Whether you need to bootstrap your database, create good-looking XML documents, fill-in your p

Jan 7, 2023
ByNom is a Go package for parsing byte sequences, suitable for parsing text and binary data

ByNom is a Go package for parsing byte sequences. Its goal is to provide tools to build safe byte parsers without compromising the speed or memo

May 5, 2021
Parse data and test fixtures from markdown files, and patch them programmatically, too.

go-testmark Do you need test fixtures and example data for your project, in a language agnostic way? Do you want it to be easy to combine with documen

Oct 31, 2022
Auto-gen fuzzing wrappers from normal code. Automatically find buggy call sequences, including data races & deadlocks. Supports rich signature types.

fzgen fzgen auto-generates fuzzing wrappers for Go 1.18, optionally finds problematic API call sequences, can automatically wire outputs to inputs acr

Dec 23, 2022
Build "Dictionary of the Old Norwegian Language" into easier-to-use data formats

Old Norwegian Dictionary Builder Build "Dictionary of the Old Norwegian Language" into easier-to-use data formats. Available formats: JSON DSL XML Usa

Oct 11, 2022
A fast, easy-of-use and dependency free custom mapping from .csv data into Golang structs

csvparser This package provides a fast and easy-of-use custom mapping from .csv data into Golang structs. Index Pre-requisites Installation Examples C

Nov 14, 2022
Your CSV pocket-knife (golang)

csvutil - Your CSV pocket-knife (golang) #WARNING I would advise against using this package. It was a language learning exercise from a time before "e

Oct 24, 2022
Simple HCL (HashiCorp Configuration Language) parser for your vars.

HCL to Markdown About To write a good documentation for terraform module, quite often we just need to print all our input variables as a fancy table.

Dec 14, 2021
Preventing 3rd Party DLLs from Injecting into your Malware

Doge-BlockDLLs Preventing 3rd Party DLLs from Injecting into your Malware ACG(Arbitrary Code Guard)的方式等大佬来实现 Ref https://www.ired.team/offensive-secur

Dec 7, 2022
Stylesheet-based markdown rendering for your CLI apps 💇🏻‍♀️
Stylesheet-based markdown rendering for your CLI apps 💇🏻‍♀️

Glamour Write handsome command-line tools with Glamour. glamour lets you render markdown documents & templates on ANSI compatible terminals. You can c

Jan 1, 2023
Your dev tool to manage /etc/hosts like a pro!
Your dev tool to manage /etc/hosts like a pro!

hostctl This tool gives you more control over the use of your hosts file. You can have multiple profiles and switch them on/off as you need. Why? It i

Jan 2, 2023
Emojictl - manage your emojis!

Emojictl (pronounced emoji control) is a package (& CLI wrapper) for managing Emojis on platforms that support custom emojis. Currently only Slack support is implemented.

Nov 17, 2022
Schedule daily tweets from markdown files in your repo, posted via github actions.

markdown-tweet-scheduler Schedule daily tweets from markdown files in your repo, posted to twitter via github actions. Setup Fork this repo Get your t

Dec 6, 2022