Golang终端进度条实现指南

Golang终端进度条实现指南 你好, 在 pip install 时,我们会看到如下截图中所示的进度条。我希望在我的 Go 应用程序 CLI 中也能有这样的进度条。请问是否有类似的东西,或者我该如何构建自己的进度条?

有什么推荐吗?

image

3 回复

在 go.dev 上有几个选项:

图标

Progress bar - 搜索结果 - Go 包

Go 是一种开源编程语言,它使得构建简单、可靠且高效的软件变得容易。

更多关于Golang终端进度条实现指南的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go中实现终端进度条有多种方式,以下是几种常用方法和示例代码:

1. 使用第三方库

progressbar 库(推荐)

package main

import (
    "time"
    "github.com/schollz/progressbar/v3"
)

func main() {
    bar := progressbar.NewOptions(100,
        progressbar.OptionEnableColorCodes(true),
        progressbar.OptionSetWidth(50),
        progressbar.OptionSetDescription("[cyan][1/3][reset] 下载文件..."),
        progressbar.OptionSetTheme(progressbar.Theme{
            Saucer:        "[green]=[reset]",
            SaucerHead:    "[green]>[reset]",
            SaucerPadding: " ",
            BarStart:      "[",
            BarEnd:        "]",
        }))
    
    for i := 0; i < 100; i++ {
        bar.Add(1)
        time.Sleep(50 * time.Millisecond)
    }
}

mpb 库(多进度条支持)

package main

import (
    "time"
    "github.com/vbauerster/mpb/v8"
    "github.com/vbauerster/mpb/v8/decor"
)

func main() {
    p := mpb.New(mpb.WithWidth(60))
    
    bar := p.New(100,
        mpb.BarStyle().Lbound("[").Filler("=").Tip(">").Padding(" ").Rbound("]"),
        mpb.PrependDecorators(
            decor.Name("处理中:", decor.WC{W: 10, C: decor.DidentRight}),
            decor.CountersNoUnit("%d / %d", decor.WCSyncWidth),
        ),
        mpb.AppendDecorators(
            decor.Percentage(decor.WC{W: 5}),
            decor.Elapsed(decor.ET_STYLE_GO),
        ),
    )
    
    for i := 0; i < 100; i++ {
        bar.Increment()
        time.Sleep(50 * time.Millisecond)
    }
    
    p.Wait()
}

2. 自定义简单进度条

package main

import (
    "fmt"
    "time"
    "strings"
)

type ProgressBar struct {
    total     int64
    current   int64
    width     int
    startTime time.Time
}

func NewProgressBar(total int64) *ProgressBar {
    return &ProgressBar{
        total:     total,
        startTime: time.Now(),
        width:     50,
    }
}

func (p *ProgressBar) Add(n int64) {
    p.current += n
    if p.current > p.total {
        p.current = p.total
    }
    p.Render()
}

func (p *ProgressBar) Render() {
    percent := float64(p.current) / float64(p.total)
    filled := int(percent * float64(p.width))
    
    bar := strings.Repeat("=", filled) + ">" + 
           strings.Repeat(" ", p.width-filled)
    
    elapsed := time.Since(p.startTime)
    eta := time.Duration(float64(elapsed)/percent - float64(elapsed))
    
    fmt.Printf("\r[%s] %.1f%% | %d/%d | 耗时: %v | ETA: %v",
        bar, percent*100, p.current, p.total, 
        elapsed.Round(time.Second), eta.Round(time.Second))
    
    if p.current >= p.total {
        fmt.Println()
    }
}

func main() {
    bar := NewProgressBar(100)
    for i := int64(0); i < 100; i++ {
        bar.Add(1)
        time.Sleep(100 * time.Millisecond)
    }
}

3. 带颜色的进度条

package main

import (
    "fmt"
    "time"
    "strings"
)

const (
    colorReset  = "\033[0m"
    colorGreen  = "\033[32m"
    colorYellow = "\033[33m"
    colorCyan   = "\033[36m"
)

func main() {
    total := 100
    width := 40
    
    for i := 0; i <= total; i++ {
        percent := float64(i) / float64(total)
        filled := int(percent * float64(width))
        
        bar := colorGreen + strings.Repeat("█", filled) + 
               colorYellow + ">" + 
               colorReset + strings.Repeat("░", width-filled)
        
        fmt.Printf("\r%s[%s]%s %.1f%% %s(%d/%d)%s",
            colorCyan, bar, colorReset,
            percent*100,
            colorYellow, i, total, colorReset)
        
        time.Sleep(50 * time.Millisecond)
    }
    fmt.Println()
}

安装第三方库

# progressbar
go get github.com/schollz/progressbar/v3

# mpb
go get github.com/vbauerster/mpb/v8

这些实现方式都能在终端中创建类似pip安装时的进度条效果。progressbar库提供了丰富的配置选项,mpb库支持多个并发进度条,自定义实现则提供了最大的灵活性。

回到顶部