3

I am trying to get dotted border (used cell border) in middle of the table by using iText 2.1.0. Below code would be generating dotted border even after middle of the table.

Could you please help me on this to add event for a specific cell alone?

import java.io.FileOutputStream;

import com.lowagie.text.Cell;
import com.lowagie.text.Document;
import com.lowagie.text.PageSize;
import com.lowagie.text.Phrase;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfPCell;
import com.lowagie.text.pdf.PdfPCellEvent;
import com.lowagie.text.pdf.PdfPTable;
import com.lowagie.text.pdf.PdfWriter;

public class DottedLine {

    public static final String RESULT = "Dotted.pdf";

    public static void main(String[] args) throws Exception {
        new DottedLine().createPdf(RESULT);
    }

    public void createPdf(String filename) throws Exception {

        Document document = new Document(PageSize.A4, 50, 50, 50, 50);

        PdfWriter.getInstance(document, new FileOutputStream(filename));

        document.open();

        PdfPTable tab = new PdfPTable(1);
        for (int j = 1; j <= 10; j++) {
            if (j == 5) {
                PdfPCell c1 = new PdfPCell(new Phrase("Test" + j));
                c1.setBorder(Rectangle.TOP);
                c1.setCellEvent(new dot());
                tab.addCell(c1);
            } else {
                PdfPCell c2 = new PdfPCell(new Phrase("Test " + j));
                c2.setBorder(Rectangle.TOP);
                tab.addCell(c2);
            }
        }

        document.add(tab);
        document.close();
    }

    // Cell Event to make dotted Line
    class dot implements PdfPCellEvent {

        @Override
        public void cellLayout(PdfPCell arg0, Rectangle arg1, PdfContentByte[] arg2) {
            arg0.setBorder(Rectangle.TOP);
            PdfContentByte cb = arg2[PdfPTable.LINECANVAS];
            cb.setLineDash(3f, 3f);
            cb.restoreState();
        }
    }
}
Bruno Lowagie
  • 75,994
  • 9
  • 109
  • 165
Nanda
  • 45
  • 1
  • 7
  • 1
    Not that upgrading would solve that paricular issue, but you should keep in mind that iText 2.1.0 is [more than 5 years old](http://itextpdf.com/changelog/210), and using such old versions may imply [technical and legal issues](http://lowagie.com/iText2), for both you and your customers. – Alexis Pigeon Nov 21 '13 at 10:26
  • +1 for Alexis. Look at my name. I'm the Lowagie you're mentioning every time you use `import com.lowagie` – Bruno Lowagie Nov 21 '13 at 14:42

1 Answers1

4

You're using a cell event, but your code is very poor. You're also introducing a PDF syntax error for which you would have received a warning if only you would use a more recent version of iText. (The warnings about obsolete iText versions are there for a reason. People shouldn't ignore them!!!)

This being said, I've made an example that solves your problem: DottedLineCell

The resulting PDF is a document with two tables: dotted_line_cell.pdf

For the first table, we use a table event:

class DottedCells implements PdfPTableEvent {
    @Override
    public void tableLayout(PdfPTable table, float[][] widths,
        float[] heights, int headerRows, int rowStart,
        PdfContentByte[] canvases) {
        PdfContentByte canvas = canvases[PdfPTable.LINECANVAS];
        canvas.setLineDash(3f, 3f);
        float llx = widths[0][0];
        float urx = widths[0][widths[0].length -1];
        for (int i = 0; i < heights.length; i++) {
            canvas.moveTo(llx, heights[i]);
            canvas.lineTo(urx, heights[i]);
        }
        for (int i = 0; i < widths.length; i++) {
            for (int j = 0; j < widths[i].length; j++) {
                canvas.moveTo(widths[i][j], heights[i]);
                canvas.lineTo(widths[i][j], heights[i+1]);
            }
        }
        canvas.stroke();
    }
}

This is the most elegant way to draw the cell borders, as it uses only one stroke() operator for all the lines. This isn't an option if you have tables with rowspans (but you probably don't care about rowspans, because you're using an obsolete version of iText that didn't support rowspans).

The second table uses a cell event:

class DottedCell implements PdfPCellEvent {
    @Override
    public void cellLayout(PdfPCell cell, Rectangle position,
        PdfContentByte[] canvases) {
        PdfContentByte canvas = canvases[PdfPTable.LINECANVAS];
        canvas.setLineDash(3f, 3f);
        canvas.rectangle(position.getLeft(), position.getBottom(),
            position.getWidth(), position.getHeight());
        canvas.stroke();
    }
}

With a cell event, a border is drawn around every cell. This means you'll have multiple stroke() operators and overlapping lines.

May I plead once more that you upgrade to a more recent version? Pre-iText 5 versions have a peculiar error that leads to table rows that disappear once in a billion rows.

Bruno Lowagie
  • 75,994
  • 9
  • 109
  • 165
  • I love iText for what it is and your posts are always very informative, but they read like FUD. Why don't you praise the new features and instead focus on the bad things of old versions? This also reflects on you as a developer ;-) – Phil Rykoff Oct 14 '14 at 19:52
  • The reason is simple: I am confronted with too many people claiming that they won't ever use the new version because of the AGPL. It's as if they don't want to invest in the future. It's as if they think we can go to the ISO meetings all around the world and help improve the PDF standard and the software just without generating any revenue. Some say we should offer professional services to make money instead of licenses. They don't understand that we're not here to take their job away. We don't want to compete with developers *using* iText. – Bruno Lowagie Oct 15 '14 at 06:34
  • Just a note.. above code would produce a PDF with all lines dotted.. one needs to SaveState() and at the end RestoreState() to avoid that.. – PepiX Jan 04 '23 at 11:47