在業(yè)務(wù)系統(tǒng)開(kāi)發(fā)中,對(duì)表格記錄的查詢、分頁(yè)、排序等處理是非常常見(jiàn)的,在Web開(kāi)發(fā)中,可以采用很多功能強(qiáng)大的插件來(lái)滿足要求,且能極大的提高開(kāi)發(fā)效率,本隨筆介紹這個(gè)bootstrap-table是一款非常有名的開(kāi)源表格插件,在很多項(xiàng)目中廣泛的應(yīng)用。Bootstrap-table插件提供了非常豐富的屬性設(shè)置,可以實(shí)現(xiàn)查詢、分頁(yè)、排序、復(fù)選框、設(shè)置顯示列、Card view視圖、主從表顯示、合并列、國(guó)際化處理等處理功能,而且該插件同時(shí)也提供了一些不錯(cuò)的擴(kuò)展功能,如移動(dòng)行、移動(dòng)列位置等一些特殊的功能,插件可以用基于HTML5的data-*屬性標(biāo)識(shí)設(shè)置,也可以使用Javascript方式進(jìn)行設(shè)置,非常方便。本篇隨筆介紹bootstrap-table插件在我實(shí)際項(xiàng)目中的應(yīng)用情況,總結(jié)相關(guān)使用中碰到的問(wèn)題處理經(jīng)驗(yàn)。
Bootstrap-Table顯示數(shù)據(jù)到表格的方式有兩種,一種是客戶端(client)模式,一種是服務(wù)器(server)模式。
客戶端模式:指的是在服務(wù)器中把要顯示到表格的數(shù)據(jù)一次性加載出來(lái),然后轉(zhuǎn)換成JSON格式傳到要顯示的界面中,客戶端模式較為簡(jiǎn)單,它是把數(shù)據(jù)一次性加載出來(lái)放到界面上,然后根據(jù)你設(shè)置的每頁(yè)記錄數(shù),自動(dòng)生成分頁(yè)。當(dāng)點(diǎn)擊第二頁(yè)時(shí),會(huì)自動(dòng)加載出數(shù)據(jù),不會(huì)再向服務(wù)器發(fā)送請(qǐng)求。同時(shí)用戶可以使用其自帶的搜索功能,可以實(shí)現(xiàn)全數(shù)據(jù)搜索。對(duì)于數(shù)據(jù)量較少的時(shí)候,可以使用這個(gè)方法。
服務(wù)器模式:指的是根據(jù)設(shè)定的每頁(yè)記錄數(shù)和當(dāng)前要顯示的頁(yè)碼,發(fā)送數(shù)據(jù)到服務(wù)器進(jìn)行查詢,然后再顯示到表格中。該方法可以根據(jù)用戶的需要?jiǎng)討B(tài)的加載數(shù)據(jù),節(jié)省了服務(wù)器的資源,但是不能使用其自帶的全數(shù)據(jù)搜索功能。
Bootstrap-table是基于Boostrap開(kāi)發(fā)的插件,因此使用的時(shí)候,需要引入Bootstrap的腳本和樣式。
如果我們項(xiàng)目中沒(méi)有引入相關(guān)的文件,則需要引入這些樣式和腳本文件,如下所示。
1 <link rel="stylesheet" href="bootstrap.min.css">
2 <script src="jquery.min.js"></script>
3 <script src="bootstrap.min.js"></script>
然后是Bootstrap-table的依賴引用:
CSS文件引入
1 <link rel="stylesheet" href="bootstrap-table.css">
腳本文件引入
1 <script src="bootstrap-table.js"></script>
2 <--漢化文件,放在 bootstrap-table.js 后面-->
3 <script src="bootstrap-table-zh-CN.js"></script>
bootstrap-table在頁(yè)面中的使用,可以分為兩種,一種是純粹用HTML5的寫(xiě)法,通過(guò)data-*的方式指定各種屬性設(shè)置,一種是HTML+JS方式實(shí)現(xiàn)彈性設(shè)置。
如果我們采用HTML5標(biāo)識(shí)的方式初始化HTML代碼,則是下面的代碼。
1 <table data-toggle="table" data-url="data1.json">
2 <thead>
3 <tr>
4 <th data-field="id">Item ID</th>
5 <th data-field="name">Item Name</th>
6 <th data-field="price">Item Price</th>
7 </tr>
8 </thead>
9 </table>
如果我們采用JS代碼方式來(lái)初始化表格插件,那么只需要在HTML上聲明一個(gè)表格對(duì)象即可,如下代碼。
1 <table id="table"></table>
js代碼如下:
1 $('#table').bootstrapTable({
2 url: 'data1.json',
3 columns: [{
4 field: 'id',
5 title: 'Item ID'
6 }, {
7 field: 'name',
8 title: 'Item Name'
9 }, {
10 field: 'price',
11 title: 'Item Price'
12 }, ]
13 });
不過(guò)實(shí)際上我們使用 bootstrap-table的JS配置功能肯定比這個(gè)復(fù)雜很多,下面界面效果是實(shí)際表的數(shù)據(jù)展示。
以上圖為例,上圖展示結(jié)果的JS代碼如下所示:
1 var $table;
2 //初始化bootstrap-table的內(nèi)容
3 function InitMainTable () {
4 //記錄頁(yè)面bootstrap-table全局變量$table,方便應(yīng)用
5 var queryUrl = '/TestUser/FindWithPager?rnd=' + Math.random()
6 $table = $('#grid').bootstrapTable({
7 url: queryUrl, //請(qǐng)求后臺(tái)的URL(*)
8 method: 'GET', //請(qǐng)求方式(*)
9 //toolbar: '#toolbar', //工具按鈕用哪個(gè)容器
10 striped: true, //是否顯示行間隔色
11 cache: false, //是否使用緩存,默認(rèn)為true,所以一般情況下需要設(shè)置一下這個(gè)屬性(*)
12 pagination: true, //是否顯示分頁(yè)(*)
13 sortable: true, //是否啟用排序
14 sortOrder: "asc", //排序方式
15 sidePagination: "server", //分頁(yè)方式:client客戶端分頁(yè),server服務(wù)端分頁(yè)(*)
16 pageNumber: 1, //初始化加載第一頁(yè),默認(rèn)第一頁(yè),并記錄
17 pageSize: rows, //每頁(yè)的記錄行數(shù)(*)
18 pageList: [10, 25, 50, 100], //可供選擇的每頁(yè)的行數(shù)(*)
19 search: false, //是否顯示表格搜索
20 strictSearch: true,
21 showColumns: true, //是否顯示所有的列(選擇顯示的列)
22 showRefresh: true, //是否顯示刷新按鈕
23 minimumCountColumns: 2, //最少允許的列數(shù)
24 clickToSelect: true, //是否啟用點(diǎn)擊選中行
25 //height: 500, //行高,如果沒(méi)有設(shè)置height屬性,表格自動(dòng)根據(jù)記錄條數(shù)覺(jué)得表格高度
26 uniqueId: "ID", //每一行的唯一標(biāo)識(shí),一般為主鍵列
27 showToggle: true, //是否顯示詳細(xì)視圖和列表視圖的切換按鈕
28 cardView: false, //是否顯示詳細(xì)視圖
29 detailView: false, //是否顯示父子表
30 //得到查詢的參數(shù)
31 queryParams : function (params) {
32 //這里的鍵的名字和控制器的變量名必須一致,這邊改動(dòng),控制器也需要改成一樣的
33 var temp = {
34 rows: params.limit, //頁(yè)面大小
35 page: (params.offset / params.limit) + 1, //頁(yè)碼
36 sort: params.sort, //排序列名
37 sortOrder: params.order //排位命令(desc,asc)
38 };
39 return temp;
40 },
41 columns: [{
42 checkbox: true,
43 visible: true //是否顯示復(fù)選框
44 }, {
45 field: 'Name',
46 title: '姓名',
47 sortable: true
48 }, {
49 field: 'Mobile',
50 title: '手機(jī)',
51 sortable: true
52 }, {
53 field: 'Email',
54 title: '郵箱',
55 sortable: true,
56 formatter: emailFormatter
57 }, {
58 field: 'Homepage',
59 title: '主頁(yè)',
60 formatter: linkFormatter
61 }, {
62 field: 'Hobby',
63 title: '興趣愛(ài)好'
64 }, {
65 field: 'Gender',
66 title: '性別',
67 sortable: true
68 }, {
69 field: 'Age',
70 title: '年齡'
71 }, {
72 field: 'BirthDate',
73 title: '出生日期',
74 formatter: dateFormatter
75 }, {
76 field: 'Height',
77 title: '身高'
78 }, {
79 field: 'Note',
80 title: '備注'
81 }, {
82 field:'ID',
83 title: '操作',
84 width: 120,
85 align: 'center',
86 valign: 'middle',
87 formatter: actionFormatter
88 }, ],
89 onLoadSuccess: function () {
90 },
91 onLoadError: function () {
92 showTips("數(shù)據(jù)加載失敗!");
93 },
94 onDblClickRow: function (row, $element) {
95 var id = row.ID;
96 EditViewById(id, 'view');
97 },
98 });
99 };
上面JS代碼的配置屬性,基本上都加了注釋說(shuō)明,是比較容易理解的了。
這里的表格數(shù)據(jù)分頁(yè)是采用服務(wù)器分頁(yè)的方式,根據(jù)搜索條件從服務(wù)器返回?cái)?shù)據(jù)記錄的,并使用了排序的處理方式,這里的queryParams參數(shù)就是提交到服務(wù)器端的參數(shù)了。
1 //得到查詢的參數(shù)
2 queryParams : function (params) {
3 //這里的鍵的名字和控制器的變量名必須一直,這邊改動(dòng),控制器也需要改成一樣的
4 var temp = {
5 rows: params.limit, //頁(yè)面大小
6 page: (params.offset / params.limit) + 1, //頁(yè)碼
7 sort: params.sort, //排序列名
8 sortOrder: params.order //排位命令(desc,asc)
9 };
10 return temp;
11 },
另外我們看到返回?cái)?shù)據(jù)的URL地址接口是FindWithPager,我們來(lái)看看這個(gè)MVC控制器方法是如何處理數(shù)據(jù)返回的。
1 /// <summary>
2 /// 根據(jù)條件查詢數(shù)據(jù)庫(kù),并返回對(duì)象集合(用于分頁(yè)數(shù)據(jù)顯示)
3 /// </summary>
4 /// <returns>指定對(duì)象的集合</returns>
5 public override ActionResult FindWithPager()
6 {
7 //檢查用戶是否有權(quán)限,否則拋出MyDenyAccessException異常
8 base.CheckAuthorized(AuthorizeKey.ListKey);
9
10 string where = GetPagerCondition();
11 PagerInfo pagerInfo = GetPagerInfo();
12 var sort = GetSortOrder();
13
14 List<TestUserInfo> list = null;
15 if (sort != null && !string.IsNullOrEmpty(sort.SortName))
16 {
17 list = baseBLL.FindWithPager(where, pagerInfo, sort.SortName, sort.IsDesc);
18 }
19 else
20 {
21 list = baseBLL.FindWithPager(where, pagerInfo);
22 }
23
24 //Json格式的要求{total:22,rows:{}}
25 //構(gòu)造成Json的格式傳遞
26 var result = new { total = pagerInfo.RecordCount, rows = list };
27 return ToJsonContent(result);
28 }
面代碼處理了兩個(gè)部分的對(duì)象信息,一個(gè)是分頁(yè)實(shí)體類信息,一個(gè)是排序信息,然后根據(jù)這些條件獲取記錄,返回類似
{total:22,rows:{}}
格式的JSON數(shù)據(jù)記錄。
1 var result = new { total = pagerInfo.RecordCount, rows = list };
2 return ToJsonContent(result);
獲取分頁(yè)的參數(shù)信息如下所示
1 /// <summary>
2 /// 根據(jù)Request參數(shù)獲取分頁(yè)對(duì)象數(shù)據(jù)
3 /// </summary>
4 /// <returns></returns>
5 protected virtual PagerInfo GetPagerInfo()
6 {
7 int pageIndex = Request["page"] == null ? 1 : int.Parse(Request["page"]);
8 int pageSize = Request["rows"] == null ? 10 : int.Parse(Request["rows"]);
9
10 PagerInfo pagerInfo = new PagerInfo();
11 pagerInfo.CurrenetPageIndex = pageIndex;
12 pagerInfo.PageSize = pageSize;
13
14 return pagerInfo;
15 }
獲取排序參數(shù)信息的代碼如下所示
1 /// <summary>
2 /// 獲取排序的信息
3 /// </summary>
4 /// <returns></returns>
5 protected SortInfo GetSortOrder()
6 {
7 var name = Request["sort"];
8 var order = Request["sortOrder"];
9 return new SortInfo(name, order);
10 }
最后就是具體實(shí)現(xiàn)具體條件、具體頁(yè)碼、具體排序條件下的數(shù)據(jù)記錄了,這部分可以根據(jù)自己的要求實(shí)現(xiàn)邏輯,這里只是給出一個(gè)封裝好的處理調(diào)用即可。
baseBLL.FindWithPager(where, pagerInfo, sort.SortName, sort.IsDesc);
實(shí)際情況下,我們列表的展示,一般需要使用不同的條件進(jìn)行數(shù)據(jù)的查詢的,雖然這個(gè)Bootstrap-table控件提供了一個(gè)默認(rèn)的查詢按鈕,不過(guò)一般是在客戶端分頁(yè)的情況下使用,而且略顯簡(jiǎn)單,我們一般使用自己查詢條件進(jìn)行處理,如下界面所示。
或者如下:
那么這樣對(duì)于上面的js屬性就需要調(diào)整下接受查詢條件參數(shù)queryParams 了
1 //得到查詢的參數(shù)
2 queryParams : function (params) {
3 //這里的鍵的名字和控制器的變量名必須一直,這邊改動(dòng),控制器也需要改成一樣的
4 var temp = {
5 rows: params.limit, //頁(yè)面大小
6 page: (params.offset / params.limit) + 1, //頁(yè)碼
7 sort: params.sort, //排序列名
8 sortOrder: params.order //排位命令(desc,asc)
9 };
10 return temp;
11 },
對(duì)于自定義查詢條件,我們可以用下面的常規(guī)方式增加參數(shù),如下所示
但是查詢條件的參數(shù)我們不方便一一設(shè)置,我們想通過(guò)一種較為快捷的方式來(lái)處理,那么就需要對(duì)這個(gè)處理方式進(jìn)行一個(gè)特別的修改了,首先添加一個(gè)擴(kuò)展函數(shù)來(lái)處理表單的條件(參考博客http://www.cnblogs.com/zcsj/p/6635677.html的介紹)
1 //自定義函數(shù)處理queryParams的批量增加
2 $.fn.serializeJsonObject = function () {
3 var json = {};
4 var form = this.serializeArray();
5 $.each(form, function () {
6 if (json[this.name]) {
7 if (!json[this.name].push) {
8 json[this.name] = [json[this.name]];
9 }
10 json[this.name].push();
11 } else {
12 json[this.name] = this.value || '';
13 }
14 });
15 return json;
16 }
然后我們就可以批量處理表單的查詢條件了
1 queryParams : function (params) {
2 //這里的鍵的名字和控制器的變量名必須一直,這邊改動(dòng),控制器也需要改成一樣的
3 var temp = $("#ffSearch").serializeJsonObject();
4 temp["rows"] = params.limit; //頁(yè)面大小
5 temp["page"] = (params.offset / params.limit) + 1; //頁(yè)碼
6 temp["sort"] = params.sort; //排序列名
7 temp["sortOrder"] = params.order; //排位命令(desc,asc)
8
9 //特殊格式的條件處理
10 temp["WHC_Age"] = $("#WHC_Age").val() + "~" + $("#WHC_Age2").val();
11 temp["WHC_BirthDate"] = $("#WHC_BirthDate").val() + "~" + $("#WHC_BirthDate2").val();
12
13 return temp;
14 },
然后后端統(tǒng)一按照邏輯處理查詢參數(shù)即可。
對(duì)于上面JS的配置信息,我們?cè)賮?lái)回顧一下,例如對(duì)于數(shù)據(jù)轉(zhuǎn)義函數(shù),可以格式化輸出的內(nèi)容的,如下界面代碼。
格式化的數(shù)據(jù)轉(zhuǎn)義函數(shù)如下,主要就是根據(jù)內(nèi)容進(jìn)行格式化輸出的JS函數(shù),好像是需要放在一個(gè)文件內(nèi)。
1 //連接字段格式化
2 function linkFormatter(value, row, index) {
3 return "<a href='" + value + "' title='單擊打開(kāi)連接' target='_blank'>" + value + "</a>";
4 }
5 //Email字段格式化
6 function emailFormatter(value, row, index) {
7 return "<a href='mailto:" + value + "' title='單擊打開(kāi)連接'>" + value + "</a>";
8 }
9 //性別字段格式化
10 function sexFormatter(value) {
11 if (value == "女") { color = 'Red'; }
12 else if (value == "男") { color = 'Green'; }
13 else { color = 'Yellow'; }
14
15 return '<div style="color: ' + color + '">' + value + '</div>';
16 }
另外,我們看到行記錄的最后增加了幾個(gè)操作按鈕,方便對(duì)當(dāng)前記錄的查看、編輯和刪除操作,如下效果圖所示。
這部分我們也是通過(guò)格式化函數(shù)進(jìn)行處理的
1 //操作欄的格式化
2 function actionFormatter(value, row, index) {
3 var id = value;
4 var result = "";
5 result += "<a href='javascript:;' class='btn btn-xs green' onclick=\"EditViewById('" + id + "', view='view')\" title='查看'><span class='glyphicon glyphicon-search'></span></a>";
6 result += "<a href='javascript:;' class='btn btn-xs blue' onclick=\"EditViewById('" + id + "')\" title='編輯'><span class='glyphicon glyphicon-pencil'></span></a>";
7 result += "<a href='javascript:;' class='btn btn-xs red' onclick=\"DeleteByIds('" + id + "')\" title='刪除'><span class='glyphicon glyphicon-remove'></span></a>";
8
9 return result;
10 }
如果我們需要雙擊彈出編輯界面的層,我們可以處理表格的雙擊事件,如下代碼所示。
1 onDblClickRow: function (row, $element) {
2 var id = row.ID;
3 EditViewById(id, 'view');
4 },
如果我們需要設(shè)置行的不同的樣式展示,可以通過(guò)增加rowStyle的JS處理函數(shù)即可,如下代碼所示
1 rowStyle: function (row, index) { //設(shè)置行的特殊樣式
2 //這里有5個(gè)取值顏色['active', 'success', 'info', 'warning', 'danger'];
3 var strclass = "";
4 if (index == 0) {
5 strclass = "warning";
6 }
7 return { classes: strclass }
8 }
對(duì)于表格記錄的獲取,我們可以通過(guò)下面的代碼進(jìn)行獲取:$table.bootstrapTable('getSelections')
1 var rows = $table.bootstrapTable('getSelections');
2 if (rows.length > 0) {
3 ID = rows[0].ID;
4 }
如果是多條記錄的處理,例如刪除記錄
1 //實(shí)現(xiàn)刪除數(shù)據(jù)的方法
2 function Delete() {
3 var ids = "";//得到用戶選擇的數(shù)據(jù)的ID
4 var rows = $table.bootstrapTable('getSelections');
5 for (var i = 0; i < rows.length; i++) {
6 ids += rows[i].ID + ',';
7 }
8 ids = ids.substring(0, ids.length - 1);
9
10 DeleteByIds(ids);
11 }
如果需要設(shè)置顯示列顯示,如下界面所示
以及排序處理
這些需要在JS代碼開(kāi)啟相關(guān)的屬性即可。
還有就是一種CardView的卡片視圖格式,如下所示。
另外一種是父子表的展開(kāi)明細(xì)的格式,如下所示
以上就是bootstrap-table插件在我實(shí)際項(xiàng)目中的應(yīng)用情況,基本上對(duì)JS各個(gè)屬性的使用進(jìn)行了一些介紹了,具體的應(yīng)用我們可以參考它的文檔,獲取對(duì)應(yīng)屬性、方法、事件的詳細(xì)說(shuō)明,這樣我們就可以更加詳細(xì)的應(yīng)用這個(gè)插件的各種功能了。
http://bootstrap-table.wenzhixin.net.cn/documentation/
PS:以上為轉(zhuǎn)載內(nèi)容,經(jīng)過(guò)自己的梳理后重新發(fā)布,感謝原作者伍華聰,原文路徑:https://www.cnblogs.com/wuhuacong/p/7284420.html
話不多說(shuō),直接上代碼。
前端代碼塊:
頁(yè)面:
1 <table id="test-table" class="col-xs-12" data-toolbar="#toolbar">
JS:
2 function initTable(){
3 $('#test-table').bootstrapTable({
4 method: 'get',
5 toolbar: '#toolbar', //工具按鈕用哪個(gè)容器
6 striped: true, //是否顯示行間隔色
7 cache: false, //是否使用緩存,默認(rèn)為true,所以一般情況下需要設(shè)置一下這個(gè)屬性(*)
8 pagination: true, //是否顯示分頁(yè)(*)
9 sortable: false, //是否啟用排序
10 sortOrder: "asc", //排序方式
11 pageNumber:1, //初始化加載第一頁(yè),默認(rèn)第一頁(yè)
12 pageSize: 10, //每頁(yè)的記錄行數(shù)(*)
13 pageList: [10, 25, 50, 100], //可供選擇的每頁(yè)的行數(shù)(*)
14 url: "/testProject/page4list.json",//這個(gè)接口需要處理bootstrap table傳遞的固定參數(shù)
15 queryParamsType:'', //默認(rèn)值為 'limit' ,在默認(rèn)情況下 傳給服務(wù)端的參數(shù)為:offset,limit,sort
16 // 設(shè)置為 '' 在這種情況下傳給服務(wù)器的參數(shù)為:pageSize,pageNumber
17
18 //queryParams: queryParams,//前端調(diào)用服務(wù)時(shí),會(huì)默認(rèn)傳遞上邊提到的參數(shù),如果需要添加自定義參數(shù),可以自定義一個(gè)函數(shù)返回請(qǐng)求參數(shù)
19 sidePagination: "server", //分頁(yè)方式:client客戶端分頁(yè),server服務(wù)端分頁(yè)(*)
20 //search: true, //是否顯示表格搜索,此搜索是客戶端搜索,不會(huì)進(jìn)服務(wù)端,所以,個(gè)人感覺(jué)意義不大
21 strictSearch: true,
22 //showColumns: true, //是否顯示所有的列
23 //showRefresh: true, //是否顯示刷新按鈕
24 minimumCountColumns: 2, //最少允許的列數(shù)
25 clickToSelect: true, //是否啟用點(diǎn)擊選中行
26 searchOnEnterKey: true,
27 columns: [{
28 field: 'id',
29 title: 'id',
30 align: 'center'
31 }, {
32 field: 'testkey',
33 title: '測(cè)試標(biāo)識(shí)',
34 align: 'center'
35 }, {
36 field: 'testname',
37 title: '測(cè)試名字',
38 align: 'center'
39 },{
40 field: 'id',
41 title: '操作',
42 align: 'center',
43 formatter:function(value,row,index){
44 //通過(guò)formatter可以自定義列顯示的內(nèi)容
45 //value:當(dāng)前field的值,即id
46 //row:當(dāng)前行的數(shù)據(jù)
47 var a = '<a href="" >測(cè)試</a>';
48 }
49 }],
50 pagination:true
51 });
52 }
在前端通過(guò)請(qǐng)求獲取table數(shù)據(jù)時(shí),bootstrap table會(huì)默認(rèn)拼一個(gè) searchText的參數(shù),來(lái)支持查詢功能。
服務(wù)端代碼:
1 @RequestMapping(value = "/page4list.json")
2 public void page4list(Integer pageSize, Integer pageNumber, String searchText, HttpServletRequest request,
3 HttpServletResponse response) {
4
5 //搜索框功能
6 //當(dāng)查詢條件中包含中文時(shí),get請(qǐng)求默認(rèn)會(huì)使用ISO-8859-1編碼請(qǐng)求參數(shù),在服務(wù)端需要對(duì)其解碼
7 if (null != searchText) {
8 try {
9 searchText = new String(searchText.getBytes("ISO-8859-1"), "UTF-8");
10 } catch (Exception e) {
11 e.printStackTrace();
12 }
13 }
14 //在service通過(guò)條件查詢獲取指定頁(yè)的數(shù)據(jù)的list
15 List<MwmsgType> list = mwMsgQueueService.page4List(pageSize, pageNumber, searchText);
16 //根據(jù)查詢條件,獲取符合查詢條件的數(shù)據(jù)總量
17 int total = mwMsgQueueService.queryCountBySearchText(searchText);
18 //自己封裝的數(shù)據(jù)返回類型,bootstrap-table要求服務(wù)器返回的json數(shù)據(jù)必須包含:totlal,rows兩個(gè)節(jié)點(diǎn)
19 PageResultForBootstrap page = new PageResultForBootstrap();
20 page.setTotal(total);
21 page.setRows(list);
22 //page就是最終返回給客戶端的數(shù)據(jù)結(jié)構(gòu),可以直接返回給前端
23
24 //下邊這段,只是我自己的代碼有自定義的spring HandlerInterceptor處理返回值,可以忽略。
25 request.setAttribute(Constants.pageResultData, page);
26
27 }
完成上述代碼,即可實(shí)現(xiàn)服務(wù)器端自動(dòng)分頁(yè),bootstrap-table根據(jù)服務(wù)器端返回的total,以及table設(shè)定的pageSize,自動(dòng)生成分頁(yè)的頁(yè)面元素,每次點(diǎn)擊下一頁(yè)或者指定頁(yè)碼,bootstrap-table會(huì)自動(dòng)給參數(shù)pageNumber賦值,服務(wù)器返回指定頁(yè)的數(shù)據(jù)。
如果發(fā)送的是post請(qǐng)求,因?yàn)閎ootstap table使用的是ajax方式獲取數(shù)據(jù),這時(shí)會(huì)將請(qǐng)求的content type默認(rèn)設(shè)置為 text/plain,這樣在服務(wù)端直接通過(guò) @RequestParam參數(shù)映射是獲取不到的。
這時(shí)就需要在bootstrap-table的參數(shù)列表中顯式設(shè)置:
1 contentType: "application/x-www-form-urlencoded"
設(shè)置成form表單的形式,tomcat內(nèi)部就會(huì)自動(dòng)將requset payload中的數(shù)據(jù)部分解析放到request.getParameter()中,之后就可以直接通過(guò)@RequestParam映射參數(shù)獲取。
天,小編為大家展示一下,用純table搭建頁(yè)面結(jié)構(gòu),實(shí)現(xiàn)QQ登陸頁(yè)(為初學(xué)者作參考,頁(yè)面結(jié)構(gòu)搭建方式很多,這種基本上就只初學(xué)table才會(huì)用的)
小編的素材
上代碼截圖:
有興趣的同學(xué)可以去試試吧。
更多基礎(chǔ)練習(xí)案例,私信小編回復(fù)“html”獲得。
章為B端產(chǎn)品經(jīng)理根據(jù)入職1年來(lái)工作所需,結(jié)合Excel線上課程所學(xué),總結(jié)沉淀的數(shù)據(jù)透視表文檔。
作者嘗試用兩篇(函數(shù)篇+透視表篇)講述初階產(chǎn)品Excel80%職場(chǎng)需求,接上篇,本篇講述數(shù)據(jù)透視表部分。
本文將從如下圖所示 基本操作、布局與格式、組合功能、技巧四個(gè)部分進(jìn)行講述,只要用心掌握以下四個(gè)部分,基本解決80%的難題,工作效率會(huì)有質(zhì)的提升。
基本操作包括【創(chuàng)建透視表基本操作】、【插入計(jì)算字段】、【使用切片器】、【數(shù)據(jù)源更新與更改】四部分。
那什么是數(shù)據(jù)透視表?
數(shù)據(jù)透視表是交互式的匯總和分析數(shù)據(jù)的工具,簡(jiǎn)單來(lái)說(shuō)就是把明細(xì)表進(jìn)行分類匯總的過(guò)程,可以使用戶通過(guò)簡(jiǎn)單的拖拽操作,完成復(fù)雜的數(shù)據(jù)分類匯總,可以說(shuō)是Excel中最實(shí)用、最常用的功能。所謂“透視”,即從數(shù)據(jù)背后找到聯(lián)系,從而將看似雜亂的數(shù)據(jù)轉(zhuǎn)化為有價(jià)值的信息。
結(jié)合函數(shù)理解數(shù)據(jù)透視表及其基本操作:
舉個(gè)例子:A公司銷售的KPI要求為“每天30秒以上電話數(shù)/人為25個(gè)”,現(xiàn)需統(tǒng)計(jì)12月2日各部門KPI完成情況。如下:左圖為A公司12月2日銷售外呼數(shù)據(jù),右圖為需要獲取的A公司銷售部各部門KPI完成情況(部門完成率=部門實(shí)際值總和/部門目標(biāo)值總和)。
根據(jù)上篇內(nèi)容,我們可以用SUMIF函數(shù),快速計(jì)算出銷售一部、銷售二部、銷售三部的30秒電話數(shù)和30秒電話數(shù)目標(biāo)值,最后在完成率列輸入公式=I4/J4計(jì)算出完成率,如下:
函數(shù)計(jì)算的方法,雖然也能較快的計(jì)算出我們需要的結(jié)果,但效率不高(這里畢竟只是計(jì)算2個(gè)值,如果我們計(jì)算的值較多時(shí)效率問(wèn)題會(huì)更明顯)。在此,我們介紹快速按需求獲取匯總數(shù)據(jù)的方法-數(shù)據(jù)透視表:
第一步:選中目標(biāo)數(shù)據(jù):選中目標(biāo)區(qū)域任意單元格,Ctrl+A。
第二步:插入數(shù)據(jù)透視表:【插入】選項(xiàng)卡-【數(shù)據(jù)透視表】,【創(chuàng)建數(shù)據(jù)透視表】彈窗:“選擇要分析的數(shù)據(jù)”(默認(rèn)即可)和“選擇要放置數(shù)據(jù)透視表的位置(現(xiàn)有工作表)”。彈窗選項(xiàng)說(shuō)明如下:
(1)【請(qǐng)選擇要分析的數(shù)據(jù)】:如針對(duì)工作簿內(nèi)數(shù)據(jù)分析,則點(diǎn)擊“選擇一個(gè)表或區(qū)域”(因?yàn)槲覀儾迦霐?shù)據(jù)透視表前,已經(jīng)選擇區(qū)域,所以一般情況下,此處默認(rèn)即可,也可以進(jìn)行修改);針對(duì)非工作簿內(nèi)數(shù)據(jù)分析,則點(diǎn)擊“使用外部數(shù)據(jù)源”。
(2)【選擇要放置數(shù)據(jù)透視表的位置】:如數(shù)據(jù)字段數(shù)較多且分析較復(fù)雜的情況下,一般選擇“新工作表”,會(huì)在新的“sheet”中生成透視表;數(shù)據(jù)字段數(shù)較少的情況下,可選擇“現(xiàn)有工作表”,在當(dāng)前“sheet”中所選區(qū)域生成透視表。
第三步:選擇字段,生成透視表:從【字段名稱】列表里,點(diǎn)擊字段拖拽至“篩選器、列、行、值”當(dāng)中,如下圖所示:給到的案例比較簡(jiǎn)單,只需要【行】和【值】?jī)刹糠旨纯色@取需要的結(jié)果。透視表結(jié)構(gòu)如下圖,詳細(xì)說(shuō)明如下:
(1)行、列、值的應(yīng)用:數(shù)據(jù)維度方在行,自變量放在列(因變量為值)。
如果我們想要看的是每一天,不同部門“30秒電話量總和”的差異,則日期是我們查看的數(shù)據(jù)維度(按照日期把數(shù)據(jù)拆分組,一個(gè)日期為一組數(shù)據(jù),占到一行,呈現(xiàn)出來(lái)的就是有多少個(gè)日期就會(huì)有多少行數(shù)據(jù));部門是自變量;而“某天某部門的30秒電話量總和”是因變量。
如果我們想要看的是同一部門,不同日期“30秒電話量總和”的差異,則部門是我們查看的數(shù)據(jù)維度(按照部門把數(shù)據(jù)拆分組,一個(gè)部門為一組數(shù)據(jù),占到一行,呈現(xiàn)出來(lái)的就是有多少個(gè)部門就會(huì)有多少行數(shù)據(jù));日期是自變量;而“某部門某日期的30秒電話量”是因變量。
(2)值:匯總方式和顯示方式介紹如下
匯總方式:如上所說(shuō)的因變量-某日期某部門30秒電話量總和,即對(duì)數(shù)據(jù)源表的數(shù)據(jù)進(jìn)行求和,求和就是匯總方式。常用的主要是求和和計(jì)數(shù);
數(shù)據(jù)顯示方式:即將匯總出來(lái)的結(jié)果以某種方式展示,從而更清晰的看出數(shù)據(jù)之間的關(guān)系和邏輯。常用的主要是總計(jì)的百分比和父行匯總的百分比;
①總計(jì)的百分比:個(gè)體占總體的情況,每一項(xiàng)分類匯總的值占總計(jì)的百分比。如:“某日期某部門30秒電話量總和” 占“數(shù)據(jù)源中所有日期、所有部門30秒電話量總和”的百分比
②父級(jí)百分比:個(gè)體占局部的情況,局部百分比。某列*行字段的匯總結(jié)果/行字段*所有列(即父行)的匯總結(jié)果(如上左圖:12月2日銷售二部的30秒電話數(shù)之和/12月2日所有部門的30秒電話數(shù)之和)
需求的結(jié)果數(shù)據(jù)一般情況下都可使用“值”字段生成,因?yàn)椤爸怠弊侄沃械?strong>匯總方式包含了使用頻率較高的通用的計(jì)算功能,但有一定的局限,而計(jì)算字段極大擴(kuò)展了數(shù)據(jù)透視表的計(jì)算功能。
比如原始數(shù)據(jù)表中有一列數(shù)據(jù)為目標(biāo)值,有一列數(shù)據(jù)為實(shí)際值,那么在數(shù)據(jù)透視表中可以通過(guò)計(jì)算字段輸入公式=30秒電話量/30秒電話量目標(biāo)值,來(lái)求出完成率,方法如下圖所示:
切片器功能同我們?nèi)粘J褂玫臄?shù)據(jù)報(bào)表(或產(chǎn)品在設(shè)計(jì)報(bào)表功能)時(shí)的篩選項(xiàng)是一樣的,如下圖所示,的數(shù)據(jù)報(bào)表中支持按日期篩選,2010版以上的excel版本的切片器功能也可以實(shí)現(xiàn),方法如下。
選中數(shù)據(jù)透視表任意單元格,在【數(shù)據(jù)透視表工具】選項(xiàng)卡下的【選項(xiàng)】子選項(xiàng)卡下單擊【插入切片器】的下拉按鈕,在彈出的【插入切片器】對(duì)話框中勾選自己所需的內(nèi)容即可。切片器對(duì)象的右上角,有兩個(gè)按鍵,左邊的是多選按鈕,后面的按鍵是取消篩選的按鈕。
(1)數(shù)據(jù)源刷新
很多時(shí)候我們的數(shù)據(jù)源是不定期發(fā)生變化的,這就要求在數(shù)據(jù)透視表中也要體現(xiàn)出來(lái),此時(shí)不需要重新創(chuàng)建一個(gè)新的數(shù)據(jù)透視表,刷新一下即可(原基礎(chǔ)上修改,不增加行列的話)。
說(shuō)明:大多數(shù)場(chǎng)景下使用的數(shù)據(jù)源均非外部數(shù)據(jù)源,本文僅介紹的為數(shù)據(jù)源為本工作簿的刷新方法。
1)手動(dòng)刷新數(shù)據(jù)透視表:在數(shù)據(jù)透視表中的任意單元格區(qū)域鼠標(biāo)右鍵,在彈出的快捷菜單中單擊【刷新】命令即可;或,在【數(shù)據(jù)透視表】工具選項(xiàng)卡中,單擊【刷新】/【全部刷新】按鈕。
2)打開(kāi)文件時(shí)刷新數(shù)據(jù)透視表:在數(shù)據(jù)透視表中的任意單元格區(qū)域鼠標(biāo)右鍵,在彈出的快捷菜單中單擊【數(shù)據(jù)透視表選項(xiàng)】命令,在【數(shù)據(jù)】選項(xiàng)卡小紅,勾選“打開(kāi)晚間時(shí)刷新數(shù)據(jù)”。
(2)數(shù)據(jù)源更改
如果增加了行或者列,只是刷新是不行的,還需要更改數(shù)據(jù)源。
1)選中數(shù)據(jù)透視表中的任意單元格區(qū)域,在【數(shù)據(jù)透視表】工具選項(xiàng)卡中,單擊【更改數(shù)據(jù)源】按鈕,更改數(shù)據(jù)源區(qū)域。
2)將數(shù)據(jù)源表設(shè)置成“表格”,選中數(shù)據(jù)源,【插入選項(xiàng)卡】點(diǎn)擊【表格】按鈕,設(shè)置成表格。不管增加行還是列都不需要再去更改數(shù)據(jù)源,只需要刷新即可。(需要注意:只針對(duì)將數(shù)據(jù)源更改為“表格”之后建立的透視表有效)
首先介紹綜合應(yīng)用,1圖看懂布局與格式的作用,3步解決在工作中的需求場(chǎng)景中的布局與格式問(wèn)題:
在涉及到多個(gè)行字段的時(shí),Excel生成的透視表的默認(rèn)格式(如下圖1左)是不滿足我們查看和分析的需要的,一般都期望調(diào)整成常規(guī)的表格格式(如下圖1右)。只需3步操作,操作說(shuō)明如下(見(jiàn)下圖2):
第一步:選中透視表任意單元格,【設(shè)計(jì)】選項(xiàng)卡-【報(bào)表布局】-“表格形式”且“重復(fù)項(xiàng)目標(biāo)簽”;
第二步:選中透視表任意單元格,右擊,取消勾選【分類匯總”…”】。
第三步:選中透視表任意單元格,右擊,選擇【數(shù)據(jù)透視表】-【顯示】,取消“展開(kāi)/折疊按鈕”;
數(shù)據(jù)透視表共有三種布局形式,分別是壓縮形式、大綱形式、表格形式,各有不同的特點(diǎn)。如下圖所示:選中數(shù)據(jù)透視表中的任意單元格區(qū)域,【設(shè)計(jì)】選項(xiàng)卡,點(diǎn)擊【報(bào)表布局】更改布局形式。
壓縮形式:是Excel默認(rèn)的透視表格式,主要的特點(diǎn)是:無(wú)論疊加多少個(gè)行字段,都只占一列,分項(xiàng)匯總顯示在每項(xiàng)的上方。大綱形式:主要特點(diǎn)是:有幾個(gè)行字段就會(huì)占幾列,即行字段會(huì)并排顯示,分項(xiàng)匯總顯示在每項(xiàng)的上方。如下圖,有部門和小組兩個(gè)行字段,大綱形式的布局會(huì)占兩列,而壓縮形式只占一列。表格形式:是最常用的一種形式。主要特點(diǎn)是:與大綱形式一樣,有幾個(gè)行字段就會(huì)占幾列,行字段會(huì)并排顯示,有幾個(gè)行字段會(huì)占幾列;與大綱形式不同的是,表格形式是有表格的(如下圖所示)且分項(xiàng)匯總顯示在每項(xiàng)的下方。
數(shù)據(jù)透視表中的組合功能,一方面能按照給定的跨度對(duì)“日期、數(shù)值等可計(jì)算字段””進(jìn)行組合,比如組合出按年、季度、月、日,甚至小時(shí)、分……的匯總;另一方面,也可通過(guò)手動(dòng)選擇的方式,將文本格式的數(shù)據(jù)按照自定義的方式進(jìn)行組合,比如組合出一線城市、二線城市等等。
通過(guò)組合功能將這些不同數(shù)據(jù)類型的數(shù)據(jù)項(xiàng)按多種組合方式進(jìn)行分組,大大增強(qiáng)了數(shù)據(jù)表分類匯總的延伸性,方便用戶提取滿足特定需求的數(shù)據(jù)子集。
在工作場(chǎng)景中,一般會(huì)獲取時(shí)間范圍(幾個(gè)月)的天維度的明細(xì)數(shù)據(jù)為一個(gè)數(shù)據(jù)源,在通過(guò)透視表進(jìn)行分析。比如:想看本季度各月各部門電話量的完成情況,對(duì)于這一需求,可對(duì)日期進(jìn)行組合。
具體方法如下圖所示:選中透視表日期列任意單元格,右擊,選擇【組合】,進(jìn)行分組設(shè)置,可根據(jù)需求更改起始日期,從完成日期列表中選擇分類維度“月/季度/年……”,即可生成我們需要的數(shù)據(jù)格式。
如果是統(tǒng)計(jì)得分情況或年齡分段情況等數(shù)據(jù)列數(shù)值的分布情況,就需要用到透視表的數(shù)值分組,選中“分值”列的任意單元格,右鍵選擇“創(chuàng)建組”,在組合中可設(shè)置起始和結(jié)尾以及步長(zhǎng)。
如果是按地區(qū)統(tǒng)計(jì)或者個(gè)性化統(tǒng)計(jì)需求,可直接在透視表里面創(chuàng)建文本分組,在需要統(tǒng)計(jì)的列中,按住Ctrl鍵選擇要組合的單元格,然后點(diǎn)擊“鼠標(biāo)右鍵”選擇“創(chuàng)建組”即可,數(shù)據(jù)透視表就會(huì)按照我們所選定的內(nèi)容進(jìn)行組合,可以自行修改組的名稱,例如改為華北大區(qū)。
(1)表頭格式:表頭只能有一行;字段不能為空(相同字段名會(huì)被自動(dòng)添加序號(hào),進(jìn)行區(qū)別)。
(2)不能有合并單元格。如下圖,3步處理數(shù)據(jù)源:取消合并單元格、定位空值、自動(dòng)填充。
(3)數(shù)值類數(shù)據(jù)不能為文本格式。轉(zhuǎn)換成常規(guī)數(shù)值的方法:使用“分列”功能進(jìn)行處理,選中數(shù)據(jù),【數(shù)據(jù)】菜單-選擇“分列”(點(diǎn)擊“下一步”-完成即可)。
(4)需對(duì)透視表數(shù)據(jù)再進(jìn)行函數(shù)計(jì)算的,可將透視表轉(zhuǎn)為普通表格:粘貼為值。
(1)工作中嘗試承接涉及數(shù)據(jù)分析相關(guān)需求,有目標(biāo)、具體場(chǎng)景的情況下學(xué)習(xí)速度會(huì)倍增。執(zhí)行過(guò)程中,會(huì)遇到各種各樣的問(wèn)題,可通過(guò)快速百度查詢、請(qǐng)教數(shù)據(jù)分析的同事等方式解決。
(2)報(bào)名1門exel線上課程(價(jià)格¥150左右),歷時(shí)1個(gè)月。推薦起點(diǎn)學(xué)院的“21天Excel零基礎(chǔ)俗稱訓(xùn)練營(yíng)”https://vip.qidianla.com/course/detail/if5qd.html;
推薦理由:性價(jià)比高、實(shí)用性強(qiáng),表現(xiàn)在:內(nèi)容好、有小節(jié)/章節(jié)作業(yè)檢驗(yàn)+有答疑、有班主任老師管理(時(shí)間節(jié)點(diǎn))+PK/獎(jiǎng)勵(lì)(上課期間還因?yàn)橥獬?周,錯(cuò)過(guò)了1個(gè)星期沒(méi)有結(jié)業(yè))。
(3)輸出exel學(xué)習(xí)經(jīng)驗(yàn)并建立自己的知識(shí)速查表。學(xué)完不是自己的,只有消化吸收了才是自己的。對(duì)于技能學(xué)習(xí)只有孰能生巧一條路,學(xué)習(xí)完課程看似掌握了,但如果學(xué)完前期缺少實(shí)際場(chǎng)景的不斷應(yīng)用,很容易忘記。
所以學(xué)習(xí)完,建議輸出exel學(xué)習(xí)經(jīng)驗(yàn),強(qiáng)化理解吸收;并形成自己的知識(shí)速查表,方便工作中使用快速查詢及不斷完善。
如上,有錯(cuò)誤之處歡迎大家指正/交流。
Excel函數(shù)篇:十個(gè)函數(shù)解決80%職場(chǎng)需求
本文由 @ 團(tuán)團(tuán) 原創(chuàng)發(fā)布于人人都是產(chǎn)品經(jīng)理,未經(jīng)許可,禁止轉(zhuǎn)載
題圖來(lái)自 Unsplash,基于 CC0 協(xié)議
*請(qǐng)認(rèn)真填寫(xiě)需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。