效果图
前台代码
<asp:GridView ID ="GridView1" runat ="server" AutoGenerateColumns ="false">
<Columns>
<asp:BoundField DataField ="NO" HeaderText ="No" HeaderStyle-HorizontalAlign ="Center" />
<asp:BoundField DataField ="NO" HeaderText ="年度|第一季度|1月" HeaderStyle-HorizontalAlign ="Center" />
<asp:BoundField DataField ="NO" HeaderText ="年度|第一季度|2月" HeaderStyle-HorizontalAlign ="Center" />
<asp:BoundField DataField ="NO" HeaderText ="年度|第一季度|3月" HeaderStyle-HorizontalAlign ="Center" />
<asp:BoundField DataField ="NO" HeaderText ="年度|第二季度|4月" HeaderStyle-HorizontalAlign ="Center" />
<asp:BoundField DataField ="NO" HeaderText ="年度|第二季度|5月" HeaderStyle-HorizontalAlign ="Center" />
<asp:BoundField DataField ="NO" HeaderText ="年度|第二季度|6月" HeaderStyle-HorizontalAlign ="Center" />
<asp:BoundField DataField ="NO" HeaderText ="年度|第三季度|7月" HeaderStyle-HorizontalAlign ="Center" />
<asp:BoundField DataField ="NO" HeaderText ="年度|第三季度|8月" HeaderStyle-HorizontalAlign ="Center" />
<asp:BoundField DataField ="NO" HeaderText ="年度|第三季度|9月" HeaderStyle-HorizontalAlign ="Center" />
<asp:BoundField DataField ="NO" HeaderText ="年度|第四季度|10月|计划" HeaderStyle-HorizontalAlign ="Center" />
<asp:BoundField DataField ="NO" HeaderText ="年度|第四季度|10月|实际" HeaderStyle-HorizontalAlign ="Center" />
<asp:BoundField DataField ="NO" HeaderText ="年度|第四季度|11月|计划" HeaderStyle-HorizontalAlign ="Center" />
<asp:BoundField DataField ="NO" HeaderText ="年度|第四季度|11月|实际" HeaderStyle-HorizontalAlign ="Center" />
<asp:BoundField DataField ="NO" HeaderText ="年度|第四季度|12月|计划" HeaderStyle-HorizontalAlign ="Center" />
<asp:BoundField DataField ="NO" HeaderText ="年度|第四季度|12月|实际" HeaderStyle-HorizontalAlign ="Center" />
<asp:BoundField DataField ="NO" HeaderText ="年度|第四季度|合计" HeaderStyle-HorizontalAlign ="Center" />
<asp:BoundField DataField ="NO" HeaderText ="上半年|计划" HeaderStyle-HorizontalAlign ="Center" />
<asp:BoundField DataField ="NO" HeaderText ="上半年|实际" HeaderStyle-HorizontalAlign ="Center" />
<asp:BoundField DataField ="NO" HeaderText ="上半年|达成率" HeaderStyle-HorizontalAlign ="Center" />
<asp:BoundField DataField ="NO" HeaderText ="下半年|计划" HeaderStyle-HorizontalAlign ="Center" />
<asp:BoundField DataField ="NO" HeaderText ="下半年|实际" HeaderStyle-HorizontalAlign ="Center" />
<asp:BoundField DataField ="NO" HeaderText ="下半年|达成率" HeaderStyle-HorizontalAlign ="Center" />
<asp:BoundField DataField ="NO" HeaderText ="年度合计" HeaderStyle-HorizontalAlign ="Center" />
</Columns>
</asp:GridView>
后台代码
Private Sub GridView1_RowCreated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView1.RowCreated
If e.Row.RowType = DataControlRowType.Header Then
Dim intLayerLevel As Integer = 0
Dim tcOld(e.Row.Cells.Count - 1) As TableCell
e.Row.Cells.CopyTo(tcOld, 0)
Dim intLength As Integer = 0
Dim strSplit As String = "|"
'获取最大层数
For i As Integer = 0 To e.Row.Cells.Count - 1
intLength = tcOld(i).Text.Split(strSplit).Length
If intLength > intLayerLevel Then
intLayerLevel = intLength
End If
Next
'移除标题
e.Row.Cells.Clear()
Dim tcHeader As New TableHeaderCell
Dim intFlag As Integer = 0
'处理行
For intLevel As Integer = 1 To intLayerLevel
For intOldCell As Integer = 0 To tcOld.Length - 1
'取得header的层级名
Dim arrHeader() As String = tcOld(intOldCell).Text.Split(strSplit)
If arrHeader.Length = intLevel Then '层级的名称等于当前层数时
intFlag = intFlag + 1
If intOldCell = tcOld.Length - 1 _
OrElse (tcOld(intOldCell + 1).Text.Split(strSplit).Length >= intLevel _
AndAlso arrHeader(intLevel - 1) <> tcOld(intOldCell + 1).Text.Split(strSplit)(intLevel - 1)) _
OrElse tcOld(intOldCell).Text <> tcOld(intOldCell + 1).Text Then
tcHeader = New TableHeaderCell()
tcHeader.ColumnSpan = intFlag
'如果当前header的层数小于最大层数,则设置该cell的行合并值
If intLayerLevel > intLevel Then
tcHeader.RowSpan = intLayerLevel - intLevel + 1 '定义表头的所占的行数
End If
tcHeader.Text = arrHeader(intLevel - 1) '设置cell文本
tcHeader.CssClass = Me.GridView1.HeaderStyle.CssClass '设置cell样式
e.Row.Cells.Add(tcHeader) '添加cell
intFlag = 0
End If
ElseIf arrHeader.Length > intLevel Then '如果层级的名称大于当前层数时
intFlag = intFlag + 1
'原标题的列数最后一列
'原标题的层数小于当前层数
'当前cell的上级层级名不等于原标题的当前层级名
If intOldCell >= tcOld.Length - 1 _
OrElse tcOld(intOldCell).Text.Split(strSplit).Length < intLevel _
OrElse arrHeader(intLevel - 1) <> tcOld(intOldCell).Text.Split(strSplit)(intLevel - 1) Then
tcHeader = New TableHeaderCell
tcHeader.ColumnSpan = intFlag
tcHeader.Text = arrHeader(intLevel - 1)
tcHeader.CssClass = Me.GridView1.HeaderStyle.CssClass
e.Row.Cells.Add(tcHeader)
intFlag = 0
ElseIf tcOld(intOldCell).Text.Split(strSplit).Length <> tcOld(intOldCell + 1).Text.Split(strSplit).Length Then
If (arrHeader.Length >= intLevel _
AndAlso tcOld(intOldCell + 1).Text.Split(strSplit).Length >= intLevel _
AndAlso arrHeader(intLevel - 1) <> tcOld(intOldCell + 1).Text.Split(strSplit)(intLevel - 1)) _
OrElse tcOld(intOldCell + 1).Text.Split(strSplit).Length < intLevel Then
tcHeader = New TableHeaderCell
tcHeader.ColumnSpan = intFlag
tcHeader.Text = arrHeader(intLevel - 1)
tcHeader.CssClass = Me.GridView1.HeaderStyle.CssClass
e.Row.Cells.Add(tcHeader)
intFlag = 0
End If
ElseIf tcOld(intOldCell).Text.Split(strSplit).Length = tcOld(intOldCell + 1).Text.Split(strSplit).Length Then
If arrHeader(intLevel - 1) <> tcOld(intOldCell + 1).Text.Split(strSplit)(intLevel - 1) Then
tcHeader = New TableHeaderCell
tcHeader.ColumnSpan = intFlag
tcHeader.Text = arrHeader(intLevel - 1)
tcHeader.CssClass = Me.GridView1.HeaderStyle.CssClass
e.Row.Cells.Add(tcHeader)
intFlag = 0
End If
End If
End If
Next
If intLevel < intLayerLevel Then
If Not tcHeader Is Nothing Then
tcHeader.Text = tcHeader.Text + "</tr><tr>"
End If
End If
Next
End If
End Sub