打印进度条核心在于 print("\r") 的使用

上代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package progress

import "fmt"

// Hello 测试用
func Hello() {
	fmt.Println("hello")
}

// Progress 进图结构体
type Progress struct {
	percent int64  // 百分比
	current int64  // 当前进度
	total   int64  // 总量
	rate    string // 进度条
	graph   string // 进度符号
}

// NewProgress 初始化方法
func NewProgress(start, total int64) *Progress {
	p := new(Progress)
	p.current = start
	p.total = total
	p.graph = "#" // 这里设置进度条的样式
	p.percent = p.GetPercent()
	return p
}

// GetPercent 获取百分比
func (p *Progress) GetPercent() int64 {
	return int64(float32(p.current) / float32(p.total) * 100)
}

// Add 增加进度
func (p *Progress) Add(i int64) {

	p.current += i

	if p.current > p.total {
		return
	}

	last := p.percent
	p.percent = p.GetPercent()

	if p.percent != last && p.percent%2 == 0 {
		p.rate += p.graph
	}

	fmt.Printf("\r[%-50s]%3d%% %8d/%d", p.rate, p.percent, p.current, p.total)
	// %-50s 左对齐, 占50个字符位置, 打印string
	// %3d   右对齐, 占3个字符位置 打印int

	if p.current == p.total {
		p.Done()
	}
}

// Done 完毕
func (p *Progress) Done() {
	fmt.Println()
}

测试文件:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
package progress

import (
	"testing"
	"time"
)

func TestRun(t *testing.T) {
	p := NewProgress(0, 100)

	for i := 0; i <= 100; i++ {
		time.Sleep(10 * time.Millisecond)
		p.Add(int64(2))
	}
}