Layouting Using Tables

Brief

The article describes how to create blocks of content with complex layout using tables with colspan and rowspan and nested tables.

Details

You can create a complex block of content where some of the elements are located on the same level, not after one another, using a table with colspan and rowspan and nested tables. In many cases, setting rowspan and colspan parameters for table cells allow you to get the necessary table. For more complex cases, you should divide your table into several logical parts and add them as nested tables.

Using rowspan and colspan parameters

If you need to get a table with cells spanning several rows and columns, similar to this one:

Set the rowspan and colspan for the appropriate cells in the parameters of the AddCell() and AddCellToRow() methods or calling the methods SetRowSpan(), SetColSpan() for the cells. For example, SetRowSpan(4), SetColSpan(3).

See Example 1 below for a code illustration.

Using nested tables

If you need to get a table with a more complex structure, similar to this one:

Identify a logical part of the content and add it to the table as a nested table. This will allow you to simplify the code structure and make it easy to understand. In this table, the content located in the nested table is highlighted in blue.

You can add a part of content in a separate procedure:

 Hide

    private static void AddTablePartToCell(TableCellBuilder cell)
    {
        cell.AddTable()
                .AddColumnToTable().AddColumnToTable()
                .AddColumnToTable().AddColumnToTable()
                .AddRow()
                    .AddCell("column 1,\nRow span", 1, 4).ToRow()
                    .AddCellToRow("column 2")
                    .AddCellToRow("column 3")
                    .AddCell("column 4").ToTable()
                .AddRow()
                    .AddCellToRow().AddCellToRow()
                    .AddCellToRow().AddCellToRow().ToTable()
                .AddRow()
                    .AddCellToRow().AddCellToRow()
                    .AddCellToRow().AddCellToRow().ToTable()
                .AddRow()
                    .AddCellToRow().AddCellToRow()
                    .AddCellToRow().AddCellToRow();
    }

It will add the necessary content as a table nested in a cell.

    AddTablePartToCell(tableCell);

With the help of such decomposition, you make your code simpler, which allows you to create your documents faster.

See Example 2 below for a code illustration.

Note that if the column width in the main table is set in percent, it may be necessary to recalculate the column width for the nested table. In the above example, the main table has five columns of 20% width. The nested table (highlighted in blue) has four columns of 25% width. If all table columns have the same width, like in this case, you don't have to specify the width.



Adjusting the height of table cells

In the case when rows should not occupy the entire available space, you may need to add an empty row. To align the cells vertically, we add a row below and shift the cells up by setting the vertical padding. The cell with the vertical padding is highlighted in blue.

See Example 3 below for a code illustration. In this example, a complex part of the table is created in a separate method and the rowspan is used.

You can create even more complex tables using all the described methods. In the following table, the two highlighted parts can be added to the table as nested tables:

Then you can use colspan and rowspan to configure the nested tables. For details on working with colspan and rowspan, in particular, on adding of empty cells for rowspan, see the Adding Table article.

See Example 4 below for a code illustration.

Here's an example of a complex real document that was created using our library - Boarding Pass:

    

The area marked by a green rectangle is a table with a complex structure - it contains two nested tables - marked in red and dark-yellow. These tables are nested inside the cells of the main table that contains two columns (75% and 25% width respectively).

But it is important to note that all elements in any cell are placed after one another in any case. A clear example of this behavior is the placement of the texts: "Passenger name", "PAVEL REMPEL".

You can find a sample of the Boarding Pass document accompanied by a descriptive article here.

Using fluent style to create nested tables

When you need to create a document using a table with nested tables, as an alternative to decomposing the code into separate procedures, you can get the same result using the fluent style to code the entire complex table. You can change the current fluent context to parent objects using the following To... methods: ToTable, ToRow, ToCell, ToSection. To avoid errors when creating nested tables, it is important to correctly specify changes of the current fluent context.

Example of creating a simple table with a nested table using the fluent style:

section
                .AddTable()
                    .AddColumnToTable()
                    .AddRow()
                    .AddCell()
                        .AddTable()
                            .AddColumnToTable()
                            .AddRow()
                            .AddCell("Nested table")
                        .ToTable() // Change the fluent context to the nested table, not the parent one
                    .ToCell() // Change the fluent context to the parent cell
                .ToTable() // Change the fluent context to the parent table
                    .AddRow()
                        .AddCell("Parent table");    

See also

Adding Table



Examples

Example 1. Create a table with rowspan and colspan Hide

                .AddSection()
                    .AddTable()
                        .AddColumnToTable().AddColumnToTable()
                        .AddColumnToTable().AddColumnToTable()
                        .AddRow()
                            .AddCell("row span").SetRowSpan(4).ToRow()
                            .AddCell("col span").SetColSpan(3).ToTable()
                        .AddRow()
                            .AddCellToRow()
                            .AddCellToRow()
                            .AddCellToRow()
                            .AddCellToRow().ToTable()
                        .AddRow()
                            .AddCellToRow()
                            .AddCellToRow()
                            .AddCellToRow()
                            .AddCellToRow().ToTable()
                        .AddRow()
                            .AddCellToRow()
                            .AddCellToRow()
                            .AddCellToRow()
                            .AddCellToRow()
                .ToDocument();
 
 The above code will generate the following:
 
 
 See the document

Example 2. Create a table with a nested table Hide

        public static void DocumentBuild()
        {
            var table = DocumentBuilder.New()
                .AddSection()
                    .AddTable()
                        .AddColumnPercent("", 25).ToTable()
                        .AddColumnPercent("", 75).ToTable()
                        .AddRow()
                        .AddCell("column 1,\nrow span", 1, 3).ToRow()
                        .AddCell("column 2")
                .ToTable();
            var row2 = table.AddRow()
                            .AddCellToRow();
            AddTablePartToCell(row2.AddCell());
            table.AddRow()
                            .AddCellToRow()
                            .AddCellToRow()
            .ToDocument().Build("Result.pdf");
        }
 
        private static void AddTablePartToCell(TableCellBuilder cell)
        {
            cell.AddTable()
                    .AddColumnToTable().AddColumnToTable()
                    .AddColumnToTable().AddColumnToTable()
                    .AddRow()
                        .AddCell("column 1,\nrow span", 1, 4).ToRow()
                        .AddCellToRow("column 2")
                        .AddCellToRow("column 3")
                        .AddCell("column 4").ToTable()
                    .AddRow()
                        .AddCellToRow().AddCellToRow()
                        .AddCellToRow().AddCellToRow().ToTable()
                    .AddRow()
                        .AddCellToRow().AddCellToRow()
                        .AddCellToRow().AddCellToRow().ToTable()
                    .AddRow()
                        .AddCellToRow().AddCellToRow()
                        .AddCellToRow().AddCellToRow();
        }
 
 The above code will generate the following:
 
 
 See the document

Example 3. Create a table with a nested table and height adjustment Hide

        public static void BuildDocument()
        {
            var builder = DocumentBuilder.New();
 
            var table = DocumentBuilder.New()
                .AddSection()
                    .AddTable().SetWidth(250)
                        .AddColumnToTable()
                        .AddRow()
                            .AddCell("City information")
                                .SetHorizontalAlignment(HorizontalAlignment.Center)
                    .ToTable();
            AddTablePartToCell(table.AddRow().AddCell());
            table.AddRow()
                    .AddCell("Complex table is completed.")
            .ToDocument().Build("Result.pdf");
        }
 
        private static void AddTablePartToCell(TableCellBuilder cell)
        {
            cell.AddTable()
            .SetWidth(XUnit.FromPercent(100))
            .AddColumnPercentToTable("", 50)
            .AddColumnPercentToTable("", 25)
            .AddColumnPercentToTable("", 25)
            .AddRow()
                .AddCell()
                    .SetRowSpan(4)
                    .AddImageToCell("smile-emoji.png").ToRow()
                .AddCellToRow("New York")
                .AddCellToRow("New York").ToTable()
            .AddRow()
                .AddCellToRow()
                .AddCellToRow("Los Angeles")
                .AddCellToRow("California").ToTable()
            .AddRow()
                .AddCellToRow()
                .AddCellToRow("Chicago")
                .AddCellToRow("Illinois").ToTable()
            .AddRow()
                .AddCellToRow()
                .AddCell("\n").SetColSpan(2)
                          .SetPadding(0, 32);
        }
 
 The above code will generate the following:
 
 
 See the document

Example 4. Create a complex table with nested tables Hide

        public static void BuildDocument()
        {
            var table = DocumentBuilder.New()
                .AddSection()
                    .AddTable()
                        .AddColumnToTable().AddColumnToTable()
                        .AddRow()
                        .AddCell("Person")
                        .SetHorizontalAlignment(HorizontalAlignment.Center)
                        .ToRow()
                        .AddCell("Department")
                        .SetHorizontalAlignment(HorizontalAlignment.Center)
                        .ToTable();
            var row2 = table.AddRow();
            AddPersonInfoPartToCell(row2.AddCell());
            AddDepartmentInfoPartToCell(row2.AddCell());
            table.AddRow()
                    .AddCellToRow("E-mail")
                    .AddCellToRow("Tel.number")
            .ToDocument().Build("Result.pdf");
        }
 
        private static void AddPersonInfoPartToCell(TableCellBuilder cell)
        {
            cell.AddTable()
                    .AddColumnToTable().AddColumnToTable()
                    .AddRow()
                        .AddCellToRow("Name")
                        .AddCell("photo", 1, 4)
                        .SetHorizontalAlignment(HorizontalAlignment.Center)
                        .ToTable()
                    .AddRow()
                        .AddCellToRow("Surname")
                        .AddCell().ToTable()
                    .AddRow()
                        .AddCellToRow("State")
                        .AddCell().ToTable()
                    .AddRow()
                        .AddCellToRow("City")
                        .AddCell().ToTable();
        }
        private static void AddDepartmentInfoPartToCell(TableCellBuilder cell)
        {
            cell.AddTable()
                    .AddColumnToTable().AddColumnToTable()
                    .AddRow()
                        .AddCellToRow("Name")
                        .AddCell("image", 1, 2)
                        .SetHorizontalAlignment(HorizontalAlignment.Center)
                        .ToTable()
                    .AddRow()
                        .AddCellToRow("Structure")
                        .AddCell().ToTable()
                    .AddRow()
                        .AddCellToRow("Floor")
                        .AddCell("qrcode", 1, 2)
                        .SetHorizontalAlignment(HorizontalAlignment.Center)
                        .ToTable()
                    .AddRow()
                        .AddCellToRow("Room")
                        .AddCell().ToTable();
        }
 
 The above code will generate the following:
 
 
 See the document

back