如何在Yii2 GridView中为指定两列实现单元格跨行合并(rowspan)?
Yii2 GridView实现指定列跨行合并及数值填充方案
要实现“Offical MOU sites”和“Official MOU sites >2700”两列的跨行合并(rowspan),核心思路是先对数据按分组维度预处理,再在GridView列配置中根据分组状态控制单元格显示与合并逻辑,具体步骤如下:
1. 预处理数据(控制器层)
先按category分组,统计每个分组的行数、目标列的聚合值,并给每个模型添加分组标识:
// 获取当前页的模型数据 $models = $dataProvider->getModels(); // 用查询批量统计各分类的目标数值(比循环累加更高效) $categoryStats = YourModel::find() ->select([ 'category', 'SUM(mou_sites) as total_mou_sites', // 替换为实际字段名 'SUM(CASE WHEN mou_sites > 2700 THEN mou_sites ELSE 0 END) as total_mou_over_2700', 'COUNT(*) as group_count' ]) ->where(['category' => array_column($models, 'category')]) ->groupBy('category') ->indexBy('category') ->asArray() ->all(); // 给每个模型添加分组属性 foreach ($models as $index => $model) { $category = $model->category; $stats = $categoryStats[$category]; // 标记是否为分组内第一行 $model->is_first_in_group = ($index === 0 || $models[$index-1]->category !== $category); // 分组行数(用于设置rowspan) $model->group_row_count = $stats['group_count']; // 目标列的聚合值 $model->total_mou_sites = $stats['total_mou_sites']; $model->total_mou_over_2700 = $stats['total_mou_over_2700']; } // 更新数据提供者的模型 $dataProvider->setModels($models);
2. GridView列配置(视图层)
在列定义中,根据模型的分组标识控制单元格的rowspan属性和显示逻辑:
echo GridView::widget([ 'dataProvider' => $dataProvider, 'columns' => [ 'id', [ 'attribute' => 'category', 'value' => function ($model) { return $model->category . ' (Count: ' . $model->group_row_count . ')'; }, 'contentOptions' => function ($model) { return $model->is_first_in_group ? ['rowspan' => $model->group_row_count] : ['style' => 'display:none;']; }, ], 'name', 'price', // Offical MOU sites 列 [ 'label' => 'Offical MOU sites', 'value' => function ($model) { return $model->is_first_in_group ? $model->total_mou_sites : ''; }, 'contentOptions' => function ($model) { return $model->is_first_in_group ? ['rowspan' => $model->group_row_count, 'class' => 'text-center'] : ['style' => 'display:none;']; }, ], // Official MOU sites >2700 列 [ 'label' => 'Official MOU sites >2700', 'value' => function ($model) { return $model->is_first_in_group ? $model->total_mou_over_2700 : ''; }, 'contentOptions' => function ($model) { return $model->is_first_in_group ? ['rowspan' => $model->group_row_count, 'class' => 'text-center'] : ['style' => 'display:none;']; }, ], ], ]);
关键说明
- 预处理时通过数据库查询批量统计分组数据,避免循环累加的性能损耗;
- 用
is_first_in_group标记分组首行,仅首行显示内容并设置rowspan,其余行隐藏单元格; - 如果使用分页,上述逻辑仅针对当前页数据生效,符合分页场景的分组合并需求;
- 可根据实际业务调整
SUM聚合逻辑,比如改为COUNT统计数量等。
内容的提问来源于stack exchange,提问作者Faizan
相关产品推荐
相关产品推荐

