Table and cell events to draw borders

This is a code example of iText PDF, discover more.

31st May 2016
admin-marketing
CellTitle.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
/*
    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/35746651
 */
 
package com.itextpdf.samples.sandbox.tables;
 
import com.itextpdf.kernel.colors.ColorConstants;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.layout.Canvas;
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 com.itextpdf.layout.renderer.CellRenderer;
import com.itextpdf.layout.renderer.DrawContext;
import com.itextpdf.samples.GenericTest;
import com.itextpdf.test.annotations.type.SampleTest;
import org.junit.experimental.categories.Category;
 
import java.io.File;
 
@Category(SampleTest.class)
public class CellTitle extends GenericTest {
    public static final String DEST = "./target/test/resources/sandbox/tables/cell_title.pdf";
 
    public static void main(String[] args) throws Exception {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new CellTitle().manipulatePdf(DEST);
    }
 
    public Cell getCell(String content, String title) {
        Cell cell = new Cell().add(new Paragraph(content));
        cell.setNextRenderer(new CellTitleRenderer(cell, title));
        cell.setPaddingTop(8).setPaddingBottom(8);
        return cell;
    }
 
    @Override
    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(1)).useAllAvailableWidth();
        Cell cell = getCell("The title of this cell is title 1", "title 1");
        table.addCell(cell);
        cell = getCell("The title of this cell is title 2", "title 2");
        table.addCell(cell);
        cell = getCell("The title of this cell is title 3", "title 3");
        table.addCell(cell);
        doc.add(table);
        doc.close();
    }
 
 
    protected class CellTitleRenderer extends CellRenderer {
        protected String title;
 
        public CellTitleRenderer(Cell modelElement, String title) {
            super(modelElement);
            this.title = title;
        }
 
        @Override
        public void drawBorder(DrawContext drawContext) {
            // create above canvas in order to draw above borders (notice that we draw borders using TableRenderer)
            PdfCanvas aboveCanvas = new PdfCanvas(drawContext.getDocument().getLastPage().newContentStreamAfter(),
                    drawContext.getDocument().getLastPage().getResources(), drawContext.getDocument());
            new Canvas(aboveCanvas, drawContext.getDocument(), getOccupiedAreaBBox())
                    .add(new Paragraph(title).setMultipliedLeading(1).setMargin(0)
                            .setBackgroundColor(ColorConstants.LIGHT_GRAY)
                            .setFixedPosition(getOccupiedAreaBBox().getLeft() + 5, getOccupiedAreaBBox().getTop() - 8, 30));
        }
    }
}
CustomBorder.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
/*
    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 the following question:
 * http://stackoverflow.com/questions/23935566/table-borders-not-expanding-properly-in-pdf-using-itext
 */
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.samples.GenericTest;
import com.itextpdf.test.annotations.type.SampleTest;
import org.junit.Ignore;
import org.junit.experimental.categories.Category;
 
import java.io.File;
 
@Ignore("DEVSIX-1035")
@Category(SampleTest.class)
public class CustomBorder extends GenericTest {
    public static final String DEST = "./target/test/resources/sandbox/tables/custom_border.pdf";
    public static final String TEXT = "This is some long paragraph\n" +
            "that will be added over and over\n" +
            "again to prove a point.\n" +
            "It should result in rows\n" +
            "that are split\n" +
            " and rows that aren't.";
 
    public static void main(String[] args) throws Exception {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new CustomBorder().manipulatePdf(DEST);
    }
 
    @Override
    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(2)).useAllAvailableWidth();
        table.setWidth(500);
 
        for (int i = 1; i < 60; i++) {
            table.addCell(new Cell().add(new Paragraph("Cell " + i)).setBorderBottom(Border.NO_BORDER));
            table.addCell(new Cell().add(new Paragraph(TEXT)).setBorderBottom(Border.NO_BORDER));
        }
        // the last row
        table.addCell(new Cell().add(new Paragraph("Cell " + 60)));
        table.addCell(new Cell().add(new Paragraph(TEXT)));
 
        doc.add(table);
 
        doc.close();
    }
}
CustomBorder2.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
/*
    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 the following question:
 * http://stackoverflow.com/questions/23935566/table-borders-not-expanding-properly-in-pdf-using-itext
 */
package com.itextpdf.samples.sandbox.tables;
 
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.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.DrawContext;
import com.itextpdf.layout.renderer.IRenderer;
import com.itextpdf.layout.renderer.TableRenderer;
import com.itextpdf.samples.GenericTest;
import com.itextpdf.test.annotations.type.SampleTest;
import org.junit.Ignore;
import org.junit.experimental.categories.Category;
 
import java.io.File;
 
@Category(SampleTest.class)
@Ignore("DEVSIX-1035")
public class CustomBorder2 extends GenericTest {
    public static final String DEST = "./target/test/resources/sandbox/tables/custom_border2.pdf";
    public static final String TEXT = "This is some long paragraph that will be added over and over " +
            "again to prove a point. It should result in rows that are split and rows that aren't.";
 
    public static void main(String[] args) throws Exception {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new CustomBorder2().manipulatePdf(DEST);
    }
 
    @Override
    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(2)).useAllAvailableWidth();
        table.setWidth(500);
        table.setNextRenderer(new CustomBorder2TableRenderer(table, new Table.RowRange(0, 60)));
        for (int i = 1; i < 60; i++) {
            table.addCell(new Cell().add(new Paragraph("Cell " + i)).setBorder(Border.NO_BORDER));
            table.addCell(new Cell().add(new Paragraph(TEXT)).setBorder(Border.NO_BORDER));
        }
        doc.add(table);
 
        doc.close();
    }
 
    class CustomBorder2TableRenderer extends TableRenderer {
        boolean wasSplitted = false;
 
        public CustomBorder2TableRenderer(Table modelElement) {
            super(modelElement);
        }
 
        public CustomBorder2TableRenderer(Table modelElement, Table.RowRange rowRange) {
            super(modelElement, rowRange);
        }
 
        @Override
        public IRenderer getNextRenderer() {
            return new CustomBorder2TableRenderer((Table) modelElement);
        }
 
        @Override
        protected TableRenderer[] split(int row, boolean hasContent) {
            TableRenderer[] results = super.split(row, hasContent);
            CustomBorder2TableRenderer splitRenderer = (CustomBorder2TableRenderer) results[0];
            splitRenderer.wasSplitted = true;
            return results;
        }
 
        @Override
        protected void drawBorders(DrawContext drawContext) {
            Rectangle area = occupiedArea.getBBox();
            PdfCanvas canvas = drawContext.getCanvas();
 
            canvas
                    .saveState()
                    .moveTo(area.getLeft(), area.getBottom())
                    .lineTo(area.getLeft(), area.getTop())
                    .moveTo(area.getRight(), area.getTop())
                    .lineTo(area.getRight(), area.getBottom());
            if (wasSplitted) {
                if (1 == drawContext.getDocument().getNumberOfPages()) {
                    canvas
                            .moveTo(area.getLeft(), area.getTop())
                            .lineTo(area.getRight(), area.getTop());
                }
            } else {
                canvas
                        .moveTo(area.getLeft(), area.getBottom())
                        .lineTo(area.getRight(), area.getBottom());
            }
            canvas
                    .stroke()
                    .restoreState();
        }
    }
}
CustomBorder3.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
182
183
184
185
/*
    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 the following question:
 * http://stackoverflow.com/questions/34555756/one-cell-with-different-border-types
 */
package com.itextpdf.samples.sandbox.tables;
 
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.kernel.pdf.canvas.PdfCanvasConstants;
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 com.itextpdf.samples.GenericTest;
import com.itextpdf.test.annotations.type.SampleTest;
 
import java.io.File;
 
import org.junit.experimental.categories.Category;
 
@Category(SampleTest.class)
public class CustomBorder3 extends GenericTest {
    public static final String DEST = "./target/test/resources/sandbox/tables/custom_border3.pdf";
 
    public static void main(String[] args) throws Exception {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new CustomBorder3().manipulatePdf(DEST);
    }
 
    @Override
    protected void manipulatePdf(String dest) throws Exception {
        PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
        Document document = new Document(pdfDoc);
 
        ILineDash solid = new Solid();
        ILineDash dotted = new Dotted();
        ILineDash dashed = new Dashed();
 
        Table table;
        Cell cell;
 
        table = new Table(UnitValue.createPercentArray(4)).useAllAvailableWidth();
        table.setMarginBottom(30);
        cell = new Cell().add(new Paragraph("dotted left border"));
        cell.setBorder(Border.NO_BORDER);
        cell.setNextRenderer(new CustomBorder3Renderer(cell,
                new ILineDash[]{null, dotted, null, null}));
        table.addCell(cell);
        cell = new Cell().add(new Paragraph("solid right border"));
        cell.setBorder(Border.NO_BORDER);
        cell.setNextRenderer(new CustomBorder3Renderer(cell,
                new ILineDash[]{null, null, null, solid}));
        table.addCell(cell);
        cell = new Cell().add(new Paragraph("dashed top border"));
        cell.setBorder(Border.NO_BORDER);
        cell.setNextRenderer(new CustomBorder3Renderer(cell,
                new ILineDash[]{dashed, null, null, null}));
        table.addCell(cell);
        cell = new Cell().add(new Paragraph("bottom border"));
        cell.setBorder(Border.NO_BORDER);
        cell.setNextRenderer(new CustomBorder3Renderer(cell,
                new ILineDash[]{null, null, solid, null}));
        table.addCell(cell);
        document.add(table);
 
        table = new Table(UnitValue.createPercentArray(4)).useAllAvailableWidth();
        table.setMarginBottom(30);
        cell = new Cell().add(new Paragraph("dotted left and solid top border"));
        cell.setBorder(Border.NO_BORDER);
        cell.setNextRenderer(new CustomBorder3Renderer(cell,
                new ILineDash[]{solid, dotted, null, null}));
        table.addCell(cell);
        cell = new Cell().add(new Paragraph("dashed right and dashed bottom border"));
        cell.setBorder(Border.NO_BORDER);
        cell.setNextRenderer(new CustomBorder3Renderer(cell,
                new ILineDash[]{null, null, dashed, dashed}));
        table.addCell(cell);
        cell = new Cell().add(new Paragraph("no border"));
        cell.setBorder(Border.NO_BORDER);
        table.addCell(cell);
        cell = new Cell().add(new Paragraph("full solid border"));
        cell.setBorder(Border.NO_BORDER);
        cell.setNextRenderer(new CustomBorder3Renderer(cell,
                new ILineDash[]{solid, solid, solid, solid}));
        table.addCell(cell);
        document.add(table);
        document.close();
    }
 
 
    interface ILineDash {
        void applyLineDash(PdfCanvas canvas);
    }
 
 
    class Solid implements ILineDash {
        public void applyLineDash(PdfCanvas canvas) {
        }
    }
 
 
    class Dotted implements ILineDash {
        public void applyLineDash(PdfCanvas canvas) {
            canvas.setLineCapStyle(PdfCanvasConstants.LineCapStyle.ROUND);
            canvas.setLineDash(0, 4, 2);
        }
    }
 
 
    class Dashed implements ILineDash {
        public void applyLineDash(PdfCanvas canvas) {
            canvas.setLineDash(3, 3);
        }
    }
 
 
    class CustomBorder3Renderer extends CellRenderer {
        ILineDash[] borders;
 
        public CustomBorder3Renderer(Cell modelElement, ILineDash[] borders) {
            super(modelElement);
            this.borders = new ILineDash[borders.length];
            for (int i = 0; i < this.borders.length; i++) {
                this.borders[i] = borders[i];
            }
        }
 
        @Override
        public void draw(DrawContext drawContext) {
            super.draw(drawContext);
            PdfCanvas canvas = drawContext.getCanvas();
            Rectangle position = getOccupiedAreaBBox();
            canvas.saveState();
            if (null != borders[0]) {
                canvas.saveState();
                borders[0].applyLineDash(canvas);
                canvas.moveTo(position.getRight(), position.getTop());
                canvas.lineTo(position.getLeft(), position.getTop());
                canvas.stroke();
                canvas.restoreState();
            }
            if (null != borders[2]) {
                canvas.saveState();
                borders[2].applyLineDash(canvas);
                canvas.moveTo(position.getRight(), position.getBottom());
                canvas.lineTo(position.getLeft(), position.getBottom());
                canvas.stroke();
                canvas.restoreState();
            }
            if (null != borders[3]) {
                canvas.saveState();
                borders[3].applyLineDash(canvas);
                canvas.moveTo(position.getRight(), position.getTop());
                canvas.lineTo(position.getRight(), position.getBottom());
                canvas.stroke();
                canvas.restoreState();
            }
            if (null != borders[1]) {
                canvas.saveState();
                borders[1].applyLineDash(canvas);
                canvas.moveTo(position.getLeft(), position.getTop());
                canvas.lineTo(position.getLeft(), position.getBottom());
                canvas.stroke();
                canvas.restoreState();
            }
            canvas.stroke();
            canvas.restoreState();
        }
    }
}
DottedLineCell.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
 */
package com.itextpdf.samples.sandbox.tables;
 
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.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 com.itextpdf.layout.renderer.TableRenderer;
import com.itextpdf.samples.GenericTest;
import com.itextpdf.test.annotations.type.SampleTest;
 
import org.junit.experimental.categories.Category;
 
import java.io.File;
 
@Category(SampleTest.class)
public class DottedLineCell extends GenericTest {
    public static final String DEST = "./target/test/resources/sandbox/tables/dotted_line_cell.pdf";
 
    public static void main(String[] args) throws Exception {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new DottedLineCell().manipulatePdf(DEST);
    }
 
    @Override
    protected void manipulatePdf(String dest) throws Exception {
        PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
        Document doc = new Document(pdfDoc);
        doc.add(new Paragraph("Table event"));
        Table table = new Table(UnitValue.createPercentArray(3)).useAllAvailableWidth();
        table.setNextRenderer(new DottedLineTableRenderer(table, new Table.RowRange(0, 2)));
        table.addCell(new Cell().add(new Paragraph("A1")).setBorder(Border.NO_BORDER));
        table.addCell(new Cell().add(new Paragraph("A2")).setBorder(Border.NO_BORDER));
        table.addCell(new Cell().add(new Paragraph("A3")).setBorder(Border.NO_BORDER));
        table.addCell(new Cell().add(new Paragraph("B1")).setBorder(Border.NO_BORDER));
        table.addCell(new Cell().add(new Paragraph("B2")).setBorder(Border.NO_BORDER));
        table.addCell(new Cell().add(new Paragraph("B3")).setBorder(Border.NO_BORDER));
        table.addCell(new Cell().add(new Paragraph("C1")).setBorder(Border.NO_BORDER));
        table.addCell(new Cell().add(new Paragraph("C2")).setBorder(Border.NO_BORDER));
        table.addCell(new Cell().add(new Paragraph("C3")).setBorder(Border.NO_BORDER));
        doc.add(table);
        doc.add(new Paragraph("Cell event"));
        table = new Table(UnitValue.createPercentArray(1)).useAllAvailableWidth();
        Cell cell = new Cell().add(new Paragraph("Test"));
        cell.setNextRenderer(new DottedLineCellRenderer(cell));
        cell.setBorder(Border.NO_BORDER);
        table.addCell(cell.setBorder(Border.NO_BORDER));
        doc.add(table);
 
        doc.close();
    }
 
 
    private class DottedLineTableRenderer extends TableRenderer {
        public DottedLineTableRenderer(Table modelElement, Table.RowRange rowRange) {
            super(modelElement, rowRange);
        }
 
        @Override
        public void drawChildren(DrawContext drawContext) {
            super.drawChildren(drawContext);
            PdfCanvas canvas = drawContext.getCanvas();
            canvas.setLineDash(3f, 3f);
            // first horizontal line
            CellRenderer[] cellRenderers = rows.get(0);
            canvas.moveTo(cellRenderers[0].getOccupiedArea().getBBox().getLeft(),
                    cellRenderers[0].getOccupiedArea().getBBox().getTop());
            canvas.lineTo(cellRenderers[cellRenderers.length - 1].getOccupiedArea().getBBox().getRight(),
                    cellRenderers[cellRenderers.length - 1].getOccupiedArea().getBBox().getTop());
 
            for (int i = 0; i < rows.size(); i++) {
                cellRenderers = rows.get(i);
                // horizontal lines
                canvas.moveTo(cellRenderers[0].getOccupiedArea().getBBox().getX(),
                        cellRenderers[0].getOccupiedArea().getBBox().getY());
                canvas.lineTo(cellRenderers[cellRenderers.length - 1].getOccupiedArea().getBBox().getRight(),
                        cellRenderers[cellRenderers.length - 1].getOccupiedArea().getBBox().getBottom());
                // first vertical line
                Rectangle cellRect = cellRenderers[0].getOccupiedArea().getBBox();
                canvas.moveTo(cellRect.getLeft(), cellRect.getBottom());
                canvas.lineTo(cellRect.getLeft(), cellRect.getTop());
                // vertical lines
                for (int j = 0; j < cellRenderers.length; j++) {
                    cellRect = cellRenderers[j].getOccupiedArea().getBBox();
                    canvas.moveTo(cellRect.getRight(), cellRect.getBottom());
                    canvas.lineTo(cellRect.getRight(), cellRect.getTop());
                }
            }
            canvas.stroke();
        }
    }
 
 
    private class DottedLineCellRenderer extends CellRenderer {
        public DottedLineCellRenderer(Cell modelElement) {
            super(modelElement);
        }
 
        @Override
        public void draw(DrawContext drawContext) {
            super.draw(drawContext);
            drawContext.getCanvas().setLineDash(3f, 3f);
            drawContext.getCanvas().rectangle(this.getOccupiedArea().getBBox());
            drawContext.getCanvas().stroke();
        }
    }
}
DottedLineCell2.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
/*
    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 the following question:
 * http://stackoverflow.com/questions/34555756/one-cell-with-different-border-types
 */
package com.itextpdf.samples.sandbox.tables;
 
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.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 com.itextpdf.samples.GenericTest;
import com.itextpdf.test.annotations.type.SampleTest;
 
import java.io.File;
 
import org.junit.experimental.categories.Category;
 
@Category(SampleTest.class)
public class DottedLineCell2 extends GenericTest {
    public static final String DEST = "./target/test/resources/sandbox/tables/dotted_line_cell2.pdf";
 
    public static void main(String[] args) throws Exception {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new DottedLineCell2().manipulatePdf(DEST);
    }
 
    @Override
    protected void manipulatePdf(String dest) throws Exception {
        PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
        Document document = new Document(pdfDoc);
        Table table;
        Cell cell;
 
        table = new Table(UnitValue.createPercentArray(4)).useAllAvailableWidth();
        table.setMarginBottom(30);
        cell = new Cell().add(new Paragraph("left border"));
        cell.setBorder(Border.NO_BORDER);
        cell.setNextRenderer(new DottedLineCellRenderer(cell,
                new boolean[]{false, true, false, false}));
        table.addCell(cell);
        cell = new Cell().add(new Paragraph("right border"));
        cell.setBorder(Border.NO_BORDER);
        cell.setNextRenderer(new DottedLineCellRenderer(cell,
                new boolean[]{false, false, false, true}));
        table.addCell(cell);
        cell = new Cell().add(new Paragraph("top border"));
        cell.setBorder(Border.NO_BORDER);
        cell.setNextRenderer(new DottedLineCellRenderer(cell,
                new boolean[]{true, false, false, false}));
        table.addCell(cell);
        cell = new Cell().add(new Paragraph("bottom border"));
        cell.setBorder(Border.NO_BORDER);
        cell.setNextRenderer(new DottedLineCellRenderer(cell,
                new boolean[]{false, false, true, false}));
        table.addCell(cell);
        document.add(table);
 
        table = new Table(UnitValue.createPercentArray(4)).useAllAvailableWidth();
        table.setMarginBottom(30);
        cell = new Cell().add(new Paragraph("left and top border"));
        cell.setBorder(Border.NO_BORDER);
        cell.setNextRenderer(new DottedLineCellRenderer(cell,
                new boolean[]{true, true, false, false}));
        table.addCell(cell);
        cell = new Cell().add(new Paragraph("right and bottom border"));
        cell.setBorder(Border.NO_BORDER);
        cell.setNextRenderer(new DottedLineCellRenderer(cell,
                new boolean[]{false, false, true, true}));
        table.addCell(cell);
        cell = new Cell().add(new Paragraph("no border"));
        cell.setBorder(Border.NO_BORDER);
        table.addCell(cell);
        cell = new Cell().add(new Paragraph("full border"));
        cell.setBorder(Border.NO_BORDER);
        cell.setNextRenderer(new DottedLineCellRenderer(cell,
                new boolean[]{true, true, true, true}));
        table.addCell(cell);
        document.add(table);
        document.close();
    }
}
 
 
class DottedLineCellRenderer extends CellRenderer {
    boolean[] borders;
 
    public DottedLineCellRenderer(Cell modelElement, boolean[] borders) {
        super(modelElement);
        this.borders = new boolean[borders.length];
        for (int i = 0; i < this.borders.length; i++) {
            this.borders[i] = borders[i];
        }
    }
 
    @Override
    public void draw(DrawContext drawContext) {
        super.draw(drawContext);
        PdfCanvas canvas = drawContext.getCanvas();
        Rectangle position = getOccupiedAreaBBox();
        canvas.saveState();
        canvas.setLineDash(0, 4, 2);
        if (borders[0]) {
            canvas.moveTo(position.getRight(), position.getTop());
            canvas.lineTo(position.getLeft(), position.getTop());
        }
        if (borders[2]) {
            canvas.moveTo(position.getRight(), position.getBottom());
            canvas.lineTo(position.getLeft(), position.getBottom());
        }
        if (borders[3]) {
            canvas.moveTo(position.getRight(), position.getTop());
            canvas.lineTo(position.getRight(), position.getBottom());
        }
        if (borders[1]) {
            canvas.moveTo(position.getLeft(), position.getTop());
            canvas.lineTo(position.getLeft(), position.getBottom());
        }
        canvas.stroke();
        canvas.restoreState();
    }
}
DottedLineHeader.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
/*
    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
 */
package com.itextpdf.samples.sandbox.tables;
 
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.Style;
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 com.itextpdf.layout.renderer.TableRenderer;
import com.itextpdf.samples.GenericTest;
import com.itextpdf.test.annotations.type.SampleTest;
 
import org.junit.experimental.categories.Category;
 
import java.io.File;
 
@Category(SampleTest.class)
public class DottedLineHeader extends GenericTest {
    public static final String DEST = "./target/test/resources/sandbox/tables/dotted_line_header.pdf";
 
    public static void main(String[] args) throws Exception {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new DottedLineHeader().manipulatePdf(DEST);
    }
 
    @Override
    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(3)).useAllAvailableWidth();
        table.setNextRenderer(new DottedHeaderTableRenderer(table, new Table.RowRange(0, 1)));
        Style noBorder = new Style().setBorder(Border.NO_BORDER);
        table.addHeaderCell(new Cell().add(new Paragraph("A1")).addStyle(noBorder));
        table.addHeaderCell(new Cell().add(new Paragraph("A2")).addStyle(noBorder));
        table.addHeaderCell(new Cell().add(new Paragraph("A3")).addStyle(noBorder));
        table.addCell(new Cell().add(new Paragraph("B1")).addStyle(noBorder));
        table.addCell(new Cell().add(new Paragraph("B2")).addStyle(noBorder));
        table.addCell(new Cell().add(new Paragraph("B3")).addStyle(noBorder));
        table.addCell(new Cell().add(new Paragraph("C1")).addStyle(noBorder));
        table.addCell(new Cell().add(new Paragraph("C2")).addStyle(noBorder));
        table.addCell(new Cell().add(new Paragraph("C3")).addStyle(noBorder));
        doc.add(table);
        doc.add(new Paragraph("Cell event"));
        table = new Table(UnitValue.createPercentArray(3)).useAllAvailableWidth();
        Cell cell = new Cell().add(new Paragraph("A1")).addStyle(noBorder);
        cell.setNextRenderer(new DottedHeaderCellRenderer(cell));
        table.addCell(cell);
        cell = new Cell().add(new Paragraph("A2")).addStyle(noBorder);
        cell.setNextRenderer(new DottedHeaderCellRenderer(cell));
        table.addCell(cell);
        cell = new Cell().add(new Paragraph("A3")).addStyle(noBorder);
        cell.setNextRenderer(new DottedHeaderCellRenderer(cell));
        table.addCell(cell);
        table.addCell(new Cell().add(new Paragraph("B1")).addStyle(noBorder));
        table.addCell(new Cell().add(new Paragraph("B2")).addStyle(noBorder));
        table.addCell(new Cell().add(new Paragraph("B3")).addStyle(noBorder));
        table.addCell(new Cell().add(new Paragraph("C1")).addStyle(noBorder));
        table.addCell(new Cell().add(new Paragraph("C2")).addStyle(noBorder));
        table.addCell(new Cell().add(new Paragraph("C3")).addStyle(noBorder));
        doc.add(table);
 
        doc.close();
    }
 
 
    private class DottedHeaderTableRenderer extends TableRenderer {
        public DottedHeaderTableRenderer(Table modelElement, Table.RowRange rowRange) {
            super(modelElement, rowRange);
        }
 
        @Override
        public void drawChildren(DrawContext drawContext) {
            super.drawChildren(drawContext);
            PdfCanvas canvas = drawContext.getCanvas();
            canvas.setLineDash(3f, 3f);
            Rectangle headersArea = headerRenderer.getOccupiedArea().getBBox();
            canvas.moveTo(headersArea.getLeft(), headersArea.getTop());
            canvas.lineTo(headersArea.getRight(), headersArea.getTop());
 
            canvas.moveTo(headersArea.getLeft(), headersArea.getBottom());
            canvas.lineTo(headersArea.getRight(), headersArea.getBottom());
            canvas.stroke();
        }
    }
 
 
    private class DottedHeaderCellRenderer extends CellRenderer {
        public DottedHeaderCellRenderer(Cell modelElement) {
            super(modelElement);
        }
 
        @Override
        public void draw(DrawContext drawContext) {
            super.draw(drawContext);
            PdfCanvas canvas = drawContext.getCanvas();
            canvas.setLineDash(3f, 3f);
            canvas.moveTo(this.getOccupiedArea().getBBox().getLeft(), this.getOccupiedArea().getBBox().getBottom());
            canvas.lineTo(this.getOccupiedArea().getBBox().getRight(),
                    this.getOccupiedArea().getBBox().getBottom());
            canvas.moveTo(this.getOccupiedArea().getBBox().getLeft(),
                    this.getOccupiedArea().getBBox().getTop());
            canvas.lineTo(this.getOccupiedArea().getBBox().getRight(),
                    this.getOccupiedArea().getBBox().getTop());
            canvas.stroke();
        }
    }
}
RoundedCorners.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
/*
    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/30106862/left-and-right-top-round-corner-for-rectangelroundrectangle
 */
package com.itextpdf.samples.sandbox.tables;
 
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.UnitValue;
import com.itextpdf.layout.renderer.CellRenderer;
import com.itextpdf.layout.renderer.DrawContext;
import com.itextpdf.samples.GenericTest;
import com.itextpdf.test.annotations.type.SampleTest;
 
import org.junit.experimental.categories.Category;
 
import java.io.File;
 
@Category(SampleTest.class)
public class RoundedCorners extends GenericTest {
    public static final String DEST = "./target/test/resources/sandbox/tables/rounded_corners.pdf";
 
    public static void main(String[] args) throws Exception {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new RoundedCorners().manipulatePdf(DEST);
    }
 
    @Override
    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(3)).useAllAvailableWidth();
        Cell cell = getCell("These cells have rounded borders at the top.");
        table.addCell(cell);
        cell = getCell("These cells aren't rounded at the bottom.");
        table.addCell(cell);
        cell = getCell("A custom cell event was used to achieve this.");
        table.addCell(cell);
        doc.add(table);
 
        doc.close();
    }
 
    public Cell getCell(String content) {
        Cell cell = new Cell().add(new Paragraph(content));
        cell.setNextRenderer(new RoundedCornersCellRenderer(cell));
        cell.setPadding(5);
        cell.setBorder(null);
        return cell;
    }
 
 
    private class RoundedCornersCellRenderer extends CellRenderer {
        public RoundedCornersCellRenderer(Cell modelElement) {
            super(modelElement);
        }
 
        @Override
        public void draw(DrawContext drawContext) {
            float llx = getOccupiedAreaBBox().getX() + 2;
            float lly = getOccupiedAreaBBox().getY() + 2;
            float urx = getOccupiedAreaBBox().getX() + getOccupiedAreaBBox().getWidth() - 2;
            float ury = getOccupiedAreaBBox().getY() + getOccupiedAreaBBox().getHeight() - 2;
            float r = 4;
            float b = 0.4477f;
            PdfCanvas canvas = drawContext.getCanvas();
            canvas.moveTo(llx, lly);
            canvas.lineTo(urx, lly);
            canvas.lineTo(urx, ury - r);
            canvas.curveTo(urx, ury - r * b, urx - r * b, ury, urx - r, ury);
            canvas.lineTo(llx + r, ury);
            canvas.curveTo(llx + r * b, ury, llx, ury - r * b, llx, ury - r);
            canvas.lineTo(llx, lly);
            canvas.stroke();
            super.draw(drawContext);
        }
    }
}
TableBorder.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
/*
    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 the following question:
 * http://stackoverflow.com/questions/35340003
 */
package com.itextpdf.samples.sandbox.tables;
 
import com.itextpdf.kernel.geom.Rectangle;
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.DrawContext;
import com.itextpdf.layout.renderer.TableRenderer;
import com.itextpdf.samples.GenericTest;
import com.itextpdf.test.annotations.type.SampleTest;
 
import java.io.File;
 
import org.junit.experimental.categories.Category;
 
@Category(SampleTest.class)
public class TableBorder extends GenericTest {
    public static final String DEST = "./target/test/resources/sandbox/tables/tables_border.pdf";
 
    public static void main(String[] args) throws Exception {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new TableBorder().manipulatePdf(DEST);
    }
 
    @Override
    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(4)).useAllAvailableWidth();
        for (int aw = 0; aw < 16; aw++) {
            table.addCell(new Cell().add(new Paragraph("hi")).setBorder(Border.NO_BORDER));
        }
        // Notice that one should set renderer after table completion
        table.setNextRenderer(new TableBorderRenderer(table));
        doc.add(table);
        doc.close();
    }
 
 
    class TableBorderRenderer extends TableRenderer {
        public TableBorderRenderer(Table modelElement) {
            super(modelElement);
        }
 
        @Override
        protected void drawBorders(DrawContext drawContext) {
            Rectangle rect = getOccupiedAreaBBox();
            drawContext.getCanvas()
                    .saveState()
                    .rectangle(rect.getLeft(), rect.getBottom(), rect.getWidth(), rect.getHeight())
                    .stroke()
                    .restoreState();
        }
    }
}

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