The article describes how to add a table to a document, configure the table and add content to it.
Using the library, you can create a wide variety of tables, including:
Tables with various content. You can add paragraphs, images, lines, and nest tables in a table.
Tables of different sizes. You can set a table size, row and column sizes. If you have a large table with a lot of rows, it will continue on the next page automatically.
Tables with different formatting. You can use easy-to-set styles for a whole table and its headers, footers, content and alternate rows, as well as instruments for precise formatting of each element.
Multipage tables. You do not have to calculate whether a table will fit into a page, the library can calculate this automatically and continue the table on the next page or a number of pages if necessary.
Tables from a JSON data source.
Tables with rowspan and colspan.
Note that tables can be used to create blocks of content with a complex layout where some of the elements are located on the same level, not after one another, and include different types of elements. For more details, see the Layouting Using Tables article.
Adding a Table
You can add a table to a section and to a repeating area.
To add a a table to a section, you can use the following options:
Call one of the AddTable
methods.
The AddTable
method allows you to add a table and specify the column width.
The AddTable
method allows you to add a table,
configure the table and add content to it inside this method.
mySectionBuilder.AddTable(...)
Call the AddTableToSection
method
to add a table, configure it and return SectionBuilder.
mySectionBuilder.AddTableToSection(...)
.AddParagraph("Some paragraph added to the section")
Call the TableBuilder.New
method and pass the instance of
SectionBuilder
you want to add this table to in this method.
To add a table to a repeating area, you can use one of the following:
Call the AddTable
method to add a table and specify the column width.
myRepeatingAreaBuilder.AddTable(...)
Call the AddTableToRepeatingArea
method
to add a table, configure it and return area.
myRepeatingAreaBuilder.AddTableToRepeatingArea(...)
Configuring the Table
When you add a table and do not specify any style or formatting for it, it will be created with default formatting settings defined in the default table style.
Each table has the following formatting:
Parameter |
Default value |
Methods for configuration (available in |
Borders |
|
|
Font |
|
|
Text overflow action |
|
|
Alignment |
Left |
|
Background color |
No color |
|
Page break |
No page break |
|
Keeping with the next element |
|
For details about formatting and styles, see the Formatting and Styles article.
The style and formatting for an entire table can be configured using methods of the TableBuilder
class.
For example:
myTableBuilder.SetContentRowStyleHorizontalAlignment(HorizontalAlignment.Center)
Page Break
When you need to start a table from a new page, insert a page break before the table using the method SetPageBreak()
.
If you call this method without the parameter, the table will start from the next page or remain on the current page if it is located at the beginning of the page.
You can specify the page from which the table will start in the method parameter. The available options are:
NextPage (the default page break) - the table starts from the next page or remains on the current page if it is located at the beginning of the page.
NextEvenPage - the table starts from the next even page or remains on the current page if it is located at the beginning of an even page.
NextOddPage - the table starts from the next odd page or remains on the current page if it is located at the beginning of an odd page.
The available page breaks are listed in the PageBreak
enumeration.
See Example 13 below for a code illustration.
Adding and Configuring Columns, Rows, and Cells
After you add a table to a section or repeating area, you should add columns, rows and cells to the table by following these steps:
Add columns to the table using one of the following options:
Call one of the AddColumn
(returning TableColumn) or AddColumnToTable
(returning Table) methods.
Call the AddColumnPercent
method to set the column width in percent.
Call any of these methods for each column you want to add.
For example:
myTableBuilder
.AddColumnToTable()
.AddColumn()
.ToTable()
.AddColumnPercent(35);
Add a row to the table by calling one of the AddRow
(returning TableRow)or
AddRowToTable
(returning Table) methods.
For example,
myTable.AddRow(...)
Add cells to the row by calling one of the AddCell
(returining TableCell) or
AddCellToRow
(returning TableRow) methods.
The number of cells in the row must be equal to the number of columns in the table.
The style and formatting for table columns, rows and cells can be configured using the methods of
TableColumnBuilder
,
TableRowBuilder
, and
TableCellBuilder
respectively.
Adding Content to the Table
Table content is contained in cells. A cell can contain paragraphs, images, and nested tables.
To add a paragraph to a cell, you can use one of the following options:
Call one of the AddParagraph
methods, it will return an instance of
ParagraphBuilder
.
myTableCellBuilder.AddParagraph(....)
Call one of the AddParagraphToCell
methods, it will return the current
TableCellBuilder
.
For more on working with paragraphs, see Adding Paragraph.
To add an image to a cell, you can use one of the following options:
Call one of the AddImage
methods, it will return an instance of
ImageBuilder
.
myTableCellBuilder.AddImage(....)
Call one of the AddImageToCell
methods, it will return the current
TableCellBuilder
.
For more on working with images, see Adding Image.
To nest a table in a cell, you can use one of the following options:
Call the AddTable
method.
myTableCellBuilder.AddTable(...)
Call the TableBuilder.New
method and pass the instance of
TableCellBuilder
you want to nest this table in.
var myTable1 = TableBuilder.New(myCellBuilder)
Configuring Table Borders
In the default table style, table borders have the following parameters: stroke = Solid
, color = Black
, width = 0.5f
.
Table borders can be configured for each cell, for each row (i.e. for all cells in the row), and for a whole table (i.e. for all cells in the table).
You can configure borders using one of the SetBorder
methods:
SetBorder(Stroke stroke, Color color, float width)
to set the border stroke style, color, and width.
SetBorder(Stroke strokeStyle, Color color)
to set the border stroke style and color.
SetBorder(Stroke strokeStyle)
to set the border stroke style. Use SetBorder()
without the parameter to reset the default border
settings for the cell or row, for example, if they were redefined by the style applied on a higher level (the row for a cell, the table for a row).
SetBorder(Action<BorderBuilder> borderConfigure)
to set border using a configuration action.
You can also set the width, height, and stroke style for all border sides or for each border side using the methods SetBorderStroke
, SetBorderColor
,
and SetBorderWidth
for a cell, for a row, or for a table.
If you set one or two of the parameters, the other parameter or parameters will have the values set on a higher level - on the row level for a cell, on the table level for a row, and in the default table style for a table. For example, if you set only the border width for an entire table, the table will have the default border stroke style and color; if you set only the border stroke style for a row in this table, the row will have the border width set for the table and the default border color; if you set only the border color for a cell in this row, the cell will have the border width set for the table and the border stroke style set for the row.
Example 1. Setting table borders Hide
DocumentBuilder.New()
.AddSection()
.AddTable()
.SetBorderWidth(2.0f)
.AddColumnToTable()
.AddColumnToTable()
.AddRow()
.SetBorderStroke(Stroke.Dashed)
.AddCell("Cell1")
.SetBorderColor(Color.Blue)
.ToRow()
.AddCell("Cell2")
.SetBorderColor(Color.Red)
.ToDocument()
.Build("Result.pdf");
Example 1a. Setting table borders (using configuration actions) Show
The above code will generate the following:
Note that if any of these three border parameters are not set for a cell, row or table by direct formatting, but these parameters are specified in a style is applied to the cell, row or table, the values will be taken from the style of the corresponding element, if specified, or from a style of a higher level element. So the following code will generate the same document because the border width will be taken from the table style:
Example 2. Taking border parameters from a style Hide
DocumentBuilder.New()
.AddSection()
.AddTable()
.ApplyStyle(StyleSheet.DefaultTableStyleBuilder().SetBorderWidth(2.0f))
.AddColumnToTable()
.AddColumnToTable()
.AddRow()
.SetBorderStroke(Stroke.Dashed)
.AddCell("Cell1")
.SetBorderColor(Color.Blue)
.ToRow()
.AddCell("Cell2")
.SetBorderColor(Color.Red)
.ToDocument()
.Build("Result.pdf");
Example 2a. Taking border parameters from a style (using configuration actions) Show
Configuring Table Background Color
You can specify the background color:
For an entire table using the
TableBuilder.SetBackColor
method.
For content, alternate, header, and footer rows using the
SetContentRowStyleBackColor
,
SetAltRowStyleBackColor
,
SetHeaderRowStyleBackColor
, and
SetFooterRowStyleBackColor
methods respectively.
For a particular table row using the
TableRowBuilder.SetBackColor
method.
For a particular cell using the
TableCellBuilder.SetBackColor
method.
When you add a paragraph to a table cell or nest a table into a table cell, you can specify the
background color for the paragraph and for the table (the entire table, its rows, and cells)
using the SetBackColor
methods of
ParagraphBuilder
,
TableBuilder
,
TableRowBuilder
, and
TableCellBuilder
.
Tables with Colspan and Rowspan
When you create a table with specifying column span and row span, make sure that the number of cells in each table row with taking into account the column span parameter is equal the number of cells in the table. You may have to add empty cells for correct table generation.
For example, you create a table with two columns and add the same number of rows to the first table row:
section.AddTable(tableBuilder =>
{
tableBuilder.AddColumn()
.AddColumn();
tableBuilder.AddRowToTable(rowBuilder =>
{
rowBuilder.AddCellToRow("cell1.1");
rowBuilder.AddCellToRow("cell1.2");
});
.....
In the second row, a cell with colspan = 2
spans two columns:
tableBuilder.AddRowToTable(rowBuilder =>
{
rowBuilder.AddCellToRow("cell2.1-2", 2);
});
In the third row, a cell with rowspan = 2
spans two rows, but the number of cells in the lower row must be equal to the
number of columns in the table, so it is necessary to add an empty cell:
tableBuilder.AddRowToTable(rowBuilder =>
{
rowBuilder.AddCell("cell3-4.1", 1, 2);
rowBuilder.AddCell("cell3.2");
});
tableBuilder.AddRowToTable(rowBuilder =>
{
rowBuilder.AddCell();
rowBuilder.AddCell("cell4.2");
});
});
See Example 7 below for a code illustration.
Image Columns
When you need to create a column with a certain image in each cell of this column (for example, a column with check boxes that the user should select on a form),
you can specify this image in the method AddImageColumn
or
AddImageColumnToTable
. See Example 10 below for a code illustration.
Multipage Tables
When you create a table that spreads to two pages, it is supposed that you expect to get a book spread table, that is, a number of columns will be located on an odd page and a number of columns will be located on an even page. So if such a table is added in the beginning of a document, its first page will be empty, and the table will be generated on the second and third pages (the first book spread).
You can create a table on more than two pages. To create such a table, it is necessary to specify the number of columns
to show on each page using the method SetMultipageSpread
.
For example, for a table containing 12 columns, calling
mytable.SetMultipageSpread(4, 3, 5)
will make the first four columns rendered on the first page, the following three columns - on the second page, and the remaining five - on the third page. If some of the table rows do not fit into one page, they will continue on the fourth page for the first four columns, on the fifth page for the following three columns, and on the sixth page for the remaining five columns.
You can also make the library automatically calculate whether a table fits into the page or not and continue the table on the next page or a number of pages if necessary.
For this, enable the automatic multi-page spread mode using the method SetAutomaticMultipageSpreadMode
.
See Examples 11 and 12 below for code illustrations.
See also
Examples
Example 3. Add a simple table to a section Hide
DocumentBuilder.New()
.AddSection()
.AddParagraph("Simple table")
.SetBold()
.SetMarginBottom(5)
.ToSection()
.AddTable()
.SetWidth(300)
.SetContentRowStyleHorizontalAlignment(HorizontalAlignment.Center)
.SetAltRowStyleHorizontalAlignment(HorizontalAlignment.Center)
.AddColumnToTable("City")
.AddColumnToTable("State")
.AddColumnToTable("Population")
.AddRow()
.AddCellToRow("New York")
.AddCellToRow("New York")
.AddCellToRow("8,336,817")
.ToTable()
.AddRow()
.AddCellToRow("Los Angeles")
.AddCellToRow("California")
.AddCellToRow("3,979,576")
.ToTable()
.AddRow()
.AddCellToRow("Chicago")
.AddCellToRow("Illinois")
.AddCellToRow("2,693,976")
.ToDocument()
.Build("Result.pdf");
The above code will generate the following:
See the document
Example 3a. Add a simple table to a section (using configuration actions) Show
Example 4. Add a simple table to a repeating area: Hide
DocumentBuilder.New()
.AddSection()
.AddHeaderToBothPages(100)
.AddParagraphToRepeatingArea("Repeating header with table")
.AddTable()
.AddColumnToTable("Column 1").AddColumnToTable("Column 2")
.AddRow()
.AddCellToRow("Row 1 Cell 1")
.AddCellToRow("Row 1 Cell 2")
.ToTable()
.AddRow()
.AddCellToRow("Row 2 Cell 1")
.AddCellToRow("Row 2 Cell 2")
.ToSection()
.AddParagraph("Main flow of the document")
.ToDocument()
.Build("Result.pdf");
The above code will generate the following:
See the document
Example 4a. Add simple table to a repeating area (using configuration actions): Show
Example 5. Add an image to a cell: Hide
DocumentBuilder.New()
.AddSection()
.AddTable()
.AddColumnToTable().AddColumnToTable()
.AddRow()
.AddCellToRow("Image in table cell:")
.AddCell()
.AddImage("imageFile.png")
.ToDocument()
.Build("Result.pdf");
The above code will generate the following:
See the document
Example 6. Add an image with formatting to a cell: Hide
DocumentBuilder.New()
.AddSection()
.AddTable()
.AddColumnToTable().AddColumnToTable()
.AddRow()
.AddCellToRow("Image in table cell:")
.AddCell()
.AddImage("imageFile.png", 50, 50, ScalingMode.UserDefined)
.SetAlignment(HorizontalAlignment.Center)
.SetBorder(Stroke.Dotted, Color.Blue, 1.4f)
.SetMargins(10)
.ToDocument()
.Build("Result.pdf");
The above code will generate the following:
See the document
Example 7. Add a table with colspan and rowspan: Hide
DocumentBuilder.New()
.AddSection()
.AddParagraph("Table with colspan and rowspan:")
.SetBold()
.SetMarginBottom(5)
.ToSection().AddTable().SetWidth(300)
.AddColumnToTable().AddColumnToTable()
.AddColumnToTable().AddColumnToTable()
.AddRow()
.SetBackColor(Color.FromRgba(0, 0.69, 0.94, 1)).SetBold()
.AddCell("Product")
.SetRowSpan(2)
.SetVerticalAlignment(VerticalAlignment.Center)
.ToRow()
.AddCell("Month")
.SetColSpan(3)
.SetHorizontalAlignment(HorizontalAlignment.Center)
.ToTable()
.AddRow().SetHorizontalAlignment(HorizontalAlignment.Center)
.AddCellToRow()
.AddCellToRow("January")
.AddCellToRow("February")
.AddCellToRow("March")
.SetBackColor(Color.FromRgba(0, 0.69, 0.94, 1))
.SetBold()
.SetHorizontalAlignment(HorizontalAlignment.Center)
.ToTable().AddRow()
.SetHorizontalAlignment(HorizontalAlignment.Center)
.AddCell()
.AddParagraphToCell("Product 1")
.SetHorizontalAlignment(HorizontalAlignment.Left)
.ToRow()
.AddCellToRow("1,000")
.AddCellToRow("1,015")
.AddCellToRow("1,030")
.ToTable().AddRow()
.SetHorizontalAlignment(HorizontalAlignment.Center)
.AddCell()
.AddParagraphToCell("Product 2")
.SetHorizontalAlignment(HorizontalAlignment.Left)
.ToRow()
.AddCellToRow("2,000")
.AddCellToRow("2,040")
.AddCellToRow("2,075")
.ToTable().AddRow()
.SetHorizontalAlignment(HorizontalAlignment.Center)
.AddCell()
.AddParagraphToCell("Product 3")
.SetHorizontalAlignment(HorizontalAlignment.Left)
.ToRow()
.AddCellToRow("3,000")
.AddCellToRow("3,060")
.AddCellToRow("3,100")
.ToTable().AddRow()
.SetBackColor(Color.FromRgba(0, 0.69, 0.94, 1))
.SetBold()
.AddCellToRow("Total for Q1")
.AddCell("18,320")
.SetHorizontalAlignment(HorizontalAlignment.Left)
.SetColSpan(3)
.ToDocument().Build("Result.pdf");
The above code will generate the following:
See the document
Example 8. Add a complex table with images and nested tables Hide
//Create data structures for tables to avoid a lot of code and to use cycles instead
//In a real application, you can get data from an external source, database or .json file
//Define two structures in your 'Program' class, somewhere outside of methods:
internal struct Game
{
public string name;
public string logo;
public CountryResult[] result;
public Game(string name, string logo, CountryResult[] result)
{
this.name = name;
this.logo = logo;
this.result = result;
}
}
internal struct CountryResult
{
public string country;
public int[] mc;
public CountryResult(string country, int[] mc)
{
this.country = country;
this.mc = mc;
}
}
private static void Main(string[] args)
{
var folderPath = Environment.CurrentDirectory;
var imgPath = Path.Combine(folderPath, "Content", "Images");
// Fill data for the table
Game[] games =
{
new Game("2018 Winter Olympics",
Path.Combine(imgPath, "olyw23.png"),
new CountryResult[]
{
new CountryResult("Norway", new int[] {14, 14, 11 }),
new CountryResult("Germany", new int[] { 14, 10, 7 }),
new CountryResult("Canada", new int[] { 11, 8, 10 })
}),
new Game("2016 Summer Olympics",
Path.Combine(imgPath, "olys31.png"),
new CountryResult[]
{
new CountryResult("United States", new int[] { 46, 37, 38 }),
new CountryResult("Great Britain", new int[] { 27, 23, 17 }),
new CountryResult("China", new int[] { 26, 18, 26 })
}),
new Game("2014 Winter Olympics",
Path.Combine(imgPath, "olyw22.png"),
new CountryResult[]
{
new CountryResult("Russia", new int[] { 11, 10, 9 }),
new CountryResult("Norway", new int[] { 11, 5, 10 }),
new CountryResult("Canada", new int[] { 10, 10, 5 })
})
};
// Create a document and add a section to it
var document = DocumentBuilder.New();
var section = document.AddSection()
.AddParagraph("Complex table with images and table in table:")
.SetBold()
.SetMarginBottom(5)
.ToSection();
// Add a table to the section
var outerTableBuilder = section.AddTable()
.SetHeaderRowStyleMinHeight(20)
.SetHeaderRowStyleBackColor(Color.Gray)
.AddColumnPercentToTable("Games", 25)
.AddColumnPercentToTable("Logo", 25)
.AddColumnPercent("Winners", 50)
.ToTable();
// Fill the table with the data
foreach (Game game in games)
{
var cell = outerTableBuilder.AddRow()
.AddCell(game.name)
.SetVerticalAlignment(VerticalAlignment.Center)
.SetHorizontalAlignment(HorizontalAlignment.Center)
.ToRow().AddCell()
.AddParagraph()
.SetAlignment(HorizontalAlignment.Center)
.AddInlineImage(game.logo)
.SetScale(ScalingMode.UserDefined)
.SetHeight(70)
.ToRow().AddCell();
var tableBuilder = cell.AddTable()
.AddColumnToTable("Country")
.AddColumnToTable("Gold")
.AddColumnToTable("Silver")
.AddColumnToTable("Bronze")
.AddColumnToTable("Total")
.SetHeaderRowStyleFont(FontBuilder.New().SetSize(10).SetBold());
foreach (CountryResult countryResult in game.result)
{
var rowBuilder = tableBuilder.AddRow();
rowBuilder.AddCell()
.AddParagraph(countryResult.country)
.SetAlignment(HorizontalAlignment.Right);
int sum = 0;
foreach (int mc in countryResult.mc)
{
sum += mc;
rowBuilder
.AddCellToRow(mc.ToString());
}
rowBuilder
.AddCellToRow(sum.ToString())
.SetHorizontalAlignment(HorizontalAlignment.Center);
}
}
document.Build("Result.pdf");
}
The above code will generate the following:
See the document
Example 9. Add a table with data from data source Hide
public static void CreateExample()
{
string simpleJSON = @"[
{
CountryId: 'AU',
CountryName: 'Australia'
},
{
CountryId: 'US',
CountryName: 'The United States Of America'
}]";
DocumentBuilder.New()
.AddSection()
.AddTable()
.SetDataSource(
JsonConvert.DeserializeObject>(simpleJSON))
.ToDocument().Build("Result.pdf");
}
public class SimpleData
{
public string CountryId { get; set; }
public string CountryName { get; set; }
}
The above code will generate the following:
See the document
Example 10. Add a table with an image column Hide
public static void CreateExample()
{
string simpleJSON = @"[
{
CountryId: 'AU',
CountryName: 'Australia'
},
{
CountryId: 'US',
CountryName: 'The United States Of America'
}]";
var image = ImageBuilder.New()
.SetFile(Path.Combine(Environment.CurrentDirectory,
"Content", "Images", "checkbox.png"))
.SetScale(ScalingMode.UserDefined)
.SetSize(12, 12)
.SetMargins(2);
DocumentBuilder.New()
.AddSection()
.AddTable()
.AddImageColumnToTable("Image column", image)
.SetDataSource(
JsonConvert.DeserializeObject>(simpleJSON))
.ToDocument().Build("Result.pdf");
}
public class SimpleData
{
public string CountryId { get; set; }
public string CountryName { get; set; }
}
The above code will generate the following:
See the document
Example 11. Add a multipage spread table Hide
var builder = DocumentBuilder.New();
TableBuilder t = builder.AddSection().AddTable()
.SetMultipageSpread(4, 3)
.AddColumnToTable("100pt", 100).AddColumnToTable("50pt", 50)
.AddColumnToTable("50pt", 50).AddColumnPercentToTable("50%", 50)
.AddColumnToTable("150pt", 150).AddColumnToTable("300pt", 300)
.AddColumnPercentToTable("10%", 10);
for (int i = 1; i <= 20; i++)
{
TableRowBuilder r = t.AddRow();
for (int j = 1; j <= 7; j++)
{
TableCellBuilder c = r.AddCell("Row" + i.ToString() + " Cell" + j.ToString());
if (((i == 2) && (j == 2)) || ((i == 6) && (j == 4)))
c.AddParagraph("This is a long text leading to several lines in one cell");
}
}
builder.Build("Result.pdf");
The above code will generate the following:
See the document
Example 11a. Add a multipage spread table (using configuration actions) Show
Example 12. Add a multipage spread table with the enabled automatic multipage spread mode Hide
var builder = DocumentBuilder.New();
TableBuilder t = builder
.AddSection()
.AddTable()
.SetAutomaticMultipageSpreadMode()
.AddColumnToTable("100pt", 100)
.AddColumnToTable("50pt", 50)
.AddColumnToTable("50pt", 50)
.AddColumnToTable("200pt", 200)
.AddColumnToTable("150pt", 150)
// The last two columns do not fit into the first page,
// so they will be rendered on the second page:
.AddColumnToTable("300pt", 300)
.AddColumnToTable("100pt", 100);
for (int i = 1; i <= 20; i++)
{
TableRowBuilder r = t.AddRow();
for (int j = 1; j <= 7; j++)
{
TableCellBuilder c = r.AddCell("Row" + i + " Cell" + j);
if (i == 2 && j == 2 || i == 6 && j == 4)
c.AddParagraph("This is a long text leading to several lines in one cell");
}
}
builder.Build("Result.pdf");
The above code will generate the following:
See the document
Example 13. Add tables with page breaks Hide
.AddSection()
.SetSize(PaperSize.C6)
.AddTable()
.SetPageBreak(PageBreak.NextPage)
.AddColumnToTable().AddRow().AddCell("Table1 has to be left at the same page")
.ToSection()
.AddTable()
.SetPageBreak(PageBreak.NextOddPage)
.AddColumnToTable().AddRow().AddCell("Table2 has to be started from page #3")
.ToSection()
.AddTable()
.SetPageBreak(PageBreak.NextEvenPage)
.AddColumnToTable().AddRow().AddCell("Table3 has to be started from page #4")
.ToSection()
.AddFooterToBothPages(20)
.AddParagraph()
.AddPageNumber("Page #")
.ToDocument()
The above code will generate the following:
See the document