Persits Software, Inc. Web Site
 Navigator:  Home |  Manual |  Chapter 7: Tables
Chapter 8: Security Chapter 6: Text and Fonts
  Chapter 7: Tables
7.1 Table Support Overview
7.2 Cell Spanning and Size Adjustment
7.3 Table Rendering

7.1 Table Support Overview

With AspPDF.NET, you can create HTML-style tables and fill them with text data. Once a table is created and filled, it can be rendered onto a canvas.

Tables are represented by the PdfTable object creatable via the CreateTable method of the PdfDocument object.

PdfTable is a free-floating entity. It is not tied to a canvas, page or any other object. Creating or changing a PdfTable object has no effect on the appearance of the document until the table, or any portion thereof, is rendered onto a canvas via the Canvas.DrawTable method. The same table can be drawn on multiple pages, or be part of one or more PdfGraphics objects.

7.1.1 Table Creation Parameters

The Doc.CreateTable method requires two parameters: Width and Height (in default user units). The number of columns and rows in the table is specified via Cols and Rows, respectively. These parameters are both 1 by default. When a table is created, all rows and columns are spaced out evenly within the table.

A generic table has an outer border, and several rows of cells. Each cell has a border of its own. Cells are separated from each other and the outer border by a margin. The following diagram illustrates various table parameters:

A table's origin is located in the upper-left corner of the table. The y axis still extends upwards, so all y-coordinates of the cells are negative.

Border is the width of the table's outer border (0 by default.)

CellBorder is the width of all cell borders (1 by default.) CellSpacing is the width of a margin that separates individual cells from each other and the outer border (0 by default).

CellPadding is the width of a margin within a cell that separates text written in that cell from the cell's borders (0 by default.)

The table colors are specified by the following parameters: BorderColor (the color of the outer border, black by default), CellBorderColor (the color of all cell borders, black by default), BgColor (the color of areas between cells, transparent by default), and CellBgColor (the color of areas within cell borders, transparent by default).

As of Version 2.7, color spaces other than RGB can be used to specify table colors. See Section 16.4 - Using Color Spaces with PdfTable and Other Objects for more information.

7.1.2 Working with Individual Rows and Cells

The PdfTable object provides the Rows property which returns the PdfRows collection of PdfRow objects representing individual table rows. The PdfRow object allows you to change this row's height and move it up and down within the table. It also allows you to change border and background colors of all its cells via the BorderColor and BgColor properties.

The PdfRow object provides the Cells property which returns the PdfCells collection of PdfCell objects representing individual cells in a row. The PdfCell object enables you to change the border width, border color, background color, size, padding, ColSpan and RowSpan of an individual cell.

An individual table cell can also be referenced directly via PdfTable's two-argument indexer by specifying 1-based row and cell indices as arguments, as follows:

PdfCell objCell = objTable[4, 2];

Rows and Cells are numbered from left to right and from top to bottom. Therefore, the upper-left cell of a table has the indices [1, 1].

The PdfCell object also provides the AddText method for placing text in a cell. This method is almost identical to Canvas.DrawText, except that instead of the X, Y, Width and Height parameters the cell coordinates and sizes are used, and two extra optional parameters, IndentX and IndentY are added for precise positioning of text inside the cell. This method also uses an optional Expand parameter described below. AddText's Font argument is optional but for it to be omitted, you must specify a table-wide default font via the PdfTable.Font property.

The following code sample uses all the properties, methods and collections described above to draw a chessboard. Here, we also use a freeware symbol font Chess Merida residing in the file MERIFONT.TTF.

C#
PdfManager objPdf = new PdfManager();

// Create empty document
PdfDocument objDoc = objPdf.CreateDocument();

// Create 8x8 table to depict a chessboard
PdfTable objTable = 
	objDoc.CreateTable( "width=200;height=200;rows=8;cols=8;border=1;cellborder=0;cellspacing=2");

// Select a Chess font to depict chess pieces
PdfFont objFont = objDoc.Fonts.LoadFromFile( Server.MapPath("MERIFONT.TTF") );

objTable.Font = objFont;

// initialize Pieces array
int	[] Pieces = {0,
0xF074, 0xF06D, 0xF076, 0xF077, 0xF06C, 0xF076, 0xF06D, 0xF074,
0xF06F, 0xF06F, 0xF06F, 0xF06F, 0xF06F, 0xF06F, 0xF06F, 0xF06F,
0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000,
0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000,
0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000,
0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000,
0xF070, 0xF070, 0xF070, 0xF070, 0xF070, 0xF070, 0xF070, 0xF070,
0xF072, 0xF06E, 0xF062, 0xF071, 0xF06B, 0xF062, 0xF06E, 0xF072 };

// go over all cells in the table
foreach( PdfRow objRow in objTable.Rows )
{
	foreach( PdfCell objCell in objRow.Cells )
	{
		// set background on cells which sum of indices is odd
		if( (objCell.Index + objRow.Index) % 2 == 1 )
			objCell.BgColor = "brown";
		
		int Piece = Pieces[ 8 * (objRow.Index - 1) + objCell.Index ];

		objCell.AddText( ((char)Piece).ToString(), "size=20; indentx=1; indenty=1" );
	}
}



// Add a new page
PdfPage objPage = objDoc.Pages.Add();

objPage.Canvas.DrawTable( objTable, "x=206, y=498" );
VB.NET
Dim objPdf As PdfManager = New PdfManager()

' Create empty document
Dim objDoc As PdfDocument = objPdf.CreateDocument()

' Create 8x8 table to depict a chessboard
Dim objTable As PdfTable = _
	objDoc.CreateTable("width=200;height=200;rows=8;cols=8;border=1;cellborder=0;cellspacing=2")

' Select a Chess font to depict chess pieces
Dim objFont As PdfFont = objDoc.Fonts.LoadFromFile(Server.MapPath("MERIFONT.TTF"))

objTable.Font = objFont

' initialize Pieces array
Dim Pieces() As Integer = {0, _
&HF074, &HF06D, &HF076, &HF077, &HF06C, &HF076, &HF06D, &HF074, _
&HF06F, &HF06F, &HF06F, &HF06F, &HF06F, &HF06F, &HF06F, &HF06F, _
&HF000, &HF000, &HF000, &HF000, &HF000, &HF000, &HF000, &HF000, _
&HF000, &HF000, &HF000, &HF000, &HF000, &HF000, &HF000, &HF000, _
&HF000, &HF000, &HF000, &HF000, &HF000, &HF000, &HF000, &HF000, _
&HF000, &HF000, &HF000, &HF000, &HF000, &HF000, &HF000, &HF000, _
&HF070, &HF070, &HF070, &HF070, &HF070, &HF070, &HF070, &HF070, _
&HF072, &HF06E, &HF062, &HF071, &HF06B, &HF062, &HF06E, &HF072}

' go over all cells in the table
For Each objRow As PdfRow In objTable.Rows

    For Each objCell As PdfCell In objRow.Cells

        ' set background on cells which sum of indices is odd
        If (objCell.Index + objRow.Index) Mod 2 = 1 Then
            objCell.BgColor = "brown"
        End If
	
        Dim Piece As Integer = Pieces(8 * (objRow.Index - 1) + objCell.Index)

        objCell.AddText(ChrW(Piece), "size=20; indentx=1; indenty=1")
    Next
Next



' Add a new page
Dim objPage As PdfPage = objDoc.Pages.Add()

objPage.Canvas.DrawTable(objTable, "x=206, y=498")

Click the links below to run this code sample:

http://localhost/asppdf.net/manual_07/07_chess.cs.aspx
http://localhost/asppdf.net/manual_07/07_chess.vb.aspx  Make sure AspPDF.NET is installed on your local machine and IIS is running for these links to work.

7.1.3 Cell Border Management

By default, each cell's border is a rectangle with all four sides drawn in the same color (specified via Cell.BorderColor). It is also possible to hide any, or all, of this rectangle's sides, and also assign individual colors to each side.

Side visibility and coloring is set via PdfCell's SetBorderParams method which accepts a PdfParam object or parameter string as an argument. The following parameters can be used (all optional):

  • Top, Bottom, Right, Left - if set to False, hide the top, bottom, right or left side of the cell border, respectively. True by default.
  • TopColor, BottomColor, RightColor, LeftColor - specify the line color for the top, bottom, right or left side, respectively.

The following code fragment hides the left, top and right sides of a cell and sets the bottom side color to green:

objTable[1, 2].SetBorderParams( "Left=False, Right=False, Top=False, BottomColor=Green" );

7.1.4 Drawing in a Cell

The PdfCell object provides a Canvas property which enables you to draw inside an individual cell the same way you would on a page as a whole. The coordinate space origin is located in the lower-left corner of the cell. Cell.Canvas allows you to draw graphics, text and even other tables inside a cell.

When a table is rendered onto a page, its cells' contents is rendered in the following order:

1. Cell background.
2. The contents of Cell.Canvas, if any.
3. Text strings specified via Cell.AddText, if any.
4. Cell borders.

The following code fragment draws a small table inside a large table's cell. The small table, in turn, has the word "Hello" drawn in its upper-left cell.

PdfTable objSmallTable = objDoc.CreateTable("Height=30; Width=30; cols=2; rows=2");
objSmallTable[1, 1].Canvas.DrawText( "Hello", "x=1, y=15; size=5", objFont );
...

objTable[1, 2].Canvas.DrawTable( objSmallTable, "x=2; y=50" );

Note that unlike the Cell.AddText method, Cell.Canvas.DrawText does not affect the size of the cell.

7.2 Cell Spanning and Size Adjustment
As mentioned earlier, all cells are created equal in size when a new table is created. Heights and widths of individual rows and columns can then be adjusted using the PdfRow.Height, PdfCell.Height and PdfCell.Width properties. Changing PdfRow.Height changes the heights of all the cells in that row, as well as the overall table height. Changing Cell.Height has the same effect as changing the height of the row this cell belongs to. Changing Cell.Width also changes the widths of cells above and below this cell, as well as the overall table width.

The method PdfCell.AddText, if called with the parameter Expand set to True, has the side effect of changing the cell's height to accommodate the entire text string passed to it.

Similarly to HTML tables, PdfTable enables you to change the row span and column span of individual cells via the properties PdfCell.RowSpan and PdfCell.ColSpan, respectively. A cell whose ColSpan and/or RowSpan is set to a number greater than 1 "swallows" cells to the right and/or below itself. This cell's width and/or height is increased by that of the cells it "swallows" (plus the width of cell spacing, if applicable).

The following code fragment transforms a default 3 x 4 table (shown in the upper half of the diagram below) into a table shown in the lower half of the diagram:

PdfParam objParam = objPDF.CreateParam("rows=3, cols=4, width=400, height=150");
... (set other parameters)
PdfTable objTable = objDoc.CreateTable(objParam);

objTable.Rows[1].Cells[1].Width = 20;
objTable[1, 1].RowSpan = 3;
objTable[1, 3].RowSpan = 2;
objTable[1, 3].ColSpan = 2;
objTable.Rows[1].Cells[2].Width = 200;
objTable[3, 2].AddText( "Hello World!!!", "size=30; expand=true", objFont );

Note that the height of row 3 was implicitly increased by calling AddText with the Expand parameter set to True. If that parameter were omitted, only the word "Hello" would be showing and the cell height would remain unchanged.

Rows can be added to a table via the Rows.Add method which takes two arguments: row height and, optionally, the desired position of the new row. By default, rows are added to the end of the table. The second argument is the 1-based index of a row to insert the new one after. The value of 0 means the new row becomes first.

7.3 Table Rendering
Once a table is created, adjusted and filled with data, it can be rendered onto a canvas via the Canvas.DrawTable method. This method expects two requires parameters, X and Y, which specify the coordinates of the table's upper-left corner (origin) on the canvas.

The DrawTable method also accepts an optional MaxHeight parameter which limits the vertical space the table can occupy on a canvas. By default, the limit is the bottom of the canvas. If a row does not fully fit in the space provided, it is not rendered, and neither are the rows that follow.

The DrawTable method is capable of rendering only a certain range of rows, or a set of ranges. This is especially handy when you need to render a large table that spans several pages, and you want the header and/or footer rows of the table to be present on each page. The row ranges are specified via the parameters RowFrom - RowTo, RowFrom1 - RowTo1, RowFrom2- RowTo2, etc.

DrawTable returns the index of the last row it managed to render.

The following code sample renders a multi-page report from data residing in a database table. This sample dynamically appends pages to the PDF document as needed to accommodate the table. The data for this code sample is taken from the MS Access file asppdf.mdb residing in the \Samples\Db subdirectory of the installation.

C#
PdfManager objPdf = new PdfManager();

// Create empty param objects to be used across the app
PdfParam objParam = objPdf.CreateParam();
PdfParam objTextParam = objPdf.CreateParam();

// Create empty document
PdfDocument objDoc = objPdf.CreateDocument();

// Create table with one row (header), and 5 columns
PdfTable objTable = 
    objDoc.CreateTable("width=500;height=20;Rows=1;Cols=5;Border=1;CellSpacing=-1;cellpadding=2");

// Set default table font
objTable.Font = objDoc.Fonts["Helvetica"];

PdfRow objHeaderRow = objTable.Rows[1];
objParam.Set("alignment=center");
objHeaderRow.BgColor = 0x90F0FE;
objHeaderRow[1].AddText( "Category", objParam );
objHeaderRow[2].AddText( "Description", objParam );
objHeaderRow[3].AddText( "Billable", objParam );
objHeaderRow[4].AddText( "Date", objParam );
objHeaderRow[5].AddText( "Amount", objParam );

// Set column widths
objHeaderRow[1].Width = 80;
objHeaderRow[2].Width = 160;
objHeaderRow[3].Width = 50;
objHeaderRow[4].Width = 70;
objHeaderRow[5].Width = 60;

objParam.Set( "expand=true" ); // expand cells vertically

// Build OLE DB connection string
String strConnect = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + 
	Server.MapPath("..\\db\\asppdf.mdb");

// If you use SQL Server, the connecton string must look something like this:
// strConnect = "Provider=SQLOLEDB;Server=MYSRV;Database=master;UID=sa;PWD=xxx"

OleDbConnection myConnection = new OleDbConnection( strConnect );
myConnection.Open();

OleDbDataAdapter myDataAdapter = new OleDbDataAdapter ("select * from report", myConnection);
DataSet myDataSet = new DataSet();
myDataAdapter.Fill( myDataSet, "report" );

// Populate table with data
DataTable tbl = myDataSet.Tables[0];
int nCount = tbl.Rows.Count;
for( int i = 0; i < nCount; i++ )
{
	PdfRow objRow = objTable.Rows.Add(20); // row height
	
	objParam.Add( "alignment=left" );
	objRow[1].AddText( tbl.Rows[i]["Category"].ToString(), objParam );
	objRow[2].AddText( tbl.Rows[i]["Description"].ToString(), objParam );
	
	objParam.Add( "alignment=center" );

	String strBillable;
	if( tbl.Rows[i]["Billable"].ToString() == "True" )
		strBillable = "Yes";
	else 
		strBillable = "No";

	DateTime dt = new DateTime();
	dt = (DateTime)tbl.Rows[i]["ExpenseDate"];
	objRow[3].AddText( strBillable, objParam );
    objRow[4].AddText(dt.ToString("MMM dd, yyyy"), objParam);

	float fAmount = Decimal.ToSingle( (Decimal)tbl.Rows[i]["Amount"] );
	objParam.Add( "alignment=right" );
	objRow[5].AddText( fAmount.ToString("0,0.00"), objParam );
}

// Render table on document, add pages as necessary
PdfPage objPage = objDoc.Pages.Add(612, 150); 

objParam.Clear();
objParam["x"] = (objPage.Width - objTable.Width) / 2; // center table on page
objParam["y"] = objPage.Height - 20;
objParam["MaxHeight"] = 100;

int nFirstRow = 2; // use this to print record count on page
while( true )
{
	// Draw table. This method returns last visible row index
	int nLastRow = objPage.Canvas.DrawTable( objTable, objParam );

	// Print record numbers
	objTextParam["x"] = (objPage.Width - objTable.Width) / 2;
	objTextParam["y"] = objPage.Height - 5;
	objTextParam.Add("color=darkgreen");
	String strTextStr = "Records " + (nFirstRow - 1) + 
		" to " + (nLastRow - 1) + 
		" of " + (objTable.Rows.Count - 1 );
	
	objPage.Canvas.DrawText( strTextStr, objTextParam, objDoc.Fonts["Courier-Bold"] );

	if( nLastRow >= objTable.Rows.Count )
		break; // entire table displayed

	// Display remaining part of table on the next page
	objPage = objPage.NextPage;
	objParam.Add( "RowTo=1; RowFrom=1" );	// Row 1 is header - must always be present.
	objParam["RowFrom1"] = nLastRow + 1;	// RowTo1 is omitted and presumed infinite

	nFirstRow = nLastRow + 1;
}


// Save document, the Save method returns generated file name
String strFilename = objDoc.Save( Server.MapPath("report.pdf"), false );
VB.NET
Dim objPdf As PdfManager = New PdfManager()

' Create empty param objects to be used across the app
Dim objParam As PdfParam = objPdf.CreateParam()
Dim objTextParam As PdfParam = objPdf.CreateParam()

' Create empty document
Dim objDoc As PdfDocument = objPdf.CreateDocument()

' Create table with one row (header), and 5 columns
Dim objTable As PdfTable = _
	objDoc.CreateTable("width=500;height=20;Rows=1;Cols=5;Border=1;CellSpacing=-1;cellpadding=2")

' Set default table font
objTable.Font = objDoc.Fonts("Helvetica")

Dim objHeaderRow As PdfRow = objTable.Rows(1)
objParam.Set("alignment=center")
objHeaderRow.BgColor = &H90F0FE
objHeaderRow(1).AddText("Category", objParam)
objHeaderRow(2).AddText("Description", objParam)
objHeaderRow(3).AddText("Billable", objParam)
objHeaderRow(4).AddText("Date", objParam)
objHeaderRow(5).AddText("Amount", objParam)

' Set column widths
objHeaderRow(1).Width = 80
objHeaderRow(2).Width = 160
objHeaderRow(3).Width = 50
objHeaderRow(4).Width = 70
objHeaderRow(5).Width = 60

objParam.Set("expand=true") ' expand cells vertically

' Build OLE DB connection string
Dim strConnect As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + _
        Server.MapPath("..\db\asppdf.mdb")

' If you use SQL Server, the connecton string must look something like this:
' strConnect = "Provider=SQLOLEDB;Server=MYSRV;Database=master;UID=sa;PWD=xxx"

Dim myConnection As OleDbConnection = New OleDbConnection(strConnect)
myConnection.Open()

Dim myDataAdapter As OleDbDataAdapter = New OleDbDataAdapter("select * from report", myConnection)
Dim myDataSet As DataSet = New DataSet()
myDataAdapter.Fill(myDataSet, "report")

' Populate table with data
Dim tbl As DataTable = myDataSet.Tables(0)
Dim nCount As Integer = tbl.Rows.Count
For i As Integer = 0 To nCount - 1

    Dim objRow As PdfRow = objTable.Rows.Add(20) ' row height

    objParam.Add("alignment=left")
    objRow(1).AddText(tbl.Rows(i)("Category").ToString(), objParam)
    objRow(2).AddText(tbl.Rows(i)("Description").ToString(), objParam)

    objParam.Add("alignment=center")

    Dim strBillable As String
    If tbl.Rows(i)("Billable").ToString() = "True" Then
        strBillable = "Yes"
    Else
        strBillable = "No"
    End If
    
    Dim dt As DateTime = New DateTime()
    dt = CType(tbl.Rows(i)("ExpenseDate"), DateTime)
    objRow(3).AddText(strBillable, objParam)
    objRow(4).AddText(dt.ToString("MMM dd, yyyy"), objParam)

    Dim fAmount As Single = Decimal.ToSingle(CType(tbl.Rows(i)("Amount"), Decimal))
    objParam.Add("alignment=right")
    objRow.Cells(5).AddText(fAmount.ToString("0,0.00"), objParam)
Next

' Render table on document, add pages as necessary
Dim objPage As PdfPage = objDoc.Pages.Add(612, 150)

objParam.Clear()
objParam("x") = (objPage.Width - objTable.Width) / 2 ' center table on page
objParam("y") = objPage.Height - 20
objParam("MaxHeight") = 100

Dim nFirstRow As Integer = 2 ' use this to print record count on page
While True

    ' Draw table. This method returns last visible row index
    Dim nLastRow As Integer = objPage.Canvas.DrawTable(objTable, objParam)

    ' Print record numbers
    objTextParam("x") = (objPage.Width - objTable.Width) / 2
    objTextParam("y") = objPage.Height - 5
    objTextParam.Add("color=darkgreen")
    Dim strTextStr As String = "Records " + (nFirstRow - 1).ToString() + _
        " to " + (nLastRow - 1).ToString() + _
        " of " + (objTable.Rows.Count - 1).ToString()

    objPage.Canvas.DrawText(strTextStr, objTextParam, objDoc.Fonts("Courier-Bold"))

    If nLastRow >= objTable.Rows.Count Then Exit While ' entire table displayed

    ' Display remaining part of table on the next page
    objPage = objPage.NextPage
    objParam.Add("RowTo=1; RowFrom=1")    ' Row 1 is header - must always be present.
    objParam("RowFrom1") = nLastRow + 1 ' RowTo1 is omitted and presumed infinite

    nFirstRow = nLastRow + 1
End While


' Save document, the Save method returns generated file name
Dim strFilename As String = objDoc.Save(Server.MapPath("report.pdf"), False)

Click the links below to run this code sample:

http://localhost/asppdf.net/manual_07/07_db.cs.aspx
http://localhost/asppdf.net/manual_07/07_db.vb.aspx  Make sure AspPDF.NET is installed on your local machine and IIS is running for these links to work.

Chapter 8: Security Chapter 6: Text and Fonts
Search AspPDF.net

Newsletter Signup

Other Products
AspPDF
AspUpload
AspJpeg
AspEmail
AspEncrypt
AspGrid
AspUser
  This site is owned and maintained by Persits Software, Inc. Copyright © 2003 - 2014. All Rights Reserved.