整合營(yíng)銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          Bootstrap-table 使用總結(jié)

          、什么是Bootstrap-table?

          在業(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?

          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ù)展示。

          三、Bootstrap-table詳解:

          1)整個(gè)JS屬性配置

          以上圖為例,上圖展示結(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ō)明,是比較容易理解的了。

          2)查詢及分頁(yè)

          這里的表格數(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ù)即可。

          3)格式化輸出函數(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

          四、怎么在Spring MVC及SpringBoot項(xiàng)目中使用Bootstrap-table進(jìn)行分頁(yè)?

          話不多說(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ù)源更新與更改】四部分。

          1. 3步創(chuàng)建數(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ù)之和)

          2. 插入計(jì)算字段

          需求的結(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)求出完成率,方法如下圖所示:

          1. 選中透視表任意單元格區(qū)域,右擊
          2. 選擇公式-計(jì)算字段
          3. 輸入字段名稱,輸入公式:公式中的字段在“字段列表”選擇字段插入

          3. 使用切片器

          切片器功能同我們?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è)按鍵,左邊的是多選按鈕,后面的按鍵是取消篩選的按鈕。

          4. 數(shù)據(jù)源刷新和更改

          (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)/折疊按鈕”;

          1. 布局

          數(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)的下方。

          2. 格式

          1. 標(biāo)簽項(xiàng)重復(fù)顯示:如“一、布局”中所述,布局格式選擇中,可進(jìn)行標(biāo)簽是否重復(fù)的設(shè)置。
          2. 顯示/隱藏分類匯總:選中透視表任意單元格區(qū)域,【右擊】,勾選/取消勾選【分類匯總】即可。
          3. 合并行標(biāo)簽:選中透視表任意單元格區(qū)域,【右擊】-【數(shù)據(jù)透視表選項(xiàng)】-【布局和格式選項(xiàng)卡】-【合并且居中排列帶標(biāo)簽的單元格】(只對(duì)表格形式布局有效)
          4. 插入空行間隔:【設(shè)計(jì)】選項(xiàng)卡- 【布局】-【空行】-【在每個(gè)項(xiàng)目后插入空行】
          5. 取消字段前”+-“符:選中透視表任意單元格區(qū)域,【右擊】-【數(shù)據(jù)透視表選項(xiàng)】-【展開(kāi)/折疊按鈕】

          三、組合功能

          數(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ù)子集

          1. 按時(shí)間組合

          在工作場(chǎng)景中,一般會(huì)獲取時(shí)間范圍(幾個(gè)月)的天維度的明細(xì)數(shù)據(jù)為一個(gè)數(shù)據(jù)源,在通過(guò)透視表進(jìn)行分析。比如:想看本季度各月各部門電話量的完成情況,對(duì)于這一需求,可對(duì)日期進(jìn)行組合。

          具體方法如下圖所示:選中透視表日期列任意單元格,右擊,選擇【組合】,進(jìn)行分組設(shè)置,可根據(jù)需求更改起始日期,從完成日期列表中選擇分類維度“月/季度/年……”,即可生成我們需要的數(shù)據(jù)格式。

          2. 按數(shù)值組合

          如果是統(tǒng)計(jì)得分情況或年齡分段情況等數(shù)據(jù)列數(shù)值的分布情況,就需要用到透視表的數(shù)值分組,選中“分值”列的任意單元格,右鍵選擇“創(chuàng)建組”,在組合中可設(shè)置起始和結(jié)尾以及步長(zhǎng)。

          3. 文本分組

          如果是按地區(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. 透視表技巧

          (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)為普通表格:粘貼為值

          2. 3點(diǎn)學(xué)習(xí)建議(同上篇)

          (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ò)誤之處歡迎大家指正/交流。

          #相關(guān)閱讀#

          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é)議


          主站蜘蛛池模板: 亲子乱AV视频一区二区| 一区二区在线播放视频| 国产激情一区二区三区| 久久久无码精品国产一区| 香蕉久久ac一区二区三区| 狠狠综合久久AV一区二区三区| 精品一区二区三区在线成人 | 日韩熟女精品一区二区三区| 国产一区玩具在线观看| 国产精品久久无码一区二区三区网| 在线精品动漫一区二区无广告| 五月婷婷一区二区| 亚洲国产精品乱码一区二区| 成人免费一区二区三区在线观看| 久久国产一区二区三区| 一区二区三区无码高清| 在线观看日韩一区| 在线观看精品视频一区二区三区| 国产在线无码视频一区二区三区| 色综合视频一区二区三区| 精品少妇人妻AV一区二区| 夜色福利一区二区三区| 国产AV午夜精品一区二区三| 亚洲高清成人一区二区三区| 国产aⅴ一区二区| 日本丰满少妇一区二区三区 | 精品理论片一区二区三区| 无码一区二区三区AV免费| 国模精品视频一区二区三区| 亚洲av成人一区二区三区| 东京热无码一区二区三区av| 精品无人区一区二区三区 | 少妇激情一区二区三区视频| 中文字幕一区二区三区在线播放| 一区二区三区视频免费| 亚洲熟女乱综合一区二区| 国产精品视频一区二区三区不卡| 日韩一区二区三区视频| 无码人妻一区二区三区免费视频| 无码人妻一区二区三区精品视频 | 一区二区三区在线看|