Nested tables

31st May 2016
admin-marketing
NestedTableProblem.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/*
    This file is part of the iText (R) project.
    Copyright (c) 1998-2019 iText Group NV
    Authors: iText Software.
 
    For more information, please contact iText Software at this address:
    sales@itextpdf.com
 */
/**
 * Example written by Bruno Lowagie in answer to:
 * http://stackoverflow.com/questions/28418108/itext-how-to-add-an-inner-table-surrounded-by-text-to-a-table
 */
package com.itextpdf.samples.sandbox.tables;
 
import com.itextpdf.kernel.colors.ColorConstants;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.borders.SolidBorder;
import com.itextpdf.layout.element.Cell;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.property.HorizontalAlignment;
import com.itextpdf.layout.property.UnitValue;
 
import java.io.File;
 
public class NestedTableProblem {
    public static final String DEST = "./target/sandbox/tables/nested_table_problem.pdf";
 
    public static void main(String[] args) throws Exception {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new NestedTableProblem().manipulatePdf(DEST);
    }
 
    protected void manipulatePdf(String dest) throws Exception {
        PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
        Document doc = new Document(pdfDoc, new PageSize(612, 792));
        doc.setMargins(30, 21, 35, 21);
 
        // table 2
        Table table2 = new Table(UnitValue.createPercentArray(1)).useAllAvailableWidth();
        table2.setHorizontalAlignment(HorizontalAlignment.LEFT);
        table2.addCell(new Cell().setBorder(new SolidBorder(ColorConstants.RED, 1)).add(new Paragraph("Goodbye World")));
        table2.setWidth(UnitValue.createPercentValue(80));
        // table 1
        Table table1 = new Table(UnitValue.createPercentArray(1)).useAllAvailableWidth();
        table1.setHorizontalAlignment(HorizontalAlignment.LEFT);
        Cell cell = new Cell();
        cell.setBorder(new SolidBorder(ColorConstants.BLACK, 1));
        cell.add(new Paragraph("Hello World"));
        cell.add(table2);
        cell.add(new Paragraph("Hello World"));
        table1.addCell(cell);
        doc.add(table1);
 
        doc.close();
    }
}
NestedTableRoundedBorder.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
/*
    This file is part of the iText (R) project.
    Copyright (c) 1998-2019 iText Group NV
    Authors: iText Software.
 
    For more information, please contact iText Software at this address:
    sales@itextpdf.com
 */
/**
 * This example was written in answer to the following question:
 * http://stackoverflow.com/questions/31330062/need-to-make-pdf-sample-with-boxes-as-table-columns-by-android-app
 */
package com.itextpdf.samples.sandbox.tables;
 
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.borders.Border;
import com.itextpdf.layout.element.Cell;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.property.UnitValue;
import com.itextpdf.layout.renderer.CellRenderer;
import com.itextpdf.layout.renderer.DrawContext;
 
import java.io.File;
 
public class NestedTableRoundedBorder {
    public static final String DEST = "./target/sandbox/tables/nested_table_rounded_border.pdf";
 
    public static void main(String[] args) throws Exception {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new NestedTableRoundedBorder().manipulatePdf(DEST);
    }
 
    protected void manipulatePdf(String dest) throws Exception {
        PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
        Document doc = new Document(pdfDoc);
 
        Cell cell;
        // outer table
        Table outertable = new Table(UnitValue.createPercentArray(1)).useAllAvailableWidth();
        // inner table 1
        Table innertable = new Table(UnitValue.createPercentArray(new float[]{8, 12, 1, 4, 12})).useAllAvailableWidth();
        // first row
        // column 1
        cell = new Cell().add(new Paragraph("Record Ref:"));
        cell.setBorder(Border.NO_BORDER);
        innertable.addCell(cell);
        // column 2
        cell = new Cell().add(new Paragraph("GN Staff"));
        cell.setPaddingLeft(2);
        innertable.addCell(cell);
        // column 3
        cell = new Cell();
        cell.setBorder(Border.NO_BORDER);
        innertable.addCell(cell);
        // column 4
        cell = new Cell().add(new Paragraph("Date: "));
        cell.setBorder(Border.NO_BORDER);
        innertable.addCell(cell);
        // column 5
        cell = new Cell().add(new Paragraph("30/4/2015"));
        cell.setPaddingLeft(2);
        innertable.addCell(cell);
        // spacing
        cell = new Cell(1, 5);
        cell.setHeight(3);
        cell.setBorder(Border.NO_BORDER);
        innertable.addCell(cell);
        // second row
        // column 1
        cell = new Cell().add(new Paragraph("Hospital:"));
        cell.setBorder(Border.NO_BORDER);
        innertable.addCell(cell);
        // column 2
        cell = new Cell().add(new Paragraph("Derby Royal"));
        cell.setPaddingLeft(2);
        innertable.addCell(cell);
        // column 3
        cell = new Cell();
        cell.setBorder(Border.NO_BORDER);
        innertable.addCell(cell);
        // column 4
        cell = new Cell().add(new Paragraph("Ward: "));
        cell.setBorder(Border.NO_BORDER);
        cell.setPaddingLeft(5);
        innertable.addCell(cell);
        // column 5
        cell = new Cell().add(new Paragraph("21"));
        cell.setPaddingLeft(2);
        innertable.addCell(cell);
        // spacing
        cell = new Cell(1, 5);
        cell.setHeight(3);
        cell.setBorder(Border.NO_BORDER);
        innertable.addCell(cell);
        // first nested table
        cell = new Cell().add(innertable);
        cell.setNextRenderer(new RoundedBorderCellRenderer(cell));
        cell.setBorder(Border.NO_BORDER);
        cell.setPadding(8);
        outertable.addCell(cell);
        // inner table 2
        innertable = new Table(UnitValue.createPercentArray(new float[]{3, 17, 1, 16}));
        innertable.setWidth(UnitValue.createPercentValue(100));
        // first row
        // column 1
        cell = new Cell();
        cell.setBorder(Border.NO_BORDER);
        innertable.addCell(cell);
        // column 2
        cell = new Cell().add(new Paragraph("Name"));
        cell.setBorder(Border.NO_BORDER);
        innertable.addCell(cell);
        // column 3
        cell = new Cell();
        cell.setBorder(Border.NO_BORDER);
        innertable.addCell(cell);
        // column 4
        cell = new Cell().add(new Paragraph("Signature: "));
        cell.setBorder(Border.NO_BORDER);
        innertable.addCell(cell);
        // spacing
        cell = new Cell(1, 4);
        cell.setHeight(3);
        cell.setBorder(Border.NO_BORDER);
        innertable.addCell(cell);
        // subsequent rows
        for (int i = 1; i < 4; i++) {
            // column 1
            cell = new Cell().add(new Paragraph(String.format("%s:", i)));
            cell.setBorder(Border.NO_BORDER);
            innertable.addCell(cell);
            // column 2
            cell = new Cell();
            innertable.addCell(cell);
            // column 3
            cell = new Cell();
            cell.setBorder(Border.NO_BORDER);
            innertable.addCell(cell);
            // column 4
            cell = new Cell();
            innertable.addCell(cell);
            // spacing
            cell = new Cell(1, 4);
            cell.setHeight(3);
            cell.setBorder(Border.NO_BORDER);
            innertable.addCell(cell);
        }
        // second nested table
        cell = new Cell().add(innertable);
        cell.setNextRenderer(new RoundedBorderCellRenderer(cell));
        cell.setBorder(Border.NO_BORDER);
        cell.setPaddingLeft(8);
        cell.setPaddingTop(8);
        cell.setPaddingRight(8);
        cell.setPaddingBottom(8);
        outertable.addCell(cell);
        // add the table
        doc.add(outertable);
 
        doc.close();
    }
 
 
    private class RoundedBorderCellRenderer extends CellRenderer {
        public RoundedBorderCellRenderer(Cell modelElement) {
            super(modelElement);
        }
 
        @Override
        public void draw(DrawContext drawContext) {
            drawContext.getCanvas().roundRectangle(getOccupiedAreaBBox().getX() + 1.5f, getOccupiedAreaBBox().getY() + 1.5f,
                    getOccupiedAreaBBox().getWidth() - 3, getOccupiedAreaBBox().getHeight() - 3, 4);
            drawContext.getCanvas().stroke();
            super.draw(drawContext);
        }
    }
}
NestedTables.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
/*
    This file is part of the iText (R) project.
    Copyright (c) 1998-2019 iText Group NV
    Authors: iText Software.
 
    For more information, please contact iText Software at this address:
    sales@itextpdf.com
 */
/**
 * This example was written by Bruno Lowagie in answer to the following questions:
 * http://stackoverflow.com/questions/24562448/the-table-width-must-be-greater-than-zero-exception-when-using-nested-tables
 * and
 * http://stackoverflow.com/questions/28444598/nested-table-stretches
 */
package com.itextpdf.samples.sandbox.tables;
 
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Cell;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.property.UnitValue;
 
import java.io.File;
 
public class NestedTables {
    public static final String DEST = "./target/sandbox/tables/nested_tables.pdf";
 
    public static void main(String[] args) throws Exception {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new NestedTables().manipulatePdf(DEST);
    }
 
    protected void manipulatePdf(String dest) throws Exception {
        PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
        // Note that it is not necessary to create new PageSize object,
        // but for testing reasons (connected to parallelization) we call constructor here
        Document doc = new Document(pdfDoc, new PageSize(PageSize.A4).rotate());
 
        float[] columnWidths = {150, 40, 90, 51, 35, 25, 35, 35, 35, 32, 32, 33, 35, 60, 46, 26};
        Table table = new Table(columnWidths);
        table.setWidth(770F);
        buildNestedTables(table);
        doc.add(new Paragraph("Add table straight to another table"));
        doc.add(table);
 
        // IMPORTANT!!!
        // Two other examples (with methods buildNestedTables1 and buildNestedTables2)
        // make no sense in itext7 because there is only one way of adding cells to tables
        // in itext7. Please, check NestedTables.java in itext5.
 
        doc.close();
    }
 
    private void buildNestedTables(Table outerTable) {
        Table innerTable1 = new Table(UnitValue.createPercentArray(1)).useAllAvailableWidth();
        Table innerTable2 = new Table(UnitValue.createPercentArray(2)).useAllAvailableWidth();
        Cell cell;
        innerTable1.addCell("Cell 1");
        innerTable1.addCell("Cell 2");
        outerTable.addCell(innerTable1);
        innerTable2.addCell("Cell 3");
        innerTable2.addCell("Cell 4");
        outerTable.addCell(innerTable2);
        cell = new Cell(1, 14);
        outerTable.addCell(cell);
    }
}
NestedTables2.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/*
    This file is part of the iText (R) project.
    Copyright (c) 1998-2019 iText Group NV
    Authors: iText Software.
 
    For more information, please contact iText Software at this address:
    sales@itextpdf.com
 */
/**
 * This example was written by Bruno Lowagie in answer to the following questions:
 * http://stackoverflow.com/questions/28503491/large-table-in-table-cell-invoke-page-break
 */
package com.itextpdf.samples.sandbox.tables;
 
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.property.UnitValue;
 
import java.io.File;
 
public class NestedTables2 {
    public static final String DEST = "./target/sandbox/tables/nested_tables2.pdf";
 
    public static void main(String[] args) throws Exception {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new NestedTables2().manipulatePdf(DEST);
    }
 
    protected void manipulatePdf(String dest) throws Exception {
        PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
        Document doc = new Document(pdfDoc);
 
        Table table = new Table(UnitValue.createPercentArray(new float[]{1, 15}));
        for (int i = 1; i <= 20; i++) {
            table.addCell(String.valueOf(i));
            table.addCell("It is not smart to use iText 2.1.7!");
        }
        Table innertable = new Table(UnitValue.createPercentArray(new float[]{1, 15}));
        for (int i = 0; i < 90; i++) {
            innertable.addCell(String.valueOf(i + 1));
            innertable.addCell("Upgrade if you're a professional developer!");
        }
        table.addCell("21");
        table.addCell(innertable);
        for (int i = 22; i <= 40; i++) {
            table.addCell(String.valueOf(i));
            table.addCell("It is not smart to use iText 2.1.7!");
        }
        doc.add(table);
 
        doc.close();
    }
}
NestedTables3.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*
    This file is part of the iText (R) project.
    Copyright (c) 1998-2019 iText Group NV
    Authors: iText Software.
 
    For more information, please contact iText Software at this address:
    sales@itextpdf.com
 */
/**
 * This example was written by Bruno Lowagie in answer to the following questions:
 * http://stackoverflow.com/questions/31108488/pdfptable-header-repeat-when-data-in-a-different-table-increases-in-itext
 */
package com.itextpdf.samples.sandbox.tables;
 
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Cell;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.property.Property;
import com.itextpdf.layout.property.UnitValue;
import com.itextpdf.layout.renderer.AbstractRenderer;
import com.itextpdf.layout.renderer.DrawContext;
import com.itextpdf.layout.renderer.IRenderer;
import com.itextpdf.layout.renderer.TableRenderer;
 
import java.io.File;
 
public class NestedTables3 {
    public static final String DEST = "./target/sandbox/tables/nested_tables3.pdf";
 
    public static void main(String[] args) throws Exception {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new NestedTables3().manipulatePdf(DEST);
    }
 
    protected void manipulatePdf(String dest) throws Exception {
        PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
        // Note that it is not necessary to create new PageSize object,
        // but for testing reasons (connected to parallelization) we call constructor here
        Document doc = new Document(pdfDoc, new PageSize(PageSize.A4).rotate());
 
        Table table = new Table(UnitValue.createPercentArray(2)).useAllAvailableWidth();
        table.setNextRenderer(new InnerTableRenderer(table, new Table.RowRange(0, 0)));
        Cell cell = new Cell(1, 2).add(new Paragraph("This outer header is repeated on every page"));
        table.addHeaderCell(cell);
        Table inner1 = new Table(UnitValue.createPercentArray(1)).useAllAvailableWidth();
        cell = new Cell();
        cell.setHeight(20);
        inner1.addHeaderCell(cell);
        cell = new Cell().add(new Paragraph("This inner header won't be repeated on every page"));
        inner1.addHeaderCell(cell);
        for (int i = 0; i < 10; i++) {
            inner1.addCell(new Cell().add(new Paragraph("test")));
        }
        cell = new Cell().add(inner1);
        table.addCell(cell.setPadding(0));
        Table inner2 = new Table(UnitValue.createPercentArray(1)).useAllAvailableWidth();
        cell = new Cell();
        cell.setHeight(20);
        inner2.addHeaderCell(cell);
        cell = new Cell().add(new Paragraph("This inner may be repeated on every page"));
        inner2.addHeaderCell(cell);
        for (int i = 0; i < 35; i++) {
            inner2.addCell("test");
        }
        cell = new Cell().add(inner2);
        table.addCell(cell.setPadding(0));
        doc.add(table);
 
        doc.close();
    }
 
    private class InnerTableRenderer extends TableRenderer {
        public InnerTableRenderer(Table modelElement, Table.RowRange rowRange) {
            super(modelElement, rowRange);
        }
 
        protected InnerTableRenderer(Table modelElement) {
            super(modelElement);
        }
 
        @Override
        protected TableRenderer[] split(int row) {
            InnerTableRenderer splitRenderer = (InnerTableRenderer) createSplitRenderer(
                    new Table.RowRange(rowRange.getStartRow(), rowRange.getStartRow() + row));
            splitRenderer.rows = rows.subList(0, row);
            InnerTableRenderer overflowRenderer = (InnerTableRenderer) createOverflowRenderer(
                    new Table.RowRange(rowRange.getStartRow() + row, rowRange.getFinishRow()));
            overflowRenderer.rows = rows.subList(row, rows.size());
            splitRenderer.occupiedArea = occupiedArea;
 
            return new TableRenderer[]{splitRenderer, overflowRenderer};
        }
 
        @Override
        public void drawChildren(DrawContext drawContext) {
            super.drawChildren(drawContext);
            for (IRenderer renderer : childRenderers) {
                PdfCanvas canvas = drawContext.getCanvas();
                canvas.beginText();
                Rectangle box = ((AbstractRenderer) renderer).getInnerAreaBBox();
                UnitValue fontSize = this.getPropertyAsUnitValue(Property.FONT_SIZE);
                canvas.moveText(box.getLeft(), box.getTop() - (fontSize.isPointValue() ? fontSize.getValue() : 12f));
                canvas.setFontAndSize(this.getPropertyAsFont(Property.FONT),
                        fontSize.isPointValue() ? fontSize.getValue() : 12f);
                canvas.showText("This inner table header will always be repeated");
                canvas.endText();
                canvas.stroke();
            }
        }
 
        @Override
        public IRenderer getNextRenderer() {
            return new InnerTableRenderer((Table) modelElement);
        }
    }
}
NestedTablesAligned.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/*
    This file is part of the iText (R) project.
    Copyright (c) 1998-2019 iText Group NV
    Authors: iText Software.
 
    For more information, please contact iText Software at this address:
    sales@itextpdf.com
 */
/**
 * This example was written by Bruno Lowagie in answer to the following question:
 * http://stackoverflow.com/questions/26625455/unable-to-left-align-nested-tables-inside-a-cell
 */
package com.itextpdf.samples.sandbox.tables;
 
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.property.HorizontalAlignment;
import com.itextpdf.layout.property.UnitValue;
 
import java.io.File;
 
public class NestedTablesAligned {
    public static final String DEST = "./target/sandbox/tables/nested_tables_aligned.pdf";
 
    public static void main(String[] args) throws Exception {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new NestedTablesAligned().manipulatePdf(DEST);
    }
 
    protected void manipulatePdf(String dest) throws Exception {
        PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
        // Note that it is not necessary to create new PageSize object,
        // but for testing reasons (connected to parallelization) we call constructor here
        Document doc = new Document(pdfDoc, new PageSize(PageSize.A4).rotate());
 
        float[] columnWidths = {200f, 200f, 200f};
        Table table = new Table(columnWidths);
        buildNestedTables(table);
        doc.add(table);
 
        doc.close();
    }
 
    private void buildNestedTables(Table outerTable) {
        Table innerTable1 = new Table(UnitValue.createPercentArray(1)).useAllAvailableWidth();
        innerTable1.setWidth(100f);
        innerTable1.setHorizontalAlignment(HorizontalAlignment.LEFT);
        innerTable1.addCell("Cell 1");
        innerTable1.addCell("Cell 2");
        outerTable.addCell(innerTable1);
        Table innerTable2 = new Table(UnitValue.createPercentArray(2)).useAllAvailableWidth();
        innerTable2.setWidth(100f);
        innerTable2.setHorizontalAlignment(HorizontalAlignment.CENTER);
        innerTable2.addCell("Cell 3");
        innerTable2.addCell("Cell 4");
        outerTable.addCell(innerTable2);
        Table innerTable3 = new Table(UnitValue.createPercentArray(2)).useAllAvailableWidth();
        innerTable3.setWidth(100f);
        innerTable3.setHorizontalAlignment(HorizontalAlignment.RIGHT);
        innerTable3.addCell("Cell 5");
        innerTable3.addCell("Cell 6");
        outerTable.addCell(innerTable3);
    }
}
NestedTableProblem.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/*
This file is part of the iText (R) project.
Copyright (c) 1998-2019 iText Group NV
Authors: iText Software.
 
For more information, please contact iText Software at this address:
sales@itextpdf.com
*/
 
using System;
using System.IO;
using iText.Kernel.Colors;
using iText.Kernel.Geom;
using iText.Kernel.Pdf;
using iText.Layout;
using iText.Layout.Borders;
using iText.Layout.Element;
using iText.Layout.Properties;
 
namespace iText.Samples.Sandbox.Tables
{
    public class NestedTableProblem
    {
        public static readonly string DEST = "../../results/sandbox/tables/nested_table_problem.pdf";
 
        public static void Main(String[] args)
        {
            FileInfo file = new FileInfo(DEST);
            file.Directory.Create();
 
            new NestedTableProblem().ManipulatePdf(DEST);
        }
 
        private void ManipulatePdf(string dest)
        {
            PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
            Document doc = new Document(pdfDoc, new PageSize(612, 792));
 
            doc.SetMargins(30, 21, 35, 21);
 
            // inner table
            Table innerTable = new Table(UnitValue.CreatePercentArray(1)).UseAllAvailableWidth();
            innerTable.SetHorizontalAlignment(HorizontalAlignment.LEFT);
            innerTable.AddCell(new Cell().SetBorder(new SolidBorder(ColorConstants.RED, 1))
                .Add(new Paragraph("Goodbye World")));
            innerTable.SetWidth(UnitValue.CreatePercentValue(80));
 
            // outer table
            Table outerTable = new Table(UnitValue.CreatePercentArray(1)).UseAllAvailableWidth();
            outerTable.SetHorizontalAlignment(HorizontalAlignment.LEFT);
 
            Cell cell = new Cell();
            cell.SetBorder(new SolidBorder(ColorConstants.BLACK, 1));
            cell.Add(new Paragraph("Hello World"));
            cell.Add(innerTable);
            cell.Add(new Paragraph("Hello World"));
 
            outerTable.AddCell(cell);
            doc.Add(outerTable);
 
            doc.Close();
        }
    }
}
NestedTableRoundedBorder.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
/*
This file is part of the iText (R) project.
Copyright (c) 1998-2019 iText Group NV
Authors: iText Software.
 
For more information, please contact iText Software at this address:
sales@itextpdf.com
*/
 
using System;
using System.IO;
using iText.Kernel.Pdf;
using iText.Layout;
using iText.Layout.Borders;
using iText.Layout.Element;
using iText.Layout.Properties;
using iText.Layout.Renderer;
 
namespace iText.Samples.Sandbox.Tables
{
    public class NestedTableRoundedBorder
    {
        public static readonly String DEST = "../../results/sandbox/tables/nested_table_rounded_border.pdf";
 
        public static void Main(String[] args)
        {
            FileInfo file = new FileInfo(DEST);
            file.Directory.Create();
 
            new NestedTableRoundedBorder().ManipulatePdf(DEST);
        }
 
        private void ManipulatePdf(string dest)
        {
            PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
            Document doc = new Document(pdfDoc);
 
            // outer table
            Table outerTable = new Table(UnitValue.CreatePercentArray(1)).UseAllAvailableWidth();
 
            // inner table 1
            Table innerTable = new Table(UnitValue.CreatePercentArray(new float[] {8, 12, 1, 4, 12}))
                .UseAllAvailableWidth();
 
            // first row
            // column 1
            Cell cell = new Cell().Add(new Paragraph("Record Ref:"));
            cell.SetBorder(Border.NO_BORDER);
            innerTable.AddCell(cell);
 
            // column 2
            cell = new Cell().Add(new Paragraph("GN Staff"));
            cell.SetPaddingLeft(2);
            innerTable.AddCell(cell);
 
            // spacing
            cell = new Cell();
            cell.SetBorder(Border.NO_BORDER);
            innerTable.AddCell(cell);
 
            // column 4
            cell = new Cell().Add(new Paragraph("Date: "));
            cell.SetBorder(Border.NO_BORDER);
            innerTable.AddCell(cell);
 
            // column 5
            cell = new Cell().Add(new Paragraph("30/4/2015"));
            cell.SetPaddingLeft(2);
            innerTable.AddCell(cell);
 
            // spacing
            cell = new Cell(1, 5);
            cell.SetHeight(3);
            cell.SetBorder(Border.NO_BORDER);
            innerTable.AddCell(cell);
 
            // second row
            // column 1
            cell = new Cell().Add(new Paragraph("Hospital:"));
            cell.SetBorder(Border.NO_BORDER);
            innerTable.AddCell(cell);
 
            // column 2
            cell = new Cell().Add(new Paragraph("Derby Royal"));
            cell.SetPaddingLeft(2);
            innerTable.AddCell(cell);
 
            // spacing
            cell = new Cell();
            cell.SetBorder(Border.NO_BORDER);
            innerTable.AddCell(cell);
 
            // column 4
            cell = new Cell().Add(new Paragraph("Ward: "));
            cell.SetBorder(Border.NO_BORDER);
            cell.SetPaddingLeft(5);
            innerTable.AddCell(cell);
 
            // column 5
            cell = new Cell().Add(new Paragraph("21"));
            cell.SetPaddingLeft(2);
            innerTable.AddCell(cell);
 
            // spacing
            cell = new Cell(1, 5);
            cell.SetHeight(3);
            cell.SetBorder(Border.NO_BORDER);
            innerTable.AddCell(cell);
 
            // first nested table
            cell = new Cell().Add(innerTable);
            cell.SetNextRenderer(new RoundedBorderCellRenderer(cell));
            cell.SetBorder(Border.NO_BORDER);
            cell.SetPadding(8);
            outerTable.AddCell(cell);
 
            // inner table 2
            innerTable = new Table(UnitValue.CreatePercentArray(new float[] {3, 17, 1, 16}));
            innerTable.SetWidth(UnitValue.CreatePercentValue(100));
 
            // first row
            // column 1
            cell = new Cell();
            cell.SetBorder(Border.NO_BORDER);
            innerTable.AddCell(cell);
 
            // column 2
            cell = new Cell().Add(new Paragraph("Name"));
            cell.SetBorder(Border.NO_BORDER);
            innerTable.AddCell(cell);
 
            // column 3
            cell = new Cell();
            cell.SetBorder(Border.NO_BORDER);
            innerTable.AddCell(cell);
 
            // column 4
            cell = new Cell().Add(new Paragraph("Signature: "));
            cell.SetBorder(Border.NO_BORDER);
            innerTable.AddCell(cell);
 
            // spacing
            cell = new Cell(1, 4);
            cell.SetHeight(3);
            cell.SetBorder(Border.NO_BORDER);
            innerTable.AddCell(cell);
 
            // subsequent rows
            for (int i = 1; i < 4; i++)
            {
                // column 1
                cell = new Cell().Add(new Paragraph(string.Format("{0}:", i)));
                cell.SetBorder(Border.NO_BORDER);
                innerTable.AddCell(cell);
 
                // column 2
                cell = new Cell();
                innerTable.AddCell(cell);
 
                // column 3
                cell = new Cell();
                cell.SetBorder(Border.NO_BORDER);
                innerTable.AddCell(cell);
 
                // column 4
                cell = new Cell();
                innerTable.AddCell(cell);
 
                // spacing
                cell = new Cell(1, 4);
                cell.SetHeight(3);
                cell.SetBorder(Border.NO_BORDER);
                innerTable.AddCell(cell);
            }
 
            // second nested table
            cell = new Cell().Add(innerTable);
            cell.SetNextRenderer(new RoundedBorderCellRenderer(cell));
            cell.SetBorder(Border.NO_BORDER);
            cell.SetPaddingLeft(8);
            cell.SetPaddingTop(8);
            cell.SetPaddingRight(8);
            cell.SetPaddingBottom(8);
            outerTable.AddCell(cell);
 
            // add the table
            doc.Add(outerTable);
 
            doc.Close();
        }
 
        private class RoundedBorderCellRenderer : CellRenderer
        {
            public RoundedBorderCellRenderer(Cell modelElement)
                : base(modelElement)
            {
            }            
            
            // If renderer overflows on the next area, iText uses getNextRender() method to create a renderer for the overflow part.
            // If getNextRenderer isn't overriden, the default method will be used and thus a default rather than custom
            // renderer will be created
            public override IRenderer GetNextRenderer()
            {
                return new RoundedBorderCellRenderer((Cell) modelElement);
            }
 
            public override void Draw(DrawContext drawContext)
            {
                drawContext.GetCanvas().RoundRectangle(GetOccupiedAreaBBox().GetX() + 1.5f,
                    GetOccupiedAreaBBox().GetY() + 1.5f, GetOccupiedAreaBBox().GetWidth() - 3,
                    GetOccupiedAreaBBox().GetHeight() - 3, 4);
                drawContext.GetCanvas().Stroke();
                base.Draw(drawContext);
            }
        }
    }
}
NestedTables.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/*
This file is part of the iText (R) project.
Copyright (c) 1998-2019 iText Group NV
Authors: iText Software.
 
For more information, please contact iText Software at this address:
sales@itextpdf.com
*/
 
using System;
using System.IO;
using iText.Kernel.Geom;
using iText.Kernel.Pdf;
using iText.Layout;
using iText.Layout.Element;
using iText.Layout.Properties;
 
namespace iText.Samples.Sandbox.Tables
{
    public class NestedTables
    {
        public static readonly string DEST = "../../results/sandbox/tables/nested_tables.pdf";
 
        public static void Main(String[] args)
        {
            FileInfo file = new FileInfo(DEST);
            file.Directory.Create();
 
            new NestedTables().ManipulatePdf(DEST);
        }
 
        private void ManipulatePdf(string dest)
        {
            PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
            Document doc = new Document(pdfDoc, PageSize.A4.Rotate());
 
            float[] columnWidths = {150, 40, 90, 51, 35, 25, 35, 35, 35, 32, 32, 33, 35, 60, 46, 26};
            Table table = new Table(columnWidths);
            table.SetWidth(770F);
 
            BuildNestedTables(table);
 
            doc.Add(new Paragraph("Add table straight to another table"));
            doc.Add(table);
 
            doc.Close();
        }
 
        private void BuildNestedTables(Table outerTable)
        {
            Table innerTable1 = new Table(UnitValue.CreatePercentArray(1)).UseAllAvailableWidth();
            Table innerTable2 = new Table(UnitValue.CreatePercentArray(2)).UseAllAvailableWidth();
            
            innerTable1.AddCell("Cell 1");
            innerTable1.AddCell("Cell 2");
            outerTable.AddCell(innerTable1);
 
            innerTable2.AddCell("Cell 3");
            innerTable2.AddCell("Cell 4");
            outerTable.AddCell(innerTable2);
 
            Cell cell = new Cell(1, 14);
            outerTable.AddCell(cell);
        }
    }
}
NestedTables2.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/*
This file is part of the iText (R) project.
Copyright (c) 1998-2019 iText Group NV
Authors: iText Software.
 
For more information, please contact iText Software at this address:
sales@itextpdf.com
*/
 
using System;
using System.IO;
using iText.Kernel.Pdf;
using iText.Layout;
using iText.Layout.Element;
using iText.Layout.Properties;
 
namespace iText.Samples.Sandbox.Tables
{
    public class NestedTables2
    {
        public static readonly string DEST = "../../results/sandbox/tables/nested_tables2.pdf";
 
        public static void Main(String[] args)
        {
            FileInfo file = new FileInfo(DEST);
            file.Directory.Create();
 
            new NestedTables2().ManipulatePdf(DEST);
        }
 
        private void ManipulatePdf(string dest)
        {
            PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
            Document doc = new Document(pdfDoc);
 
            Table table = new Table(UnitValue.CreatePercentArray(new float[] {1, 15}));
 
            for (int i = 1; i <= 20; i++)
            {
                table.AddCell(i.ToString());
                table.AddCell("It is not smart to use iText 2.1.7!");
            }
 
            Table innertable = new Table(UnitValue.CreatePercentArray(new float[] {1, 15}));
 
            for (int i = 0; i < 90; i++)
            {
                innertable.AddCell((i + 1).ToString());
                innertable.AddCell("Upgrade if you're a professional developer!");
            }
 
            table.AddCell("21");
            table.AddCell(innertable);
 
            for (int i = 22; i <= 40; i++)
            {
                table.AddCell(i.ToString());
                table.AddCell("It is not smart to use iText 2.1.7!");
            }
 
            doc.Add(table);
 
            doc.Close();
        }
    }
}
NestedTables3.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/*
This file is part of the iText (R) project.
Copyright (c) 1998-2019 iText Group NV
Authors: iText Software.
 
For more information, please contact iText Software at this address:
sales@itextpdf.com
*/
 
using System;
using System.IO;
using System.Linq;
using iText.Kernel.Geom;
using iText.Kernel.Pdf;
using iText.Kernel.Pdf.Canvas;
using iText.Layout;
using iText.Layout.Element;
using iText.Layout.Properties;
using iText.Layout.Renderer;
 
namespace iText.Samples.Sandbox.Tables
{
    public class NestedTables3
    {
        public static readonly string DEST = "../../results/sandbox/tables/nested_tables3.pdf";
 
        public static void Main(String[] args)
        {
            FileInfo file = new FileInfo(DEST);
            file.Directory.Create();
 
            new NestedTables3().ManipulatePdf(DEST);
        }
 
        private void ManipulatePdf(string dest)
        {
            PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
            Document doc = new Document(pdfDoc, PageSize.A4.Rotate());
 
            // Creates outer table
            Table table = new Table(UnitValue.CreatePercentArray(2)).UseAllAvailableWidth();
            
            // Draws header for every nested table.
            // That header will be repeated on every page.
            table.SetNextRenderer(new InnerTableRenderer(table, new Table.RowRange(0, 0)));
 
            Cell cell = new Cell(1, 2).Add(new Paragraph("This outer header is repeated on every page"));
            table.AddHeaderCell(cell);
 
            // Creates the first inner table 
            Table inner1 = new Table(UnitValue.CreatePercentArray(1)).UseAllAvailableWidth();
 
            // Creates an empty header cell for the header content drawn by outer table renderer
            cell = new Cell();
            cell.SetHeight(20);
            inner1.AddHeaderCell(cell);
 
            // Creates header cell that will be repeated only on pages, where that table has content
            cell = new Cell().Add(new Paragraph("This inner header won't be repeated on every page"));
            inner1.AddHeaderCell(cell);
 
            for (int i = 0; i < 10; i++)
            {
                inner1.AddCell(new Cell().Add(new Paragraph("test")));
            }
 
            cell = new Cell().Add(inner1);
            table.AddCell(cell.SetPadding(0));
 
            // Creates the second inner table 
            Table inner2 = new Table(UnitValue.CreatePercentArray(1)).UseAllAvailableWidth();
 
            // Creates an empty header cell for the header content drawn by outer table renderer
            cell = new Cell();
            cell.SetHeight(20);
            inner2.AddHeaderCell(cell);
 
            // Creates header cell that will be repeated only on pages, where that table has content
            cell = new Cell().Add(new Paragraph("This inner header may be repeated on every page"));
            inner2.AddHeaderCell(cell);
 
            for (int i = 0; i < 35; i++)
            {
                inner2.AddCell("test");
            }
 
            cell = new Cell().Add(inner2);
            table.AddCell(cell.SetPadding(0));
 
            doc.Add(table);
 
            doc.Close();
        }
 
        private class InnerTableRenderer : TableRenderer
        {
            public InnerTableRenderer(Table modelElement, Table.RowRange rowRange)
                : base(modelElement, rowRange)
            {
            }
 
            protected InnerTableRenderer(Table modelElement)
                : base(modelElement)
            {
            }
            
            public override void DrawChildren(DrawContext drawContext)
            {
                base.DrawChildren(drawContext);
 
                foreach (IRenderer renderer in childRenderers)
                {
                    PdfCanvas canvas = drawContext.GetCanvas();
                    canvas.BeginText();
                    Rectangle box = ((AbstractRenderer) renderer).GetInnerAreaBBox();
                    UnitValue fontSize = GetPropertyAsUnitValue(Property.FONT_SIZE);
                    canvas.MoveText(box.GetLeft(),
                        box.GetTop() - (fontSize.IsPointValue() ? fontSize.GetValue() : 12f));
                    canvas.SetFontAndSize(GetPropertyAsFont(Property.FONT),
                        fontSize.IsPointValue() ? fontSize.GetValue() : 12f);
                    canvas.ShowText("This inner table header will always be repeated");
                    canvas.EndText();
                    canvas.Stroke();
                }
            }           
            
            // If renderer overflows on the next area, iText uses getNextRender() method to create a renderer for the overflow part.
            // If getNextRenderer isn't overriden, the default method will be used and thus a default rather than custom
            // renderer will be created
            public override IRenderer GetNextRenderer()
            {
                return new InnerTableRenderer((Table) modelElement);
            }
        }
    }
}
NestedTablesAligned.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
/*
This file is part of the iText (R) project.
Copyright (c) 1998-2019 iText Group NV
Authors: iText Software.
 
For more information, please contact iText Software at this address:
sales@itextpdf.com
*/
 
using System;
using System.IO;
using iText.Kernel.Geom;
using iText.Kernel.Pdf;
using iText.Layout;
using iText.Layout.Element;
using iText.Layout.Properties;
 
namespace iText.Samples.Sandbox.Tables
{
    public class NestedTablesAligned
    {
        public static readonly string DEST = "../../results/sandbox/tables/nested_tables_aligned.pdf";
 
        public static void Main(String[] args)
        {
            FileInfo file = new FileInfo(DEST);
            file.Directory.Create();
 
            new NestedTablesAligned().ManipulatePdf(DEST);
        }
 
        private void ManipulatePdf(String dest)
        {
            PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
            Document doc = new Document(pdfDoc, PageSize.A4.Rotate());
 
            float[] columnWidths = {200f, 200f, 200f};
 
            Table table = new Table(columnWidths);
            BuildNestedTables(table);
 
            doc.Add(table);
 
            doc.Close();
        }
 
        private void BuildNestedTables(Table outerTable)
        {
            Table innerTable1 = new Table(UnitValue.CreatePercentArray(1));
            innerTable1.SetWidth(100f);
            innerTable1.SetHorizontalAlignment(HorizontalAlignment.LEFT);
            innerTable1.AddCell("Cell 1");
            innerTable1.AddCell("Cell 2");
            outerTable.AddCell(innerTable1);
 
            Table innerTable2 = new Table(UnitValue.CreatePercentArray(2));
            innerTable2.SetWidth(100f);
            innerTable2.SetHorizontalAlignment(HorizontalAlignment.CENTER);
            innerTable2.AddCell("Cell 3");
            innerTable2.AddCell("Cell 4");
            outerTable.AddCell(innerTable2);
 
            Table innerTable3 = new Table(UnitValue.CreatePercentArray(2));
            innerTable3.SetWidth(100f);
            innerTable3.SetHorizontalAlignment(HorizontalAlignment.RIGHT);
            innerTable3.AddCell("Cell 5");
            innerTable3.AddCell("Cell 6");
            outerTable.AddCell(innerTable3);
        }
    }
}

Click the following link to see the legacy example for iText 5. Except for security fixes, iText 5 is no longer being developed.



Contact

Still have questions? 

We're happy to answer your questions. Reach out to us and we'll get back to you shortly.

Contact us
Stay updated

Join 11,000+ subscribers and become an iText PDF expert by staying up to date with our new products, updates, tips, technical solutions and happenings.

Subscribe Now