实现一个简单分页器

在go web编程中,当需要展示的列表数据太多时,不可避免需要分页展示,可以使用Go实现一个简单分页器,提供各个数据列表展示使用。
具体需求:
1. 可展示“首页”和“尾页”。
2. 可展示“上一页”和“下一页”。
3. 展示一定数量的数字页码,但总保持当前访问页码在中间位置。
分页器代码:

package paginator

import (
	"math"
)

//分页器结构
type paginator struct {
	Total     int   //记录总数
	PageSize  int   //每页大小
	PageTotal int   //总页数
	Page      int   //当前页数
	LastPage  int   //上一页
	NextPage  int   //下一页
	PageNums  []int //显示页码
}

var defaultPageSize = 5 //默认页大小
var pageNum = 5         //显示页码数量

//获取默认页大小
func GetDefaultPageSize() int {
	return defaultPageSize
}

//设置默认页大小
func SetDefaultPageSize(ps int) {
	if ps < 1 {
		ps = 1
	}
	defaultPageSize = ps
}

//设置显示页码数量
func SetPageNum(pn int) {
	if pn < 1 {
		pn = 1
	}
	pageNum = pn
}

//创建分页器
func CreatePaginator(page, pageSize, total int) paginator {
	if pageSize <= 0 {
		pageSize = defaultPageSize
	}
	pager := &paginator{
		Total:     total,
		PageSize:  pageSize,
		PageTotal: int(math.Ceil(float64(total) / float64(pageSize))),
		Page:      page,
	}
	if total <= 0 {
		pager.PageTotal = 1
		pager.Page = 1
		pager.LastPage = 1
		pager.NextPage = 1
		pager.PageNums = append(pager.PageNums, 1)
		return *pager
	}
	//分页边界处理
	if pager.Page > pager.PageTotal {
		pager.Page = pager.PageTotal
	} else if pager.Page < 1 {
		pager.Page = 1
	}
	//上一页与下一页
	pager.LastPage = pager.Page
	pager.NextPage = pager.Page
	if pager.Page > 1 {
		pager.LastPage = pager.Page - 1
	}
	if pager.Page < pager.PageTotal {
		pager.NextPage = pager.Page + 1
	}
	//显示页码
	var start, end int //开始页码与结束页码
	if pager.PageTotal <= pageNum {
		start = 1
		end = pager.PageTotal
	} else {
		before := pageNum / 2         //当前页前面页码数
		after := pageNum - before - 1 //当前页后面页码数
		start = pager.Page - before
		end = pager.Page + after
		if start < 1 { //当前页前面页码数不足
			start = 1
			end = pageNum
		} else if end > pager.PageTotal { //当前页后面页码数不足
			start = pager.PageTotal - pageNum + 1
			end = pager.PageTotal
		}
	}
	for i := start; i <= end; i++ {
		pager.PageNums = append(pager.PageNums, i)
	}
	return *pager
}

控制器使用:

pager := paginator.CreatePaginator(page, pageSize, total)
tpl, err := template.New("index.html").ParseFiles("index.html")
if err != nil {
	fmt.Fprint(writer, "模板解析错误:", err)
	return
}
err = tpl.Execute(writer, map[string]interface{}{"paginator": pager})
if err != nil {
	fmt.Fprint(writer, "模板执行错误:", err)
	return
}

模板使用:

#pageBar {
    text-align: right;
    padding: 20px 0 20px 0;
}
.pageBtn a {
    display: inline-block;
    border: 1px solid #aaa;
    padding: 2px 5px;
    margin : 0 3px;
    font-size: 13px;
    background: #ECECEC;
    color: black;
    text-decoration: none;
    -moz-border-radius: 2px;
    -webkit-border-radius: 3px;
}
.pageBtn-selected a {
    display: inline-block;
    border: 1px solid #aaa;
    padding: 2px 5px;
    margin : 0 3px;
    font-size: 13px;
    background: #187BBD;
    color: white;
    text-decoration: none;
    -moz-border-radius: 2px;
    -webkit-border-radius: 3px;
}
.pageBtn a:hover {
    background: #187BBD;
    color: white;
}
<div class="row" id="pageBar">
     {{if ne .paginator.Page 1}}
         <span class="pageBtn"><a href="/address/1/{{.paginator.PageSize}}">首页</a></span>
         <span class="pageBtn"><a href="/address/{{.paginator.LastPage}}/{{.paginator.PageSize}}">上一页</a></span>
     {{end}}
     {{range $k, $v := .paginator.PageNums}}
         {{if eq $v $.paginator.Page}}
              <span class="pageBtn-selected"><a href="/address/{{$v}}/{{$.paginator.PageSize}}">{{$v}}</a></span>
         {{else}}
              <span class="pageBtn"><a href="/address/{{$v}}/{{$.paginator.PageSize}}">{{$v}}</a></span>
         {{end}}
     {{end}}
     {{if ne .paginator.Page .paginator.PageTotal}}
          <span class="pageBtn"><a href="/address/{{.paginator.NextPage}}/{{.paginator.PageSize}}">下一页</a></span>
          <span class="pageBtn"><a href="/address/{{.paginator.PageTotal}}/{{.paginator.PageSize}}">尾页</a></span>
     {{end}}
</div>

效果:

原文地址:https://www.cnblogs.com/wujuntian/p/12073909.html