先來回顧一下rowspan和colspanhtml
<td>元素的colspan屬性來實現單元格跨列操做,使用<td>元素的rowspan屬性來實現單元格的跨行操做。java
colspan屬性規定單元格可橫跨的列數,全部瀏覽器都支持colspan屬性。其取值爲number,瀏覽器
以下圖所示:jsp
例如:this
<table border="1"> <tr> <th>星期一</th> <th>星期二</th> </tr> <tr> <td colspan="2">星期天</td> </tr> </table>
實現結果以下圖所示:spa
rowspan屬性規定單元格可橫跨的列數,全部瀏覽器都支持rowspan屬性。其取值爲number,以下圖所示:.net
例如:code
<table border="1"> <tr> <td rowspan="2">星期一</td> <td>星期二</td> </tr> <tr> <td>星期三</td> </tr> </table>
實現結果以下圖所示:orm
總結colspan和rowspan的使用以下:htm
<table border="1"> <tr> <th colspan="3">物資詳情說明</th> </tr> <tr> <td colspan="2" align="center">數量(支)</td> <td rowspan="2">重量(噸)</td> </tr> <tr> <td>實發數</td> <td>實收數</td> </tr> <tr> <td>12</td> <td>10</td> <td>100.00</td> </tr> </table>
實現結果以下圖所示:
下面進入正題:
假設沒有rowspan的時候,首行下面有三行,若是執行了rowspan=4(rowspan=1,表示佔用一行,其自己就是佔用一行,因此若是要額外佔用其餘的三行,那麼rowspasn=1+3),這個時候會佔用下面三行的,看起來的效果就是合併了其他三行(使用rowspan,那麼它自己和它即將要合併的行必須在不一樣的行,而且處於相同的列)
<html> <body> <table border="1"> <tr> <th>第一行</th> </tr> <tr> <th>第二行</th> </tr> <tr> <th>第三行</th> </tr> <tr> <th>第四行</th> </tr> </table> </body> </html>
效果圖:
若是合併三面的三行:
<html> <body> <table border="1"> <tr> <th rowspan="4">第一行</th>//合併三面的三行,會把下面三行的位置佔據,下面的三行將會被擠到右邊去 </tr> <tr> <th>第二行</th> </tr> <tr> <th>第三行</th> </tr> <tr> <th>第四行</th> </tr> </table> </body> </html>
效果圖:
碰到項目中的一個問題:
有個樹結構的數據,它有多個頂級節點(AuditorInfoObject),每一個頂級可能有子節點(TaskObject),子節點可能還有本身的子節點(BaseObject),如何造成合並行的table:
解決步驟:
1.計算最頂級節點佔用的行數(即rowspan)
private Map<Integer,Integer> countMap = new HashMap<>();//key爲頂級節點的索引值,value爲rowspan的數量 if(this.auditorList != null) { //計算頁面合併行的總個數 for(int i = 0;i < this.auditorList.size();i++) { int total = 1;//每一個頂級節點本身本來就佔有一行 List<TaskObject> childrens = this.auditorList.get(i).getChildren(); if(childrens != null && childrens.size() > 0) { for(TaskObject child:childrens) { total++;//每一個子節點佔一行 List<BaseObject<?>> processElenmentList = child.getProcessElenmentList(); if(processElenmentList != null && processElenmentList.size() > 0) { total += processElenmentList.size();//每一個子節點的子節點又佔一行 } } } countMap.put(i, total); } }
2.在頁面寫好三層循環結構:
jsp代碼:
<table class="table" style="width:100%;border:0px;" id="shcx_table"> <tbody> <tr> <th height="18px;" style="text-align:center">頂級節點</th> <th style="text-align:center;" id="myStep">一級節點</th> <th style="text-align:center;" id="myName">二級節點</th> </tr> <s:iterator value="auditorList" var="obj" status="l"> <tbody title="<s:property value="#obj.processName" />"> <tr><!-- 頂級節點 --> <th rowspan="<s:property value="countMap.get(#l.index)"/>" style="text-align:center; width:80px;"> <s:property value="#obj.processName"/> </th> </tr> <s:iterator value="#obj.children" var="c"><!-- 一級節點 --> <s:if test="#c.processElenmentList != null && #c.processElenmentList.size() > 0"> <tr> <th rowspan="<s:property value="#c.processElenmentList.size()+1"/>" style="text-align:left; width:80px;"> <s:property value="#c.stepName"/> </th> </tr> <s:iterator value="#c.processElenmentList" var="r"><!-- 二級節點 --> <tr> <th style="text-align:left; font-weight:normal;width:400px"><s:property value="#r.elementName"/></th> </tr> </s:iterator> </s:if> <s:else> <tr><!-- 一級節點沒有子節點走這裏 --> <th style="text-align:left; font-weight:normal;width:10px"><s:property value="#c.stepName"/></th> <th style="text-align:left; font-weight:normal;width:400px">無子節點</th> </tr> </s:else> </s:iterator> </tbody> </s:iterator> </tbody> </table>
顯示效果:
紅色箭頭表示父節點方向,對於這種結構樹,
能夠這麼作:
(1)能夠先不考慮合併行,把每一個tr從父節點到子節點都一一用td列出來
即:每一行tr都是從頂級節點到最後一個節點都一一用td裝入進來
(2)在頂級節點使用rowspan,這個時候會發現:頂級節點的rowspan=1(root自己佔1行)+該節點擁有的一級子節點(root.getChildren().size())+每個子節點擁有的子節點樹(child.getProcessElenmentList().size())
(3)在使用的rowspan以後,把被擠到右側的節點的頂級節點刪除掉(被合併的行再也不須要root節點,只有第一行須要,其餘的行和第一行公用root節點)
(4)由於一級節點也有子節點,此時再合併一級節點,步驟同頂級節點...
參考:https://blog.csdn.net/u012724595/article/details/79401401