Go 终端表
最后修改时间 2024 年 4 月 11 日
在本文中,我们将展示如何在 Go 中创建终端表。随着控制台应用程序的复兴,我们寻找一种以整洁格式化的终端表来显示数据的方法。
要使用 Go 创建终端表,我们使用 go-pretty
包。
Go 简单终端表
在第一个示例中,我们创建了一个简单的终端表。
package main import ( "fmt" "github.com/jedib0t/go-pretty/v6/table" ) func main() { t := table.NewWriter() t.SetCaption("Users") t.AppendHeader(table.Row{"#", "Name", "Occupation"}) t.AppendRow(table.Row{1, "John Doe", "gardener"}) t.AppendRow(table.Row{2, "Roger Roe", "driver"}) t.AppendRows([]table.Row{{3, "Paul Smith", "trader"}, {4, "Lucy Smith", "teacher"}}) fmt.Println(t.Render()) }
该表有三列和四行。
t := table.NewWriter()
我们使用 NewWriter
创建一个新的表写入器。
t.AppendHeader(table.Row{"#", "Name", "Occupation"})
表头使用 AppendHeader
创建。我们指定了三列的名称。
t.AppendRow(table.Row{1, "John Doe", "gardener"})
使用 AppendRow
添加单行。
t.AppendRows([]table.Row{{3, "Paul Smith", "trader"}, {4, "Lucy Smith", "teacher"}})
可以使用 AppendRows
一次添加多行。
fmt.Println(t.Render())
使用 Render
渲染表。
$ go run main.go +---+------------+------------+ | # | NAME | OCCUPATION | +---+------------+------------+ | 1 | John Doe | gardener | | 2 | Roger Roe | driver | | 3 | Paul Smith | trader | | 4 | Lucy Smith | teacher | +---+------------+------------+ Users
在下一个示例中,我们修改了一些东西。
package main import ( "fmt" "github.com/jedib0t/go-pretty/v6/table" "github.com/jedib0t/go-pretty/v6/text" ) func main() { t := table.NewWriter() t.SetTitle("Users") t.SetAutoIndex(true) t.Style().Format.Header = text.FormatTitle t.AppendHeader(table.Row{"Name", "Occupation"}) t.AppendRow(table.Row{"John Doe", "gardener"}) t.AppendRow(table.Row{"Roger Roe", "driver"}) t.AppendRows([]table.Row{{"Paul Smith", "trader"}, {"Lucy Smith", "teacher"}}) fmt.Println(t.Render()) }
该示例略有修改。
t.SetTitle("Users")
我们使用 SetTitle
设置表标题,而不是说明。
t.SetAutoIndex(true)
SetAutoIndex
函数会自动创建一个索引列。
t.Style().Format.Header = text.FormatTitle
我们更改了列标题名称的格式。默认情况下,它们显示为大写。
$ go run main.go +-----------------------------+ | Users | +---+------------+------------+ | | Name | Occupation | +---+------------+------------+ | 1 | John Doe | gardener | | 2 | Roger Roe | driver | | 3 | Paul Smith | trader | | 4 | Lucy Smith | teacher | +---+------------+------------+
表尾
使用 AppendFooter
添加表尾。
package main import ( "fmt" "github.com/jedib0t/go-pretty/v6/table" "github.com/jedib0t/go-pretty/v6/text" ) type User struct { Name string Occupation string Salary int } func main() { users := []User{{"John Doe", "gardener", 1250}, {"Roger Roe", "driver", 950}, {"Paul Smith", "trader", 2100}, {"Lucy Smith", "teacher", 880}} var total int for _, u := range users { total += u.Salary } t := table.NewWriter() t.SetCaption("Users") t.SetAutoIndex(true) t.Style().Format.Header = text.FormatTitle t.Style().Format.Footer = text.FormatTitle t.AppendHeader(table.Row{"Name", "Occupation", "Salary"}) for _, u := range users { t.AppendRow(table.Row{u.Name, u.Occupation, u.Salary}) } t.AppendFooter(table.Row{"", "Total", total}) fmt.Println(t.Render()) }
我们有一个用户表。每个用户有三个属性:姓名、职业和薪水。我们在表的页脚中添加了总薪水。
type User struct { Name string Occupation string Salary int }
我们定义了 User
结构体。
users := []User{{"John Doe", "gardener", 1250}, {"Roger Roe", "driver", 950}, {"Paul Smith", "trader", 2100}, {"Lucy Smith", "teacher", 880}}
我们定义了一个用户集合。
for _, u := range users { total += u.Salary }
我们从集合中计算了总薪水金额。
for _, u := range users { t.AppendRow(table.Row{u.Name, u.Occupation, u.Salary}) }
我们将数据添加到表中。
t.AppendFooter(table.Row{"", "Total", total})
我们使用 AppendFooter
函数将页脚添加到表中。
$ go run main.go +---+------------+------------+--------+ | | Name | Occupation | Salary | +---+------------+------------+--------+ | 1 | John Doe | gardener | 1250 | | 2 | Roger Roe | driver | 950 | | 3 | Paul Smith | trader | 2100 | | 4 | Lucy Smith | teacher | 880 | +---+------------+------------+--------+ | | | Total | 5180 | +---+------------+------------+--------+ Users
将表写入文件
渲染的表可以轻松地写入文件。
package main import ( "log" "os" "github.com/jedib0t/go-pretty/v6/table" "github.com/jedib0t/go-pretty/v6/text" ) type User struct { Name string Occupation string Salary int } func main() { f, err := os.Create("data.txt") if err != nil { log.Fatal(err) } defer f.Close() users := []User{{"John Doe", "gardener", 1250}, {"Roger Roe", "driver", 950}, {"Paul Smith", "trader", 2100}, {"Lucy Smith", "teacher", 880}} t := table.NewWriter() t.SetCaption("Users") t.SetAutoIndex(true) t.Style().Format.Header = text.FormatTitle t.SetOutputMirror(os.Stdout) t.AppendHeader(table.Row{"Name", "Occupation", "Salary"}) for _, u := range users { t.AppendRow(table.Row{u.Name, u.Occupation, u.Salary}) } f.WriteString(t.Render()) }
在程序中,我们将表写入文件,也写入终端。
f, err := os.Create("data.txt") if err != nil { log.Fatal(err) } defer f.Close()
我们创建一个文件,并在其中写入我们的表。
t.SetOutputMirror(os.Stdout)
使用 SetOutputMirror
,我们还将数据发送到终端。实际上,数据被写入文件并在控制台中镜像。
f.WriteString(t.Render())
Render
函数返回一个字符串,该字符串使用 WriteString
写入文件。
表样式
该库附带预定义的样式。样式由 table.Style
结构表示。
package main import ( "fmt" "github.com/jedib0t/go-pretty/v6/table" "github.com/jedib0t/go-pretty/v6/text" ) type User struct { Name string Occupation string Salary int } func main() { styles := []table.Style{ table.StyleDefault, table.StyleLight, table.StyleColoredDark, table.StyleColoredBlueWhiteOnBlack, } users := []User{{"John Doe", "gardener", 1250}, {"Roger Roe", "driver", 950}, {"Paul Smith", "trader", 2100}, {"Lucy Smith", "teacher", 880}} for _, style := range styles { t := table.NewWriter() t.SetCaption("Users") t.AppendHeader(table.Row{"Name", "Occupation", "Salary"}) for _, u := range users { t.AppendRow(table.Row{u.Name, u.Occupation, u.Salary}) } t.SetAutoIndex(true) t.SetStyle(style) t.Style().Options.SeparateRows = true t.Style().Format.Header = text.FormatTitle fmt.Println(t.Render()) fmt.Println() } }
在示例中,我们以各种样式输出表。
styles := []table.Style{ table.StyleDefault, table.StyleLight, table.StyleColoredDark, table.StyleColoredBlueWhiteOnBlack, }
我们有一个内置样式的集合。
t.SetStyle(style)
使用 SetStyle
应用样式。
t.Style().Options.SeparateRows = true t.Style().Format.Header = text.FormatTitle
样式可以在之后通过属性进行修改。
币安订单簿
订单簿是特定资产的买入/买出和卖出/卖出订单的电子列表,按价格水平组织。在我们的示例中,我们展示了币安上 LTC 代币的订单簿。
package main import ( "context" "fmt" "log" "os" "github.com/adshao/go-binance/v2" "github.com/jedib0t/go-pretty/v6/table" "github.com/jedib0t/go-pretty/v6/text" ) func main() { var ( apiKey = os.Getenv("BINANCE_API_KEY") secretKey = os.Getenv("BINANCE_SECRET_KEY") ) client := binance.NewClient(apiKey, secretKey) tickers, err := client.NewDepthService().Symbol("LTCBUSD").Limit(15). Do(context.Background()) if err != nil { log.Fatal(err) } // Bids t := table.NewWriter() t.SetTitle("LTC") t.SetCaption("Bids") t.SetAutoIndex(true) t.SetStyle(table.StyleColoredGreenWhiteOnBlack) t.Style().Format.Header = text.FormatTitle t.SetColumnConfigs([]table.ColumnConfig{ {Number: 1, Align: text.AlignRight}, {Number: 2, Align: text.AlignRight}}) t.AppendHeader(table.Row{"Price", "Quatity"}) for _, bid := range tickers.Bids { t.AppendRow(table.Row{bid.Price, bid.Quantity}) } fmt.Println(t.Render()) fmt.Println() // Asks t2 := table.NewWriter() t2.SetTitle("LTC") t2.SetCaption("Asks") t2.SetAutoIndex(true) t2.SetStyle(table.StyleColoredRedWhiteOnBlack) t2.Style().Format.Header = text.FormatTitle t2.Style().Format.Row = text.Format(text.AlignRight) t2.SetColumnConfigs([]table.ColumnConfig{ {Number: 1, Align: text.AlignRight}, {Number: 2, Align: text.AlignRight}}) t2.AppendHeader(table.Row{"Price", "Quatity"}) for _, ask := range tickers.Asks { t2.AppendRow(table.Row{ask.Price, ask.Quantity}) } fmt.Println(t2.Render()) }
该示例创建了两个表:一个用于买单,一个用于卖单。
var ( apiKey = os.Getenv("BINANCE_API_KEY") secretKey = os.Getenv("BINANCE_SECRET_KEY") ) client := binance.NewClient(apiKey, secretKey)
我们从币安交易所检索数据。在我们的账户中,我们设置了 API 和 Secret 密钥。
tickers, err := client.NewDepthService().Symbol("LTCBUSD").Limit(15). Do(context.Background())
使用 NewDepthService
检索订单簿。我们使用 LTCBUSD
对。
// Bids t := table.NewWriter() t.SetTitle("LTC") t.SetCaption("Bids") t.SetAutoIndex(true) t.SetStyle(table.StyleColoredGreenWhiteOnBlack) t.Style().Format.Header = text.FormatTitle t.SetColumnConfigs([]table.ColumnConfig{ {Number: 1, Align: text.AlignRight}, {Number: 2, Align: text.AlignRight}})
这些是买单。传统上,它们显示为绿色。因此,我们选择了 table.StyleColoredGreenWhiteOnBlack
表样式。我们也已将数据右对齐。
t.AppendHeader(table.Row{"Price", "Quatity"})
每行有两列:价格和数量。
for _, bid := range tickers.Bids { t.AppendRow(table.Row{bid.Price, bid.Quantity}) } fmt.Println(t.Render())
我们遍历买单并将它们添加到表中。之后,该表被渲染到控制台。
t2.SetStyle(table.StyleColoredRedWhiteOnBlack)
对于卖单,我们选择了 table.StyleColoredRedWhiteOnBlack
样式。
for _, ask := range tickers.Asks { t2.AppendRow(table.Row{ask.Price, ask.Quantity}) } fmt.Println(t2.Render())
我们遍历卖单,并将它们添加到第二个表中。最后渲染该表。
来源
在本文中,我们展示了如何在 Go 的终端中生成表。