Reputation: 85
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.
Upvotes: 0
Views: 2978
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:
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
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:
Upvotes: 2