网站建设概,政务公开 网站建设滞后,网站开发工程师求职简历,汽车之家 网站建设用Go在命令行输出好看的表格前言正文生成Table表头设置插入行表格标题自动标号单元格合并列合并行合并样式设置居中设置数字自动高亮标红完整Demo代码结语前言
最近在写一些运维小工具#xff0c;比如批量进行ping包的工具#xff0c;实现不困难#xff0c;反正就是ping比如批量进行ping包的工具实现不困难反正就是ping统计然后输出不过我本着自己既是开发者又是使用者的理念还是不喜欢输出特别难看的工具就像这样 所以就去https://pkg.go.dev/瞄了一眼看看有没有啥适合的库能够把输出整的好看点的于是找到了一个库github.com/jedib0t/go-pretty/v6/table这是一个在命令行输出格式化表格的库这里记录一下使用这个库进行一些格式化输出的过程。
其实还有一个比较简单的库叫做gotable也能实现基础的格式化输出功能使用起来也方便些不过功能相对来说就要单一一些在表格样式设置上会差一些没那么自由也可以看下https://pkg.go.dev/github.com/liushuochen/gotable#section-readme
正文
接下来开始正式的去在命令行生成好看的满足需要的表格。
生成Table
首先我们要生成一个Table结构体的实例可以直接New一个也可以自己构造
t : table.Table{}
// 或者
t : table.NewWriter()NewWriter会返回一个Writer接口
表头设置
表格首先要设置表头以我的应用为例表头设置
header : table.Row{ID, IP, Num, PacketsRecv, PacketLoss, AvgRtt}这样生成了一个表头行然后要通过AppendHeader方法在表格中生效
t.AppendHeader(header)看看效果表头已经打印出来了
----------------------------------------------
| ID | IP | NUM | PACKETSRECV | PACKETLOSS | AVGRTT |
----------------------------------------------
----------------------------------------------插入行
数据的插入和表头的生成类似要生成一个table.Row然后调用AppendRow方法
func (d *Demo) AppendRow() {for i : 1; i 5; i {row : table.Row{i, fmt.Sprintf(10.0.0.%v, i), i 4, i, i, AppendRow}d.T.AppendRow(row)}
}效果如下
-------------------------------------------------------
| ID | IP | NUM | PACKETSRECV | PACKETLOSS | AVGRTT |
-------------------------------------------------------
| 1 | 10.0.0.1 | 5 | 1 | 1 | AppendRow |
| 2 | 10.0.0.2 | 6 | 2 | 2 | AppendRow |
| 3 | 10.0.0.3 | 7 | 3 | 3 | AppendRow |
| 4 | 10.0.0.4 | 8 | 4 | 4 | AppendRow |
| 5 | 10.0.0.5 | 9 | 5 | 5 | AppendRow |
-------------------------------------------------------当然也可以生成table.Row的切片后调用一次AppendRows方法效果和上面是一样的
func (d *Demo) AppendRows() {var rows []table.Rowfor i : 1; i 5; i {rows append(rows, table.Row{i, fmt.Sprintf(10.0.0.%v, i), i 4, i, i, AppendRows})}d.T.AppendRows(rows)
}--------------------------------------------------------
| ID | IP | NUM | PACKETSRECV | PACKETLOSS | AVGRTT |
--------------------------------------------------------
| 1 | 10.0.0.1 | 5 | 1 | 1 | AppendRow |
| 2 | 10.0.0.2 | 6 | 2 | 2 | AppendRow |
| 3 | 10.0.0.3 | 7 | 3 | 3 | AppendRow |
| 4 | 10.0.0.4 | 8 | 4 | 4 | AppendRow |
| 5 | 10.0.0.5 | 9 | 5 | 5 | AppendRow |
| 1 | 10.0.0.1 | 5 | 1 | 1 | AppendRows |
| 2 | 10.0.0.2 | 6 | 2 | 2 | AppendRows |
| 3 | 10.0.0.3 | 7 | 3 | 3 | AppendRows |
| 4 | 10.0.0.4 | 8 | 4 | 4 | AppendRows |
| 5 | 10.0.0.5 | 9 | 5 | 5 | AppendRows |
--------------------------------------------------------表格标题
在设置表格实际内容时还可以设置一个表格标题如下
func (d *Demo) AddTitle() {d.T.SetTitle(This is Easy Table)
}-------------------------------------------------------------
| This is Easy Table |
--------------------------------------------------------
| ID | IP | NUM | PACKETSRECV | PACKETLOSS | AVGRTT |
--------------------------------------------------------
| 1 | 10.0.0.1 | 5 | 1 | 1 | AppendRow |
| 2 | 10.0.0.2 | 6 | 2 | 2 | AppendRow |
| 1 | 10.0.0.1 | 5 | 1 | 1 | AppendRows |
| 2 | 10.0.0.2 | 6 | 2 | 2 | AppendRows |
--------------------------------------------------------自动标号
在插入行的时候我额外输入了一个ID列作为标号其实table提供了相关的方法和接口只需要调用SetAutoIndex方法增加自动的索引列即可
func (d *Demo) MakeHeader() {header : table.Row{IP, Num, PacketsRecv, PacketLoss, AvgRtt}d.T.AppendHeader(header)d.T.SetAutoIndex(true)
}------------------------------------------------------------
| This is Easy Table |
-------------------------------------------------------
| | IP | NUM | PACKETSRECV | PACKETLOSS | AVGRTT |
-------------------------------------------------------
| 1 | 10.0.0.1 | 5 | 1 | 1 | AppendRow |
| 2 | 10.0.0.2 | 6 | 2 | 2 | AppendRow |
| 3 | 10.0.0.1 | 5 | 1 | 1 | AppendRows |
| 4 | 10.0.0.2 | 6 | 2 | 2 | AppendRows |
-------------------------------------------------------单元格合并
有的时候相邻单元格的值一样我们可能会想要进行合并这样更美观单元格合并分为列合并和行合并先定义一下这里的列合并和行合并
列合并针对单列如果单列中的多个相邻行数据一样那么就合并为一个大行行合并针对单行如果单行中的多个相邻列数据一样那么久合并为一个大列
这里我们用到的原始表格如下
--------------------------------------------------------------
| This is Easy Table |
---------------------------------------------------------
| | IP | NUM | PACKETSRECV | PACKETLOSS | AVGRTT |
---------------------------------------------------------
| 1 | 10.0.0.1 | 5 | 1 | 1 | AppendRow |
| 2 | 10.0.0.2 | 6 | 2 | 2 | AppendRow |
| 3 | 10.0.0.1 | 5 | 1 | 1 | AppendRows |
| 4 | 10.0.0.2 | 6 | 2 | 2 | AppendRows |
---------------------------------------------------------
| | TOTAL | TOTAL | TOTAL | TOTAL | 4 |
---------------------------------------------------------列合并
我们先进行最后一列AvgRtt的列合并
func (d *Demo) ColumnMerge() {d.T.SetColumnConfigs([]table.ColumnConfig{{Name: AvgRtt,// Number是指定列的序号// Number: 5,AutoMerge: true,Align: text.AlignCenter,},})
}可以选择通过列的表头或者列的序号来选择具体进行合并的列
---------------------------------------------------------
| | IP | NUM | PACKETSRECV | PACKETLOSS | AVGRTT |
---------------------------------------------------------
| 1 | 10.0.0.1 | 5 | 1 | 1 | AppendRow |
| 2 | 10.0.0.2 | 6 | 2 | 2 | |
| 3 | 10.0.0.1 | 5 | 1 | 1 | AppendRows |
| 4 | 10.0.0.2 | 6 | 2 | 2 | |
---------------------------------------------------------
| | TOTAL | TOTAL | TOTAL | TOTAL | 4 |
---------------------------------------------------------这样看表格线条不明显感觉不到区分那么可以加上一些设置d.T.Style().Options.SeparateRows true ---------------------------------------------------------
| | IP | NUM | PACKETSRECV | PACKETLOSS | AVGRTT |
---------------------------------------------------------
| 1 | 10.0.0.1 | 5 | 1 | 1 | AppendRow |
--------------------------------------------- |
| 2 | 10.0.0.2 | 6 | 2 | 2 | |
---------------------------------------------------------
| 3 | 10.0.0.1 | 5 | 1 | 1 | AppendRows |
--------------------------------------------- |
| 4 | 10.0.0.2 | 6 | 2 | 2 | |
---------------------------------------------------------
| | TOTAL | TOTAL | TOTAL | TOTAL | 4 |
---------------------------------------------------------行合并
行合并我们对最后一行的汇总行进行合并具体做法是在添加汇总行时增加RowConfig参数
func (d *Demo) AppendFooter() {d.T.AppendFooter(table.Row{Total, Total, Total, Total, count}, table.RowConfig{AutoMerge: true})
}---------------------------------------------------------
| | IP | NUM | PACKETSRECV | PACKETLOSS | AVGRTT |
---------------------------------------------------------
| 1 | 10.0.0.1 | 5 | 1 | 1 | AppendRow |
--------------------------------------------- |
| 2 | 10.0.0.2 | 6 | 2 | 2 | |
---------------------------------------------------------
| 3 | 10.0.0.1 | 5 | 1 | 1 | AppendRows |
--------------------------------------------- |
| 4 | 10.0.0.2 | 6 | 2 | 2 | |
---------------------------------------------------------
| | TOTAL | 4 |
------------------------------------------------------------样式设置
现在整个表格已经生成但我们还需要进行一些美化这就要对表格的样式进行设置了
居中设置
对于居中无法直接进行全局的设置必须根据列进行如下
func (d *Demo) SetAlignCenter() {column : []string{IP, Num, PacketsRecv, PacketLoss, AvgRtt}c : []table.ColumnConfig{}// 根据表格的列数循环进行设置统一居中for i : 1; i len(column); i {name : column[i-1]if name AvgRtt {c append(c, table.ColumnConfig{Name: AvgRtt,AutoMerge: true,Align: text.AlignCenter,AlignHeader: text.AlignCenter,AlignFooter: text.AlignCenter,})continue}c append(c, table.ColumnConfig{Name: column[i],Align: text.AlignCenter,AlignHeader: text.AlignCenter,AlignFooter: text.AlignCenter,})}d.T.SetColumnConfigs(c)
}居中效果如下这样既能保留列合并又完成了剧中设置
---------------------------------------------------------
| | IP | NUM | PACKETSRECV | PACKETLOSS | AVGRTT |
---------------------------------------------------------
| 1 | 10.0.0.1 | 5 | 1 | 1 | AppendRow |
--------------------------------------------- |
| 2 | 10.0.0.2 | 6 | 2 | 2 | |
---------------------------------------------------------
| 3 | 10.0.0.1 | 5 | 1 | 1 | AppendRows |
--------------------------------------------- |
| 4 | 10.0.0.2 | 6 | 2 | 2 | |
---------------------------------------------------------
| | TOTAL | 4 |
------------------------------------------------------------数字自动高亮标红
在我的应用场景中ping的ip如果出现了丢包情况那就要红色高亮方便使用者马上关注到这种情况下可以通过Transformer来设置
func (d *Demo) SetWarnColor() {// 字体颜色WarnColor : text.Colors{text.BgRed}warnTransformer : text.Transformer(func(val interface{}) string {if val.(float64) 0 {// 统计丢包服务器总数return WarnColor.Sprintf(%.2f%%, val)}return fmt.Sprintf(%v%%, val)})d.T.SetColumnConfigs([]table.ColumnConfig{{Name: PacketLoss,AutoMerge: true,Align: text.AlignCenter,AlignHeader: text.AlignCenter,AlignFooter: text.AlignCenter,Transformer: warnTransformer,},})
}实际效果如下
完整Demo代码
package mainimport (fmtmath/randgithub.com/jedib0t/go-pretty/v6/tablegithub.com/jedib0t/go-pretty/v6/text
)var count 0type Demo struct {T table.Writer
}func NewDemo() *Demo {return Demo{T: table.NewWriter(),}
}func (d *Demo) MakeHeader() {header : table.Row{IP, Num, PacketsRecv, PacketLoss, AvgRtt}d.T.AppendHeader(header)d.T.SetAutoIndex(true)// d.T.SetStyle(table.StyleLight)d.T.Style().Options.SeparateRows true
}func (d *Demo) AddTitle() {d.T.SetTitle(This is Easy Table)
}func (d *Demo) AppendRow() {// rowConfig : table.RowConfig{AutoMerge: true}for i : 1; i 2; i {row : table.Row{fmt.Sprintf(10.0.0.%v, i), i 4, i, rand.Float64() * 100, AppendRow}count 1d.T.AppendRow(row)}d.T.AppendRow(table.Row{fmt.Sprintf(10.0.0.%v, 4), 1 4, 1, 0.0, AppendRow})
}func (d *Demo) AppendRows() {var rows []table.Rowfor i : 1; i 2; i {rows append(rows, table.Row{fmt.Sprintf(10.0.0.%v, i), i 4, i, rand.Float64() * 100, AppendRows})count 1}d.T.AppendRows(rows)
}func (d *Demo) AppendFooter() {d.T.AppendFooter(table.Row{Total, Total, Total, Total, count}, table.RowConfig{AutoMerge: true, AutoMergeAlign: text.AlignCenter})
}func (d *Demo) ColumnMerge() {d.T.SetColumnConfigs([]table.ColumnConfig{{Name: AvgRtt,// Number是指定列的序号// Number: 5,AutoMerge: true,Align: text.AlignCenter,},})
}func (d *Demo) SetAlignCenter() {column : []string{IP, Num, PacketsRecv, PacketLoss, AvgRtt}c : []table.ColumnConfig{}// 根据表格的列数循环进行设置统一居中for i : 1; i len(column); i {name : column[i-1]if name AvgRtt {c append(c, table.ColumnConfig{Name: AvgRtt,AutoMerge: true,Align: text.AlignCenter,AlignHeader: text.AlignCenter,AlignFooter: text.AlignCenter,})continue}c append(c, table.ColumnConfig{Name: column[i],Align: text.AlignCenter,AlignHeader: text.AlignCenter,AlignFooter: text.AlignCenter,})}d.T.SetColumnConfigs(c)
}func (d *Demo) SetWarnColor() {// 字体颜色WarnColor : text.Colors{text.BgRed}warnTransformer : text.Transformer(func(val interface{}) string {if val.(float64) 0 {// 统计丢包服务器总数return WarnColor.Sprintf(%.2f%%, val)}return fmt.Sprintf(%v%%, val)})d.T.SetColumnConfigs([]table.ColumnConfig{{Name: PacketLoss,AutoMerge: true,Align: text.AlignCenter,AlignHeader: text.AlignCenter,AlignFooter: text.AlignCenter,Transformer: warnTransformer,},})
}func (d *Demo) Print() {fmt.Println(d.T.Render())
}func main() {demo : NewDemo()demo.MakeHeader()// demo.AddTitle()demo.AppendRow()demo.AppendRows()// demo.ColumnMerge()demo.AppendFooter()// demo.SetAlignCenter()demo.SetWarnColor()demo.Print()
}
结语
本文介绍了使用第三方库美化Golang的命令行表格格式化输出除了table以外go-pretty库中还包含了进度条、列表等美化方法感兴趣可以自己看看官方文档。