Spring Boot 与 Bootstrap-table 实现商品的分页展示

注意!Bootstrap Table 和 Datatables 不是同一个东西!
要学会看官方文档,Bootstrap-table文档中关于配置项的解释已经非常详细,还附有示例!
有道无术,术尚可求,有术无道,止于术
Spring Boot 与 Bootstrap-table 实现商品的分页展示

// 分页结果数据传输对象
// 通过观察Bootstrap-Table的dataField, totalField => 我们可以知道默认参数名为'rows', 'total'
TableDTO => {
	List<T> rows;
	Long total;
}
formatter 结合font Awesome
formatter => <i class="glyphicon glyphicon-edit"></i>

关于导出报表:
导出使用的插件是bootstrap-table-export.js,而这个插件中使用的是tableExport.jquery.plugin插件。
后者是一个独立的表格导出插件。而前者是经过bootstrap官方将后者与bootstrap表格进行了完美的整合之后的插件。所以我们只需要使用前者即可。

首先前台加载大量数据的话,渲染会非常慢,甚至僵死超时,更不用说导出还要消耗更长的时间,所以该方案不合适
$("#datatable").bootstrapTable('refresh',{url:'/listData'});

html文件

<!doctype html>
<html lang="en">
<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>IceStream 商品列表展示</title>

    <link rel="shortcut icon" href="/campus_shop/static/favicon.ico">

    <link rel="stylesheet" href="/campus_shop/static/plugins/bootstrap/css/bootstrap.min.css">
    <!-- 图标所需CSS -->
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css">
    <link href="https://s3-us-west-2.amazonaws.com/colors-css/2.2.0/colors.min.css" rel="stylesheet">
    <link rel="stylesheet" href="/campus_shop/static/plugins/bootstrap-table/css/bootstrap-table.min.css">
    <link rel="stylesheet"
          href="//rawgit.com/vitalets/x-editable/master/dist/bootstrap3-editable/css/bootstrap-editable.css">

</head>

<body>

<div id="toolbar">
    <div class="form-inline" role="form">
        <div class="form-group">
            <span>页码: </span>
            <input name="pageNumber" class="form-control w70" type="number" value="1">
        </div>
        <div class="form-group">
            <span>显示条数: </span>
            <input name="pageSize" class="form-control w70" type="number" value="10">
        </div>
        <div class="form-group">
            <input name="search" class="form-control" type="text" placeholder="搜索商品...">
        </div>
        <button id="searchButton" type="submit" class="btn btn-primary">搜索</button>
    </div>
</div>

<div class="box-body">
    <a href="#" type="button" class="btn btn-sm btn-primary"><i class="fa fa-plus"></i> 新增</a>&nbsp;&nbsp;&nbsp;
    <button type="button" class="btn btn-sm btn-danger"><i class="fa fa-trash-o"></i> 删除</button>&nbsp;&nbsp;&nbsp;
</div>

<table id="productTable"></table>

<script src="/campus_shop/static/plugins/jquery-3.4.0.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js"></script>
<script src="/campus_shop/static/plugins/bootstrap/js/bootstrap.min.js"></script>
<script src="/campus_shop/static/plugins/bootstrap-table/js/bootstrap-table.min.js"></script>
<script src="/campus_shop/static/plugins/bootstrap-table/js/bootstrap-table-zh-CN.min.js"></script>

<script src="/campus_shop/static/plugins/bootstrap-table/js/bootstrap-table-export.js"></script>
<script src="/campus_shop/static/js/productInfo.js"></script>

</body>
</html>

productInfo.js

$(function () {
    var productTable = $('#productTable');
    var searchButton = $('#searchButton');

    searchButton.click(function () {
        productTable.bootstrapTable('refresh');
    });

    productTable.bootstrapTable({
        url: '/campus_shop/productInfo/page',
        sidePagination: 'server', // 分页方式,client:客户端分页,server:服务端分页
        pagination: true, // 是否进行分页
        striped: true, // 是否显示行间隔色
        cache: false,
        toolbar: '#toolbar', // 指定工具按钮容器
        showRefresh: true, // 是否显示刷新
        showFullscreen: true, // 是否显示全屏
        showToggle: true, // 是否显示详细视图和列表视图的切换按钮
        showExport: true,  // 是否显示导出按钮
        buttonsAlign: "right",  // 按钮位置
        exportTypes: ['json', 'xml', 'csv', 'txt', 'sql', 'excel'],  // 导出文件类型
        exportDataType: 'basic',
        exportOptions: {
            fileName: '商品统计报表',  // 文件名称设置
            worksheetName: 'sheet1',  // 表格工作区名称
            tableName: '商品统计报表',
            excelstyles: ['background-color', 'color', 'font-size', 'font-weight']
        },
        pageNumber: 1, // 初始化加载第一页,默认第一页
        pageSize: 10, // 当前页面显示条数
        uniqueId: 'productId',
        rowStyle: function (row) {
            // 这里有5个取值代表5种颜色 ['active', 'success', 'info', 'warning', 'danger'];
            var rowClass = "";
            if (row.productStatus == 0) {
                rowClass = 'danger';
            } else if (row.productStatus == 1) {
                rowClass = 'success';
            } else {
                return {};
            }
            return {classes: rowClass}
        },
        queryParams: function () {
            var params = {};
            $('#toolbar').find('input[name]').each(function () {
                params[$(this).attr('name')] = $(this).val();
            });
            return params;
        },
        columns: [{
            checkbox: true, // 是否显示复选框
            visible: true,
        }, {
            field: 'productId',
            title: '商品 编号',
            width: "20%",
            align: 'center'
        }, {
            field: 'productName',
            title: '商品 名称',
            width: "30%",
            align: 'center'
        }, {
            field: 'productPrice',
            title: '商品 价格',
            width: "30%",
            align: 'center'
        }, {
            field: 'productStatus',
            title: '商品 状态',
            width: "30%",
            align: 'center',
            formatter: function (value) {
                // value: the field value
                var rowFormat = "";
                if (value == 0) {
                    var rowFormat = "<span style='color:#c12e2a;'><i class='fa fa-ban'></i> " + "下架" + "</span>";
                } else if (value == 1) {
                    var rowFormat = "<span style='color:#3e8f3e'><i class='fa fa-check-circle'></i> " + "正常" + "</span>";
                }
                return rowFormat;
            }
        }]
    });
});

ProductInfoController

/**
 * 分页查询
 *
 * @return 分页结果传输对象
 */
@RequestMapping("/page")
public TableDTO<ProductInfo> productInfoPage(Integer pageNumber, Integer pageSize, 
                                             String search) {
    IPage<ProductInfo> productInfoIPage = productInfoServiceImpl.productPage(pageNumber, pageSize, search);

    return new TableDTO<ProductInfo>(productInfoIPage.getRecords(), productInfoIPage.getTotal());
}

ProductInfoServiceImpl

/**
 * 分页查询
 *
 * @param pageNumber 当前页码
 * @param pageSize   当前页显示条数
 * @param search     搜索关键字
 * @return 分页结果对象
 */
@Override
public IPage<ProductInfo> productPage(Integer pageNumber, Integer pageSize, String search) {
    if (pageNumber == null || pageNumber <= 0) {
        pageNumber = 1;
    }

    if (pageSize == null || pageSize <= 0) {
        pageSize = 10;
    }

    // 构造分页查询条件
    QueryWrapper<ProductInfo> productInfoQueryWrapper = new QueryWrapper<>();

    // 先构造排序条件
    productInfoQueryWrapper.orderByDesc("product_price");

    // 如果有搜索要求,则进行搜索
    if (search != null && search.trim().length() != 0) {
        productInfoQueryWrapper.like("product_name", search);
    }

    return productInfoMapper.selectPage(new Page<ProductInfo>(pageNumber, pageSize), productInfoQueryWrapper);
}