< >4.4 (Adding a table at an absolute position)讀書筆記


前言

在第二節中我們創建了大量high-level的對象,iText會自動對其布局。在第三節的時候我們學會了writing to direct content,然后使用ColumnText對象將high-levl和lowel-level對象組合起來使用。目前為止我們將PdfPTable對象當作high-level對象使用,因此在其被添加到Document時:單元格的文本內容會被添加到文本層(text layer),其它所有的邊框,背景色,圖片都添加到文本層的下面。但是我們也可以將PdfPTable添加到文本層的上面抑或是圖形層的下面。

Working with WriteSelectedRows()

下圖是2011年的日歷,背景是一張圖片,而在背景前面是一個絕對定位的表格。

PdfCander

listing 4.21 PdfCalendar.cs

PdfPTable table;
Calendar calendar = CultureInfo.GetCultureInfo(LANGUAGE).Calendar;

PdfContentByte canvas = writer.DirectContent;
for (int month = 1; month <= 12; month++)
{

    // draw the background
    DrawImageAndText(canvas, month.ToString().PadLeft(2, '0'));
    // create a table with 7 columns
    table = new PdfPTable(7);
    table.TotalWidth = 504;
    // add the name of the month
    table.DefaultCell.BackgroundColor = BaseColor.WHITE;
    DateTime dt = new DateTime(YEAR, month, 1);
    table.AddCell(GetMonthCell(dt));
    int daysInMonth = DateTime.DaysInMonth(YEAR, month);
    int day = 0;
    int position = (int)calendar.GetDayOfWeek(dt);
    // add empty cells
    for (int j = 0; j < position; j++)
    {
        table.AddCell("");
    }
    // add cells for each day
    do
    {
        DateTime oneDt = dt.AddDays(day);
        day++;
        table.AddCell(GetDayCell(calendar, oneDt));

    } while (day < daysInMonth);

    // complete the table
    table.CompleteRow();
    // write the table to an absolute position
    table.WriteSelectedRows(0, -1, 169, table.TotalHeight + 18, canvas);

    document.NewPage();
}

在我們將table絕對定位時一定要設置表格總的寬度(TotalWidth),而且我們也不需要將寬度鎖定,因為iText會忽視WidthPercentage的屬性(這個屬性只有在通過Documnet.Add方法添加時才有效)。表格的絕對定位是通過WriteSelectedRows方法實現的,現在我們討論下此方法的參數。

SELECTING THE ROWS AND THE TABLE POSITION

方法的前兩個參數是表格的起始和結束列,0到-1表示添加所有的列,其中-1表示所有剩余的列。接下來的兩個參數是表格絕對定位的左上角座標,因為希望表格不要離頁面的下邊距太近,我們在表格的高度上添加了18pt。最后一個參數就是要添加的PdfContentByte對象。

CONTENT CANVASES

除了單個的PdfContentByte對象,WriteSelectedRows方法還接受4個PdfContentByte對象組合的一個數組,其中每個PdfContentByte對象都有一個特定的名稱和目的:

  • PdfPTable.BASECANVAS----添加到這里的內容會處於表格下面
  • PdfPTable.BACKGROUNDCANVAS----背景色的層
  • PdfPTable.LINECANVAS----線的層
  • PdfPTable.TEXTCANVAS----表格中文本的層,其會位於表格上面

如果只是傳入一個PdfContentByte對象,則文本位於線上面,線位於背景色上面,背景色位於BaseCanvas上面。

SPLITTING A PDFPTABLE VERTICALLY

假設一個表格的列太多了導致一頁不能完全顯示,這個時候我們就可以將表格在水平面上分隔,就如下圖:

zhang

上圖是一個表格,其內容是張藝謀導演的電影,表格總的寬度設置為600pt,但頁面可用的寬度只有595pt。因此使用了兩次WriteSelectedRows方法來實現,具體參考以下代碼:

listing 4.22 Zhang.cs

// Create a table and fill it with movies
List<Movie> movies = PojoFactory.GetMovies(conn, 3);
PdfPTable table = new PdfPTable(new float[] { 1, 5, 5, 1 });
foreach (Movie movie in movies)
{
    table.AddCell(movie.Year.ToString());
    table.AddCell(movie.Title);
    table.AddCell(movie.OriginalTitle);
    table.AddCell(movie.Duration.ToString());
}

// set the total width of the table
table.TotalWidth = 600;
PdfContentByte canvas = writer.DirectContent;

// draw the first three columns on one page
table.WriteSelectedRows(0, 2, 0, -1, 236, 806, canvas);
document.NewPage();
// draw the next three columns on the next page
table.WriteSelectedRows(2, -1, 0, -1, 36, 806, canvas);

在第一次調用WriteSelectedRows方法時我們將前兩列添加到一頁中,其它的列添加到下一頁中。通過WriteSelectedRows方法可以將表格絕對定位,但還有一種絕對定位的方法:將PdfPTable對象包裹在ColumnText對象中。

Wrapping tables in columns

好了直接上圖和代碼:

ColumnTable

listing 4.23 ColumnTable.cs

ColumnText column = new ColumnText(writer.DirectContent);
List<DateTime> days = PojoFactory.GetDays(conn);

float[,] x ={  { document .Left ,document .Left +380},
            { document .Right -380,document .Right }};

foreach (DateTime day in days)
{
    // add content to the column
    column.AddElement(GetTable(conn, day));
    int count = 0;
    float height = 0;
    int status = ColumnText.NO_MORE_COLUMN;
    // render the column as long as it has content
    while (ColumnText.HasMoreText(status))
    {
        // add the top-level header to each new page
        if (count == 0)
        {
            height = AddHeaderTable(document, day, writer.PageNumber);
        }

        // set the dimensions of the current column
        column.SetSimpleColumn(x[count, 0], document.Bottom, x[count, 1], document.Top - height - 10);
        // render as much content as possible
        status = column.Go();
        // go to a new page if you've reached the last column
        if (++count > 1)
        {
            count = 0;
            document.NewPage();
        }
    }
    document.NewPage();
}

這里使用的是ColumnText對象的一些屬性,比較簡單就不詳細解釋。

總結

表格的絕對定位這里使用了兩種方式:WriteSelectedRows方法和ColumnText對象,這兩種方式都設計一些low-level的操作。這里第四節的內容就完全結束了,但對於PdfPTable和PdfPCell的討論還要繼續,下一節中我們會使用表格和單元格的事件進行更加完美的布局,最后是代碼下載

同步

此文章已同步到目錄索引:iText in Action 2nd 讀書筆記。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM