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 的终端中生成表。