前言
iText已經有10年的歷史了,如果有人問在這10年中iText中那個對象是最重要的話,本書的作者會毫不猶豫的說是PdfPTable和PdfPCell。因為作者大部分的工作(相信也是大多數人的工作)就是從數據中取出數據然后在文檔中以表格的形式呈現出來。因為兩個類實在是太重要,這里我們會花費整個第二章的內容來詳細說明。
Constructing tables
在iText中處理Table的有很多老版本的類如Table和PdfTable,但由於有些缺點,而且在處理多頁的情況分割表格,控制表格單元格等情況下力不從心,因此有了PdfPTable和PdfPCell的出現。iText最新的版本已經移出了PdfPTable和Table,只剩下PdfPable和PdfPCell。
Your first PdfPTable
假設我們想創建一個下圖的表格:
那么代碼如下,而且比較簡單:
listing 4.1 MyFirstTable.cs
PdfPTable table = new PdfPTable(3); PdfPCell cell; cell = new PdfPCell(new Phrase("Cell with colspan 3")); cell.Colspan = 3; table.AddCell(cell); cell = new PdfPCell(new Phrase("cell with rowspan 2")); cell.Rowspan = 2; table.AddCell(cell); table.AddCell("row 1; cell 1"); table.AddCell("row 1;cell 2"); table.AddCell("row 2;cell 1"); table.AddCell("row 2; cell 2");
當我們創建PdfPTable的實例時,一般都要傳入列的個數,如果創建表格的列為零的話就會拋出RunTimeException異常。然后我們可以通過PdfPTable的AddCell方法往表格中添加內容。
AUTOMATIC CREATION OF ROWS
以上代碼大家要注意的是:我們沒有使用PdfPRow對象,iText會在內部使用這個類來存儲同一列的單元格。下面我們對listing 4.1進行一些說明:
一開始的創建的PdfPTable有三列,當一個跨三列的單元格被添加之后第一行就滿了,接下來的單元格就會被添加到iText內部創建的第二列,但由於第二個單元格跨兩行所以第三列也被創建了。接下來的四個單元格中的前二個就被添加到第二列,后兩個被添加到第三列。
大家要注意的是當我們將PdfPTable添加到Document時,只有完整的列被添記進去,如果想添加不完整的列我們需要調用PdfPTable的CompleteRow方法。因為iText會為我們處理表格的列,我們要做的是確保添加了正確個數的單元格。
PdfPTable properties
接下來我們會討論單元格的一些屬性:對齊,邊框等。但首先我們還是先看下PdfPTable的一些屬性:PdfPTable的寬度和列,表格之前或之后的空間以及對齊選項。
表格的寬度是可用空間的80%,對於listing 4.1創建的表格寬度我們就需要做一些數學計算:(595-(36*2))*0.80=418.4pt,其中36是左右頁邊距的寬度。
表格寬度
每一個PdfPTable有兩個關於寬度的屬性:
- WidthPercentage----可用寬度的百分比
- TotalWidth-----絕對寬度,但單位為user unit
當我們將PdfPTable添加到Document時,iText會根據LockedWidth屬性來決定使用其中一個:LockedWidth為true時表格就有一個固定的寬度(使用TotalWidth屬性)。默認情況下LockedWidth為false,表格的精確寬度就依賴頁面的可用寬度或者被添加到ColumnText對象的寬度。默認每一列的寬度就是表格的寬度除以列數,這個時候可以說每一列的相對寬度為1,但我們可以修改這個默認設置項。
列的相對寬度
上圖和通過listing 4.1創建的表格看起來是一樣的,但表格的寬度和列由五種不同的屬性絕對,以下為代碼:
listing 4.2 ColumnWidths.cs
public PdfPTable CreateTable1() { PdfPTable table = new PdfPTable(3); table.WidthPercentage = 288 / 5.23f; table.SetWidths(new int[] { 2, 1, 1 }); …… return table; } public PdfPTable CreateTable2() { PdfPTable table = new PdfPTable(3); table.TotalWidth = 288; table.LockedWidth = true; table.SetWidths(new float[] { 2, 1, 1 }); ……… return table; } public PdfPTable CreateTable3() { PdfPTable table = new PdfPTable(new float[] { 2, 1, 1 }); table.WidthPercentage = 55.067f; …….. return table; }
在以上的三個創建表格的方法中,列都使用了相對寬度,代碼中是通過new int[] {2, 1, 1} 或者new float{2, 1, 1}設置,這些代碼的意思是我們希望將表格分成2+1+1=4等份:第一列占有2等份,其它的都占有1等份。
假設我們希望創建的表格寬度為288pt而不是523pt,那可以先計算寬度的百分比:(288/523)*100=55.067,或者直接通過TotalWidth 和LockedWidth 屬性來設置寬度(這種方法可以避免計算)。
ABSOLUTE COLUMN WIDTHS
在上面的代碼中我們是通過定義整個表格的寬度實現的,但還可以定義每一列的寬度來實現,以下為代碼:
listing 4.3 ColumnWidths.cs (contiuned)
public PdfPTable CreateTable4() { PdfPTable table = new PdfPTable(3); Rectangle rect = new Rectangle(523, 770); table.SetWidthPercentage(new float[] { 144, 72, 72 }, rect); …… return table; } public PdfPTable CreateTable5() { PdfPTable table = new PdfPTable(3); table.SetTotalWidth(new float[] { 144, 72, 72 }); table.LockedWidth = true; …… return table; }
以上代碼中的第一個方法需要還需要計算可用空間,因此直接設置SetTotalWidth方法並且將屬性LockedWidth設置為true效果會更好一點。
表格之前和之后的空間
以上代碼創建的五個表格是通過以下代碼添加到文檔中:
listing 4.4 ColumnWidths.cs (contiuned)
PdfPTable table = CreateTable1();
document.Add(table);
table = CreateTable2();
table.SpacingBefore = 5;
table.SpacingAfter = 5;
document.Add(table);
table = CreateTable3();
document.Add(table);
table = CreateTable4();
table.SpacingAfter = 5;
table.SpacingBefore = 5;
document.Add(table);
table = CreateTable5();
document.Add(table);
以上代碼通過SpacingBefore和SpacingAfter屬性設置了表格之前和之后的空間,這樣兩個表格不至於擠在一起。如果我們沒有設置這些屬性,那么就很難分辨不同的表格,但這有時候也有好處:我們可以創建一系列小而且不同的表格來組成一個大的表格,但看起來卻是一個整體。
TABLE ALIGNMENT
好了直接上圖:
上圖中三個表格就沒有設置SpacingBefore和SpacingAfter屬性,但設置了HorizontalAlignment設置,具體的代碼如下:
listing 4.5 TableAlignment.cs
PdfPTable table = CreateFirestTable(); table.WidthPercentage = 50; table.HorizontalAlignment = Element.ALIGN_LEFT; document.Add(table); table.HorizontalAlignment = Element.ALIGN_CENTER; document.Add(table); table.HorizontalAlignment = Element.ALIGN_RIGHT; document.Add(table);
總結
這一節的內容主要是介紹了PdfPTable的一些常用屬性,內容比較簡單,接下來會介紹PdfPCell的具體使用,最后是代碼下載。
同步
此文章已同步到目錄索引:iText in Action 2nd 讀書筆記。