Sameer
Sameer

Reputation: 85

Create a table with repeating header with iText

I want to create a table with repeatingheaders like the image that I attached to my post.

I want to fill the first three columns on the left to the end of the table and then fill the second three columns on the right of the table.

I used one table with 6 columns as it shown on the page.I fetched the data from database based on date order and I want to place my data in the table like the picture.

I can create a the table with iText in java but I don't know how can I create a table with this style in with iText. please help me if it is possible.

Table style

Upvotes: 0

Views: 2978

Answers (2)

Uladzimir Asipchuk
Uladzimir Asipchuk

Reputation: 2458

I didn't quite get how do you want your table to be processed on split and supposed that you're in search for a two column layout. If that's the case, there is a predefined ColumnDocumentRenderer class for you. If set on Document instance it allows to layout the document content into columns.

So i defined the columns:

Rectangle pageSize = pdfDocument.getDefaultPageSize(); Rectangle[] areas = new Rectangle[2]; areas[0] = new Rectangle(36, 36, ((float) pageSize.getWidth() / 2) - 35.75f, pageSize.getHeight() - 72); areas[1] = new Rectangle((float) pageSize.getWidth() / 2 - 0.25f, 36, ((float) pageSize.getWidth() / 2) - 35.75f , pageSize.getHeight() - 72);

And then I applied the renderer on the Document instance: layoutDocument.setRenderer(new ColumnDocumentRenderer(layoutDocument, areas));

The result on split looks that way: enter image description here

The code in full:

    @Test
public void tableTest02() throws Exception {
    String outFileName = destinationFolder + "tableTest02.pdf";
    String cmpFileName = sourceFolder + "cmp_tableTest02.pdf";

    PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
    Document layoutDocument = new Document(pdfDocument);


    Table table = new Table(3);
    table.setWidth(UnitValue.createPercentValue(100));

    Rectangle pageSize = pdfDocument.getDefaultPageSize();
    Rectangle[] areas = new Rectangle[2];
    areas[0] = new Rectangle(36, 36, ((float) pageSize.getWidth() / 2) - 35.75f, pageSize.getHeight() - 72);
    areas[1] = new Rectangle((float) pageSize.getWidth() / 2 - 0.25f, 36, ((float) pageSize.getWidth() / 2) - 35.75f , pageSize.getHeight() - 72);

    layoutDocument.setRenderer(new ColumnDocumentRenderer(layoutDocument, areas));
    // header
    for(int i=0;i<1;i++) {
        table.addHeaderCell(new Cell().add(new Paragraph("Number")).setBackgroundColor(new DeviceRgb(74,189,172)));
        table.addHeaderCell(new Cell().add(new Paragraph("Firstname")).setBackgroundColor(new DeviceRgb(74,189,172)));
        table.addHeaderCell(new Cell().add(new Paragraph("Lastname")).setBackgroundColor(new DeviceRgb(74,189,172)));
    }

    // table
    for(int i=0;i<500;i++){

        table.addCell(new Cell().add(new Paragraph((i + 1)+"")));
        table.addCell(new Cell().add(new Paragraph("Hello")));
        table.addCell(new Cell().add(new Paragraph("World")));

    }

    layoutDocument.add(table);

    pdfDocument.close();

    Assert.assertNull(new CompareTool().compareByContent(outFileName, cmpFileName, destinationFolder, "diff"));
}

The tricky moment was to collapse table borders but increasing the width with 0.25f and moving the right column 0.25f on the left i achieved the borders to be placed one on the other.

Upvotes: 0

Joris Schellekens
Joris Schellekens

Reputation: 9012

This is relatively straightforward.

First I made a class that represents a single data entry.

static class Record{
    public String firstname;
    public String lastname;
    public Record(String firstname, String lastname){
        this.firstname = firstname;
        this.lastname = lastname;
    }
    public String getFirstname(){return firstname;}
    public String getLastname(){return lastname;}
    public boolean equals(Object o){
        if(o instanceof Record){
            Record r = (Record) o;
            return r.firstname.equals(firstname) && r.lastname.equals(lastname);
        }
        return false;
    }
}

I also made a method that randomly generates objects of this kind, using characters of The Simpsons.

private static Random RANDOM = new Random(System.currentTimeMillis());
public Record randomRecord(){
    String[] fn = {"Marge", "Homer", "Bart", "Lisa", "Nelson", "Apu", "Doris", "Seymour"};
    String[] ln = {"Bouvier", "Simpson", "Muntz", "Nahasapeemapetilan", "Skinner"};
    return new Record(fn[RANDOM.nextInt(fn.length)], ln[RANDOM.nextInt(ln.length)]);
}

The code to generate the table looks like this:

    List<Record> recordList = new ArrayList<>();
    for(int i=0;i<17;i++)
        recordList.add(randomRecord());

    File outputFile = getOutputFile();
    PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outputFile));
    Document layoutDocument = new Document(pdfDocument);

    int numberOfItemsInFirstHalf = (int) Math.ceil(recordList.size() / 2.0);

    Table table = new Table(new float[]{0.16f, 0.16f, 0.16f, 0.16f, 0.16f, 0.16f});

    // header
    for(int i=0;i<2;i++) {
        table.addCell(new Cell().add(new Paragraph("Number")).setBackgroundColor(new DeviceRgb(74,189,172)));
        table.addCell(new Cell().add(new Paragraph("Firstname")).setBackgroundColor(new DeviceRgb(74,189,172)));
        table.addCell(new Cell().add(new Paragraph("Lastname")).setBackgroundColor(new DeviceRgb(74,189,172)));
    }

    // table
    for(int i=0;i<numberOfItemsInFirstHalf;i++){
        Record r0 = recordList.get(i);
        Record r1 = (i+numberOfItemsInFirstHalf) < recordList.size() ? recordList.get(i + numberOfItemsInFirstHalf) : null;

        table.addCell(new Cell().add(new Paragraph((i + 1)+"")));
        table.addCell(new Cell().add(new Paragraph(r0.getFirstname())));
        table.addCell(new Cell().add(new Paragraph(r0.getLastname())));

        if(r1 == null){
            table.addCell(new Cell().add(new Paragraph("")));
            table.addCell(new Cell().add(new Paragraph("")));
            table.addCell(new Cell().add(new Paragraph("")));
        }else{
            table.addCell(new Cell().add(new Paragraph((i + numberOfItemsInFirstHalf + 1)+"")));
            table.addCell(new Cell().add(new Paragraph(r1.getFirstname())));
            table.addCell(new Cell().add(new Paragraph(r1.getLastname())));
        }
    }

    layoutDocument.add(table);

    pdfDocument.close();

which generates the following PDF document:

enter image description here

Upvotes: 2

Related Questions