piaoyi's blog - 站在煩惱裡仰望幸福

Main | Next page »

http://www.javaworld.com.tw/roller/piaoyi/date/20080416 Wednesday April 16, 2008

HTML列印時,在分頁後如何重覆印出表格的表頭表尾

目錄

摘要

我們在HTML中常使用Table來呈現表格的資料,有時Table很大,如果利用Browser列印時,Table會被切成二頁,此時第二頁的Table由於沒有表頭資料,時常會不知哪一欄代表的意義是什麼,不過其實 CSS 是有定義與支援的,也就是利用 html tag : THEAD, TBODY, TFOOT這三個 tag 來 group 一個表格中的 header, body, footer 三塊,再利用 CSS 的設定,就可以在列印時,會在 Table 被切頁時,在第二頁會自動加入 Table header 與 footer。

See also : CSS對HTML列印的支援

設定方式

使用 THEAD, TBODY, TFOOT 來分類 Table 中的元素

HTML Table 中,底下第一層為TR,再來為TD,而TR代表一列,所以在分類中是以TR為主,看你要多少個TR為表頭,表身,或表尾都可以。
一般而言,表頭只會設一列,表尾則不常使用,表身則是主要表格內的內容,會有多列,而只要在寫TR前,先用THEAD,TBODY,TFOOT包裹即可。

THEAD, TBODY, TFOOT
<TABLE>
<THEAD>
  <TR>
    <TH noWrap>表頭 COL 1</TH>
    <TH noWrap>表頭 COL 2</TH>
    <TH>表頭 COL 3</TH>
    <TH noWrap>表頭 COL 4</TH>
    <TH>表頭 COL 5</TH>
    <TH noWrap>表頭 COL 6</TH>
    <TH noWrap>表頭 COL 7</TH>
  </TR>
</THEAD>
<TBODY>
  <TR>
    <TD>表身 ROW 1 COL 1</TD>
    <TD>表身 ROW 1 COL 2</TD>
    <TD>表身 ROW 1 COL 3</TD>
    <TD>表身 ROW 1 COL 4</TD>
    <TD>表身 ROW 1 COL 5</TD>
    <TD>表身 ROW 1 COL 6</TD>
    <TD>表身 ROW 1 COL 7</TD>
  </TR>
  <TR>
    <TD>表身 ROW 2 COL 1</TD>
    <TD>表身 ROW 2 COL 2</TD>
    <TD>表身 ROW 2 COL 3</TD>
    <TD>表身 ROW 2 COL 4</TD>
    <TD>表身 ROW 2 COL 5</TD>
    <TD>表身 ROW 2 COL 6</TD>
    <TD>表身 ROW 2 COL 7</TD>
  </TR>
  <TR>
    <TD>表身 ROW 3 COL 1</TD>
    <TD>表身 ROW 3 COL 2</TD>
    <TD>表身 ROW 3 COL 3</TD>
    <TD>表身 ROW 3 COL 4</TD>
    <TD>表身 ROW 3 COL 5</TD>
    <TD>表身 ROW 3 COL 6</TD>
    <TD>表身 ROW 3 COL 7</TD>
  </TR>
  <TR>
    <TD>表身 ROW 4 COL 1</TD>
    <TD>表身 ROW 4 COL 2</TD>
    <TD>表身 ROW 4 COL 3</TD>
    <TD>表身 ROW 4 COL 4</TD>
    <TD>表身 ROW 4 COL 5</TD>
    <TD>表身 ROW 4 COL 6</TD>
    <TD>表身 ROW 4 COL 7</TD>
  </TR>
  <TR>
    <TD>表身 ROW 5 COL 1</TD>
    <TD>表身 ROW 5 COL 2</TD>
    <TD>表身 ROW 5 COL 3</TD>
    <TD>表身 ROW 5 COL 4</TD>
    <TD>表身 ROW 5 COL 5</TD>
    <TD>表身 ROW 5 COL 6</TD>
    <TD>表身 ROW 5 COL 7</TD>
  </TR>
  <TR>
    <TD>表身 ROW 6 COL 1</TD>
    <TD>表身 ROW 6 COL 2</TD>
    <TD>表身 ROW 6 COL 3</TD>
    <TD>表身 ROW 6 COL 4</TD>
    <TD>表身 ROW 6 COL 5</TD>
    <TD>表身 ROW 6 COL 6</TD>
    <TD>表身 ROW 6 COL 7</TD>
  </TR>
  <TR>
    <TD>表身 ROW 7 COL 1</TD>
    <TD>表身 ROW 7 COL 2</TD>
    <TD>表身 ROW 7 COL 3</TD>
    <TD>表身 ROW 7 COL 4</TD>
    <TD>表身 ROW 7 COL 5</TD>
    <TD>表身 ROW 7 COL 6</TD>
    <TD>表身 ROW 7 COL 7</TD>
  </TR>
  <TR>
    <TD>表身 ROW 8 COL 1</TD>
    <TD>表身 ROW 8 COL 2</TD>
    <TD>表身 ROW 8 COL 3</TD>
    <TD>表身 ROW 8 COL 4</TD>
    <TD>表身 ROW 8 COL 5</TD>
    <TD>表身 ROW 8 COL 6</TD>
    <TD>表身 ROW 8 COL 7</TD>
  </TR>
</TBODY>
<TFOOT>
  <TR>
    <TH noWrap>表尾 COL 1</TH>
    <TH noWrap>表尾 COL 2</TH>
    <TH>表尾 COL 3</TH>
    <TH noWrap>表尾 COL 4</TH>
    <TH>表尾 COL 5</TH>
    <TH noWrap>表尾 COL 6</TH>
    <TH noWrap>表尾 COL 7</TH>
  </TR>
</TFOOT>
</TABLE>

使用 CSS 來設定列印時,重覆印出Table header 與 footer

使用THEAD, TBODY, TFOOT 分類後,對 Browser html 輸出並不會有影響,和沒有加的效果是一樣的,也就是Table就是一個,如果超過一頁則是用Scrollbar來拉,而列印時亦同,也沒有差異。
如果你希望列印時,當表格被分在二頁時,第二頁的表格會重覆印出表頭表尾,則你在該網頁中設定CSS來通知Browser列印時的處理。

與html中加入CSS設定
<HTML>
<HEAD>
<STYLE>
 THEAD {display: table-header-group;}
 TFOOT {display: table-footer-group;}
</STYLE>
</HEAD>
<BODY>
<table>
.......
</table>
</BODY>
</HTML>

原始網頁呈現

表頭 COL 1 表頭 COL 2 表頭 COL 3 表頭 COL 4 表頭 COL 5 表頭 COL 6 表頭 COL 7 表頭 COL 8
表身 ROW 1 COL 1 表身 ROW 1 COL 2 表身 ROW 1 COL 3 表身 ROW 1 COL 4 表身 ROW 1 COL 5 表身 ROW 1 COL 6 表身 ROW 1 COL 7 表身 ROW 1 COL 8
表身 ROW 2 COL 1 表身 ROW 2 COL 2 表身 ROW 2 COL 3 表身 ROW 2 COL 4 表身 ROW 2 COL 5 表身 ROW 2 COL 6 表身 ROW 2 COL 7 表身 ROW 2 COL 8
表身 ROW 3 COL 1 表身 ROW 3 COL 2 表身 ROW 3 COL 3 表身 ROW 3 COL 4 表身 ROW 3 COL 5 表身 ROW 3 COL 6 表身 ROW 3 COL 7 表身 ROW 3 COL 8
表身 ROW 4 COL 1 表身 ROW 4 COL 2 表身 ROW 4 COL 3 表身 ROW 4 COL 4 表身 ROW 4 COL 5 表身 ROW 4 COL 6 表身 ROW 4 COL 7 表身 ROW 4 COL 8
表身 ROW 5 COL 1 表身 ROW 5 COL 2 表身 ROW 5 COL 3 表身 ROW 5 COL 4 表身 ROW 5 COL 5 表身 ROW 5 COL 6 表身 ROW 5 COL 7 表身 ROW 5 COL 8
表身 ROW 6 COL 1 表身 ROW 6 COL 2 表身 ROW 6 COL 3 表身 ROW 6 COL 4 表身 ROW 6 COL 5 表身 ROW 6 COL 6 表身 ROW 6 COL 7 表身 ROW 6 COL 8
表身 ROW 7 COL 1 表身 ROW 7 COL 2 表身 ROW 7 COL 3 表身 ROW 7 COL 4 表身 ROW 7 COL 5 表身 ROW 7 COL 6 表身 ROW 7 COL 7 表身 ROW 7 COL 8
表身 ROW 8 COL 1 表身 ROW 8 COL 2 表身 ROW 8 COL 3 表身 ROW 8 COL 4 表身 ROW 8 COL 5 表身 ROW 8 COL 6 表身 ROW 8 COL 7 表身 ROW 8 COL 8
表尾 COL 1 表尾 COL 2 表尾 COL 3 表尾 COL 4 表尾 COL 5 表尾 COL 6 表尾 COL 7 表尾 COL 8

列印時的效果

假設在第 4 row 剛好分頁了。


Page 1

表頭 COL 1 表頭 COL 2 表頭 COL 3 表頭 COL 4 表頭 COL 5 表頭 COL 6 表頭 COL 7 表頭 COL 8
表身 ROW 1 COL 1 表身 ROW 1 COL 2 表身 ROW 1 COL 3 表身 ROW 1 COL 4 表身 ROW 1 COL 5 表身 ROW 1 COL 6 表身 ROW 1 COL 7 表身 ROW 1 COL 8
表身 ROW 2 COL 1 表身 ROW 2 COL 2 表身 ROW 2 COL 3 表身 ROW 2 COL 4 表身 ROW 2 COL 5 表身 ROW 2 COL 6 表身 ROW 2 COL 7 表身 ROW 2 COL 8
表身 ROW 3 COL 1 表身 ROW 3 COL 2 表身 ROW 3 COL 3 表身 ROW 3 COL 4 表身 ROW 3 COL 5 表身 ROW 3 COL 6 表身 ROW 3 COL 7 表身 ROW 3 COL 8
表身 ROW 4 COL 1 表身 ROW 4 COL 2 表身 ROW 4 COL 3 表身 ROW 4 COL 4 表身 ROW 4 COL 5 表身 ROW 4 COL 6 表身 ROW 4 COL 7 表身 ROW 4 COL 8
表尾 COL 1 表尾 COL 2 表尾 COL 3 表尾 COL 4 表尾 COL 5 表尾 COL 6 表尾 COL 7 表尾 COL 8

Page 2

表頭 COL 1 表頭 COL 2 表頭 COL 3 表頭 COL 4 表頭 COL 5 表頭 COL 6 表頭 COL 7 表頭 COL 8
表身 ROW 5 COL 1 表身 ROW 5 COL 2 表身 ROW 5 COL 3 表身 ROW 5 COL 4 表身 ROW 5 COL 5 表身 ROW 5 COL 6 表身 ROW 5 COL 7 表身 ROW 5 COL 8
表身 ROW 6 COL 1 表身 ROW 6 COL 2 表身 ROW 6 COL 3 表身 ROW 6 COL 4 表身 ROW 6 COL 5 表身 ROW 6 COL 6 表身 ROW 6 COL 7 表身 ROW 6 COL 8
表身 ROW 7 COL 1 表身 ROW 7 COL 2 表身 ROW 7 COL 3 表身 ROW 7 COL 4 表身 ROW 7 COL 5 表身 ROW 7 COL 6 表身 ROW 7 COL 7 表身 ROW 7 COL 8
表身 ROW 8 COL 1 表身 ROW 8 COL 2 表身 ROW 8 COL 3 表身 ROW 8 COL 4 表身 ROW 8 COL 5 表身 ROW 8 COL 6 表身 ROW 8 COL 7 表身 ROW 8 COL 8
表尾 COL 1 表尾 COL 2 表尾 COL 3 表尾 COL 4 表尾 COL 5 表尾 COL 6 表尾 COL 7 表尾 COL 8

Sample download

  1. Download [table_header_footer_sample.zip]
  2. 使用Browser 開啟 table_header_footer_sample.html,再點Browser 的[預覽列印],即可看到效果。

注意事項

  1. IE在表格分頁時,不會自動控制何處該切斷,也就是IE列印可能會把一個TD裡的內容截成二半,一半在上頁,一半在下頁,這時如果又有重覆押表頭,在第下頁看起來時會覺的有點奇怪,不過在 FireFox 與 Opera 則會以一個 TR 為切頁單位,輸出的感覺就會比較正常。因此,如果用 IE 列印,則可能需要自己用 javascript 計算,該在何處的 TR 加上 page-break-before 註記來完成以 TR 為單位的換頁。


CSS對HTML列印的支援

目錄

摘要

在此截錄一些CSS用在控制列印時的語法,但是並不是所有的Browser都支援。

@page 控制一頁的長,寬,邊界,直印,橫印等..

Page size: the 'size' property
'size' 
      Value:       <length>{1,2} | auto | portrait | landscape | inherit  
      Initial:     auto  
      Applies to:  the page context  
      Inherited:   N/A  
      Percentages: N/A  
      Media:       visual, paged
@page sample
@page { size 8.5in 11in; margin: 2cm }

@page {
  size: auto;   /* auto is the initial value */
  margin: 10%;
}

@page :left {
  margin-left: 4cm;
  margin-right: 3cm;
}

@page :right {
  margin-left: 3cm;
  margin-right: 4cm;
}

@page { margin: 2cm } /* All margins set to 2cm */

@page :first {
  margin-top: 10cm    /* Top margin on first page 10cm */
}

Reference : http://www.w3.org/TR/REC-CSS2/page.html

Page Break ,換頁控制

page break 是用來告訴 browser,在什麼情形下應該換頁,與應該不換頁,但這不是所有的Browser都能正確支援。

Reference : http://www.w3.org/TR/REC-CSS2/page.html#page-breaks

page-break-before

這個CSS代表在 Rander 某個 Tag 前,先換一頁。
這個屬性在IE 只支援 always 與 avoid 這二種屬性值,而且其中 avoid 是以空白代表。
這個屬性通常沒什麼用,除非我們明確的知道我要在哪要分頁,或我需要在哪要有切頁,這樣在我們產生HTML時,就可以在想要分頁的地方加入此設定。
例如我們可以自己用 javascript 計算每個 html 元素中的大小與位置,好決定在什麼時候要切頁,主要是用來在 Table 與 IMG 不要被截斷或可以截斷在好一點的位置。

page-break-before property
Value:   auto | always | avoid | left | right | inherit  
Initial:   auto  
Applies to:   block-level elements  
Inherited:   no  
Percentages:   N/A  
Media:   visual, paged

page-break-after

這個CSS代表在 Rander 某個 Tag 後,就換一頁。
這個屬性在IE 只支援 always 與 avoid 這二種屬性值,而且其中 avoid 是以空白代表。
這個屬性通常沒什麼用,除非我們明確的知道我要在哪要分頁,或我需要在哪要有切頁,這樣在我們產生HTML時,就可以在想要分頁的地方加入此設定。
例如我們可以自己用 javascript 計算每個 html 元素中的大小與位置,好決定在什麼時候要切頁,主要是用來在 Table 與 IMG 不要被截斷或可以截斷在好一點的位置。

page-break-after property
Value:   auto | always | avoid | left | right | inherit  
Initial:   auto  
Applies to:   block-level elements  
Inherited:   no  
Percentages:   N/A  
Media:   visual, paged

page-break-inside

這個屬性代表著,被 Apply 的 Tag 中不可以被切頁,而其實這個屬性最好用,因為我們通常都是希望某些元素在列印時不要被切斷,如 Table 中的 TR, TD ,IMG等,所以只要把這個 CSS apply 到 TR ,這樣就不會有 Table 被切頁時,會有一部份 TD 內容在上頁,一部份 TD 內容在下頁。
不幸的是,這個 CSS 支援的 Browser 太少了,只有一個Broser Opera有支援,而偏偏 IE 並不支援,或許可以看以後會不會支援而再來加以應用。所以目前只可以利用 javascript 自己計算位置在適當的位置加入 page-break-before or after。

page-break-inside property
Value:   avoid | auto | inherit  
Initial:   auto  
Applies to:   block-level elements  
Inherited:   yes  
Percentages:   N/A  
Media:   visual, paged

page-break value description

auto Neither force nor forbid a page break before (after, inside) the generated box.
always Always force a page break before (after) the generated box.
avoid Avoid a page break before (after, inside) the generated box.
left Force one or two page breaks before (after) the generated box so that the next page is formatted as a left page.
right Force one or two page breaks before (after) the generated box so that the next page is formatted as a right page.

page break sample

page-break-inside property
<STYLE>
<!-- 套用所有的 TR 中強迫不要被切頁-->
 TR { page-break-inside:avoid;} </STYLE>
</STYLE>



<!-- 或是只套用在某一個位置的Tag上-->
<!-- 強迫在印這一個row前,先換頁-->
<TR style="page-break-before:always">
    <TD>健康認知指導 (A) </TD>
    <TD >食道吻合手術前後須知 </TD>
    <TD >全不知</TD>
    <TD >2006/08/30 </TD>
    <TD >ssss</TD>
    <TD >示教 <BR>其他 :ffdd <BR></TD>
    <TD>家屬</TD>
</TR>

各家瀏覽器的支援程度

Reference : http://www.westciv.com/style_master/academy/browser_support/printing.html



Main | Next page »