Problem Statement:-
I am using Itext7 in JAVA to create a PDF having a table. I need to give the separations between the cells of the table.
Red and blue arrows in the image are the pin points from where I want to separate them.
Any help regarding the issue is highly appreciated!!
Code:-
package com.example.pdfcreator;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import com.itextpdf.*;
#SpringBootApplication
public class PdfcreatorApplication {
public static final String DEST = "D:\\generate_pdf\\hello.pdf";
public static void main(String args[]) throws IOException, java.io.IOException {
PdfDocument pdf = new PdfDocument(new PdfWriter(DEST));
Document document = new Document(pdf);
var table = new Table(new float[] { 3,3,3,3,3,3,3}).setWidth(UnitValue.createPercentValue(100)).setFixedLayout().setFontSize(8).setMarginTop(4);
Cell cell11 = new Cell(1, 2).setBorder(Border.NO_BORDER).add(new Paragraph("label1 :"));
Cell cell12 = new Cell(1, 5).add(new Paragraph(""));
Cell cell21 = new Cell(1, 2).setBorder(Border.NO_BORDER).add(new Paragraph("label2 :"));
Cell cell22 = new Cell(1, 5).add(new Paragraph(""));
Cell cell31 = new Cell(1, 2).setBorder(Border.NO_BORDER).add(new Paragraph("label3 :"));
Cell cell32 = new Cell(1, 5).add(new Paragraph(""));
Cell cell41 = new Cell(1, 2).setBorder(Border.NO_BORDER).add(new Paragraph("label4 :"));
Cell cell42 = new Cell(1, 5).add(new Paragraph(""));
table.addCell(cell11);
table.addCell(cell12);
table.addCell(cell21);
table.addCell(cell22);
table.addCell(cell31);
table.addCell(cell32);
table.addCell(cell41);
table.addCell(cell42);
document.add(table);
var table99 = new Table(new float[] { 3,3,3,3,3,3,3}).setWidth(UnitValue.createPercentValue(100)).setFixedLayout().setFontSize(8);
Cell cell = new Cell(1,2).setBorder(Border.NO_BORDER).add(new Paragraph("label9 : "));
table99.addCell(cell);
cell = new Cell(1,4).add(new Paragraph(" "));
table99.addCell(cell);
Cell cell23 = new Cell(5, 1).add(new Paragraph("Photo").setMarginLeft(23).setMarginTop(28));
table99.addCell(cell23);
cell = new Cell(1,2).setBorder(Border.NO_BORDER).add(new Paragraph(" label10: "));
table99.addCell(cell);
cell = new Cell(1,4).add(new Paragraph(" "));
table99.addCell(cell);
cell = new Cell(1,2).setBorder(Border.NO_BORDER).add(new Paragraph(" label11: "));
table99.addCell(cell);
cell = new Cell(1,4).add(new Paragraph(" "));
table99.addCell(cell);
cell = new Cell(1,2).setBorder(Border.NO_BORDER).add(new Paragraph(" label12: "));
table99.addCell(cell);
cell = new Cell(1,4).add(new Paragraph(" "));
table99.addCell(cell);
cell = new Cell(1,2).setBorder(Border.NO_BORDER).add(new Paragraph(" label13: "));
table99.addCell(cell);
cell = new Cell(1,4).add(new Paragraph(" "));
table99.addCell(cell);
document.add(table99); }}
I have given the seperations using the empty cells with borders removed and it has worked properly as per my requirement. Demo code line which i have implemented are written as below.
I have created one style in which i have given the minimum height required for my spacing and removed the borders from the cell.
Style spacingCellStyle = new Style().setBorder(Border.NO_BORDER).setHeight(1);
Then, i have simply just added the cell with this style wherever in the table, spacing was required.
Table.addCell(new Cell(1, 6).addStyle(spacingCellStyle));
As per my requirement, this was the only possible way to do so and it executed perfectly.
Related
I have a question regarding iText (2.1.7).
I create a table which has TextFields in every cell at the moment. The TextFields are added with a PdfPCellEvent. I found this example on the iText Website and tried it out. It all works fine - until my table reaches a specific length. Then Acrobat Reader tells me, that there is an error on the page and that it might be displayed wrong. Nevertheless the table and the fields work, they are just slow (when changing fields, etc). When I open the PDF in Foxit Reader there is no error so I assume that there is a performance issue and Acrobat Reader cannot handle it.
I tried to split my table into smaller tables then and did 5 tables with 10 rows instead of one table with 50 rows - but the same problem occurs.
I now search for a way to increase the performance of my code, so that I can add a lot of rows without having this error message in Acrobat Reader.
This is my code:
First the PdfPCellEvent:
class MyCellField implements PdfPCellEvent {
protected String fieldname;
protected String content;
public MyCellField(String fieldname, String content) {
this.fieldname = fieldname;
this.content = content;
}
public void cellLayout(PdfPCell cell, Rectangle rectangle, PdfContentByte[] canvases) {
PdfWriter writer = canvases[PdfPTable.BASECANVAS].getPdfWriter();
TextField textField = new TextField(writer, rectangle, fieldname);
textField.setRotation(90);
textField.setFont(inside_textbox.getBaseFont());
textField.setFontSize(inside_textbox.getSize());
textField.setText(content);
PdfFormField field;
try {
field = textField.getTextField();
writer.addAnnotation(field);
} catch (Exception e) {
e.printStackTrace();
}
}
}
(I rotate the Textfield because the document is landscape)
And this is the place where i use it:
PageNumeration event = new PageNumeration();
writer.setPageEvent(event);
document.open();
PdfPTable table= new PdfPTable(8);
table.setWidths(new float[] {30,160,320,170,65,85,85,85});
table.setWidthPercentage(80);
table.setKeepTogether(false);
table= createTableHeads(document, table);
table.setHeaderRows(1);
PdfPCell cell;
for(int i=0; i<50; i++) {
cell = new PdfPCell();
cell.setMinimumHeight(mtp(4));
cell.setCellEvent(new MyCellField("a"+i, "a"));
table.addCell(cell);
cell = new PdfPCell();
cell.setMinimumHeight(mtp(4));
cell.setCellEvent(new MyCellField("b"+i, "b"));
table.addCell(cell);
cell = new PdfPCell();
cell.setMinimumHeight(mtp(4));
cell.setCellEvent(new MyCellField("c"+i, "c"));
table.addCell(cell);
cell = new PdfPCell();
cell.setMinimumHeight(mtp(4));
cell.setCellEvent(new MyCellField("d"+i, "d"));
table.addCell(cell);
cell = new PdfPCell();
cell.setMinimumHeight(mtp(4));
cell.setCellEvent(new MyCellField("e"+i, "e"));
table.addCell(cell);
cell = new PdfPCell();
cell.setMinimumHeight(mtp(4));
cell.setCellEvent(new MyCellField("f"+i, "f"));
table.addCell(cell);
cell = new PdfPCell();
cell.setMinimumHeight(mtp(4));
cell.setCellEvent(new MyCellField("g"+i, "g"));
table.addCell(cell);
cell = new PdfPCell();
cell.setMinimumHeight(mtp(4));
cell.setCellEvent(new MyCellField("h"+i, "h"));
table.addCell(cell);
}
document.add(table);
document.close();
mtp() is just a shorter writing for Utilities.millimetersToPoints. And createTableHeads adds 8 cells with plain text in it to the table before adding all the Textfield-Cells.
Are there any ideas on how to avoid the error message I get?
EDIT
I just noticed that actually my PageNumeration Event causes trouble if the table gets too long. But still its not obvious for my why it does so. This is the PageNumerationEvent:
private class PageNumeration extends PdfPageEventHelper{
PdfTemplate allPages;
#Override
public void onOpenDocument(PdfWriter writer, Document document) {
allPages = writer.getDirectContent().createTemplate(50, 50);
allPages.setFontAndSize(standard_text.getBaseFont(), standard_text.getSize());
}
#Override
public void onEndPage(PdfWriter writer, Document document) {
PdfContentByte cb = writer.getDirectContent();
cb.beginText();
try {
Rectangle pageSize = document.getPageSize();
cb.setFontAndSize(standard_text.getBaseFont(), standard_text.getSize());
String s = "( " + writer.getPageNumber() + " / ";
cb.showTextAligned(Element.ALIGN_CENTER, s, pageSize.getWidth() /2, document.bottomMargin(), 0);
cb.addTemplate(allPages, pageSize.getWidth() /2 + standard_text.getBaseFont().getWidthPoint(s, 4), document.bottomMargin());
} catch (Exception exc) {
exc.printStackTrace();
}
cb.endText();
}
#Override
public void onCloseDocument(PdfWriter writer, Document document) {
allPages.beginText();
try {
allPages.setFontAndSize(standard_text.getBaseFont(), standard_text.getSize());
allPages.setTextMatrix(0f, 0f);
allPages.showText("" + (writer.getPageNumber() -1) + " )");
} catch (Exception ex) {
ex.printStackTrace();
}
allPages.endText();
}
}
If you see the below table I have separated two cells one cell is added as a left cell(Name) and one more cell added as a table.
I have tried below code :
I am using the package as import com.lowagie.text.pdf.*;
PdfWriter.getInstance(document,
new FileOutputStream("C:/Temp/TableWidthAlignment.pdf"));
document.open();
//Main table
PdfPTable mainTable = new PdfPTable(2);
mainTable.setWidths(new int[] { 10,90 });
//cell one is Name cell
PdfPCell innerCellKeyName = new PdfPCell(new Phrase("Name", boldFont));
//innerCellKeyName.setBorder(Rectangle.NO_BORDER);
mainTable.addCell(innerCellKeyName);
PdfPTable table = new PdfPTable(3);
PdfPCell cell = new PdfPCell(new Paragraph("header with colspan 3"));
cell.setColspan(3);
table.addCell(cell);
table.addCell("1.1");
table.addCell("2.1");
table.addCell("3.1");
table.addCell("1.2");
table.addCell("2.2");
table.addCell("3.2");
table.addCell("4.1");
table.addCell("4.2");
table.addCell("4.3");
//cell two is as table
PdfPCell cell2 = new PdfPCell(table);
mainTable.addCell(cell2);
document.add(mainTable);
Output is:
Expected output is : Cross box need to be removed form box in the left cell.
I have tried some thing to make work out of expected result
Solution:
I have copy pasted the same above table and made the left cell as no boarder.
document.open();
PdfPTable mainTable = new PdfPTable(2);
mainTable.setWidths(new int[] { 10,90 });
PdfPCell innerCellKeyName = new PdfPCell(new Phrase("Name", boldFont));
//innerCellKeyName.setBorder(Rectangle.NO_BORDER);
mainTable.addCell(innerCellKeyName);
// step4
PdfPTable table = new PdfPTable(3);
PdfPCell cell = new PdfPCell(new Paragraph("header with colspan 3"));
cell.setColspan(3);
table.addCell(cell);
table.addCell("1.1");
table.addCell("2.1");
table.addCell("3.1");
table.addCell("1.2");
table.addCell("2.2");
table.addCell("3.2");
table.addCell("4.1");
table.addCell("4.2");
table.addCell("4.3");
PdfPCell cell2 = new PdfPCell(table);
mainTable.addCell(cell2);
document.add(mainTable);
PdfPTable mainTable2 = new PdfPTable(2);
mainTable2.setWidths(new int[] { 10,90 });
PdfPCell innerCellKeyName2 = new PdfPCell(new Phrase("", boldFont));
innerCellKeyName2.setBorder(Rectangle.NO_BORDER);
mainTable2.addCell(innerCellKeyName2);
// step4
PdfPTable table2 = new PdfPTable(3);
PdfPCell cell3 = new PdfPCell(new Paragraph("header with colspan 3"));
cell3.setColspan(3);
table2.addCell(cell3);
table2.addCell("1.1");
table2.addCell("2.1");
table2.addCell("3.1");
table2.addCell("1.2");
table2.addCell("2.2");
table2.addCell("3.2");
table2.addCell("4.1");
table2.addCell("4.2");
table2.addCell("4.3");
PdfPCell cell4 = new PdfPCell(table2);
mainTable2.addCell(cell4);
document.add(mainTable2);
/**
* Adds the header and the footer.
* #see com.itextpdf.text.pdf.PdfPageEventHelper#onEndPage(
* com.itextpdf.text.pdf.PdfWriter, com.itextpdf.text.Document)
*/
public void onEndPage(PdfWriter writer, Document document) {
//Rectangle rect = writer.getBoxSize("art");
CalibrateItLogger.publish("Page Number :"+writer.getPageNumber());
PdfPTable footterPdfPTable = new PdfPTable(1);
PdfPTable fotterLeftPdfPTable =new PdfPTable(1);
PdfPTable fotterRightPdfPTable =new PdfPTable(1);
//document.newPage();
document.add(Chunk.NEWLINE);
footterPdfPTable = new PdfPTable(3);
footterPdfPTable.setWidthPercentage(100);
fotterLeftPdfPTable = new PdfPTable(1);
fotterLeftPdfPTable.setWidthPercentage(100);
PdfPCell planBExtendedPdfPCell = new PdfPCell();
planBExtendedPdfPCell.addElement(new Paragraph("PLAN B EXTENDED"));
planBExtendedPdfPCell.setBorder(Rectangle.NO_BORDER);
fotterLeftPdfPTable.addCell(planBExtendedPdfPCell);
//Calibration Company Name
PdfPCell comapnyNameLablePdfPCell=new PdfPCell (new Paragraph (companyname(),font4));
comapnyNameLablePdfPCell.setBorder(Rectangle.NO_BORDER);
fotterLeftPdfPTable.addCell(comapnyNameLablePdfPCell);
//Address
PdfPCell addressPdfPCell=new PdfPCell (new Paragraph ("Address data",font3));
addressPdfPCell.setBorder(Rectangle.NO_BORDER);
fotterLeftPdfPTable.addCell(addressPdfPCell);
//Zipcode
PdfPCell zipPdfPCell=new PdfPCell (new Paragraph ("Postal code",font3));
zipPdfPCell.setBorder(Rectangle.NO_BORDER);
fotterLeftPdfPTable.addCell(zipPdfPCell);
//Certificate and Serial Number
PdfPCell cityStateAndZipPdfPCell=new PdfPCell (new Paragraph ("Serial No ",font3));
cityStateAndZipPdfPCell.setBorder(Rectangle.NO_BORDER);
fotterLeftPdfPTable.addCell(cityStateAndZipPdfPCell);
//Model Name and Asset No
PdfPCell pipetteModelNamePdfPCell=new PdfPCell (new Paragraph ("Asset No",font3));
pipetteModelNamePdfPCell.setBorder(Rectangle.NO_BORDER);
fotterLeftPdfPTable.addCell(pipetteModelNamePdfPCell);
PdfPCell footerLeftPdfPCell = new PdfPCell(fotterLeftPdfPTable);
footerLeftPdfPCell.setBorder(Rectangle.NO_BORDER);
footterPdfPTable.addCell(footerLeftPdfPCell);
PdfPCell emptyPdfPCell = getEmptyPdfPCell();
emptyPdfPCell.addElement(getEmptyParagraph());
PdfPTable pageNumberPdfPTable = new PdfPTable(1);
pageNumberPdfPTable.addCell(emptyPdfPCell);
pageNumberPdfPTable.addCell(emptyPdfPCell);
pageNumberPdfPTable.addCell(emptyPdfPCell);
pageNumberPdfPTable.addCell(emptyPdfPCell);
pageNumberPdfPTable.addCell(emptyPdfPCell);
Paragraph pageNumberParagraph = new Paragraph("Page "+pagenumber,font3);
pageNumberParagraph.setAlignment(Element.ALIGN_CENTER);
//pageNumberPdfPTable.addCell(pageNumberParagraph);
PdfPCell pegeNumberPdfPCell = new PdfPCell(pageNumberParagraph);
pegeNumberPdfPCell.setBorder(Rectangle.NO_BORDER);
footterPdfPTable.addCell(pegeNumberPdfPCell);
fotterRightPdfPTable = new PdfPTable(2);
fotterRightPdfPTable.setWidthPercentage(100);
//Date
Paragraph dateParagraph = new Paragraph(new Phrase("Date :"+CurrentDate.getDateFormat(Date,"dd/MM/yyyy"),font3));
dateParagraph.setAlignment(Element.ALIGN_LEFT);
PdfPCell datePdfPCell = new PdfPCell(dateParagraph);
datePdfPCell.setBorder(Rectangle.NO_BORDER);
fotterRightPdfPTable.addCell(datePdfPCell);
//Next Due Data
Paragraph nextDueParagraph = new Paragraph(new Phrase("Next Due :"+CurrentDate.getDateFormat(Date,"dd/MM/yyyy"),font3));
dateParagraph.setAlignment(Element.ALIGN_LEFT);
PdfPCell nextDuePdfPCell = new PdfPCell(nextDueParagraph);
nextDuePdfPCell.setBorder(Rectangle.NO_BORDER);
fotterRightPdfPTable.addCell(nextDuePdfPCell);
fotterRightPdfPTable.addCell(getEmptyPdfPCell());
fotterRightPdfPTable.addCell(getEmptyPdfPCell());
fotterRightPdfPTable.addCell(getEmptyPdfPCell());
fotterRightPdfPTable.addCell(getEmptyPdfPCell());
emptyPdfPCell = getEmptyPdfPCell();
emptyPdfPCell.setColspan(2);
fotterRightPdfPTable.addCell(emptyPdfPCell);
PdfPCell underlinePdfPCell = new PdfPCell(new Phrase(new Chunk("Sign :").setUnderline(+1f, -2f)));
underlinePdfPCell.setBorder(Rectangle.NO_BORDER);
underlinePdfPCell.setColspan(2);
fotterRightPdfPTable.addCell(underlinePdfPCell);
Paragraph employeeParagraph = new Paragraph("Govardhan Rao",font3);
employeeParagraph .setAlignment(Element.ALIGN_CENTER);
PdfPCell employeePdfPCell = new PdfPCell(employeePdfPCell );
employeePdfPCell .setBorder(Rectangle.NO_BORDER);
calibrationEmployeePdfPCell.setColspan(2);
fotterRightPdfPTable.addCell(employeePdfPCell );
PdfPCell footerRightPdfPCell = new PdfPCell(fotterRightPdfPTable);
footerRightPdfPCell.setBorder(Rectangle.NO_BORDER);
footterPdfPTable.addCell(footerRightPdfPCell);
//footterPdfPTable.writeSelectedRows(0, -1, 34, 803, writer.getDirectContent());
document.add(footterPdfPTable);
I'm using itext-rtf 2.1.7 to generate an RTF document.
The parameter table below for the method writeSectionHeaderTableInACell() will have two columns.
For each column, I need to insert a new inner Table, with two columns as well. This inner table will have the first column as left-aligned, and the second as right-aligned.
However, the code below causes a corrupted Table in the generated RTF document. The two inner Tables which supposed to be both on a single row, they appear as one row for each inner Table.
Anyone, has any idea why it seems we cannot add an inner Table within a Cell for RTF document? Thanks.
private static void writeSectionHeaderTableInACell(PdfPTable table) {
PdfPTable sectionTable1 = new PdfPTable(2);
Phrase phrase1 = new Phrase("? 1 ?", FontFactory.getFont("MS Mincho", 10, Font.NORMAL));
Paragraph p1 = new Paragraph(phrase1);
p1.setAlignment(Element.ALIGN_LEFT);
PdfPCell cell1 = new PdfPCell(p1);
sectionTable1.addCell(cell1);
Phrase phrase2 = new Phrase("2 Chi", FontFactory.getFont("MS Mincho", 10, Font.NORMAL));
Paragraph p2 = new Paragraph(phrase2);
p2.setAlignment(Element.ALIGN_RIGHT);
PdfPCell cell2 = new PdfPCell(p2);
sectionTable1.addCell(cell2);
table.addCell(new PdfPCell(sectionTable1));
PdfPTable sectionTable2 = new PdfPTable(2);
Phrase phrase3 = new Phrase("Section 1", FontFactory.getFont("Times New Roman", 10, Font.NORMAL));
Paragraph p3 = new Paragraph(phrase3);
p3.setAlignment(Element.ALIGN_LEFT);
PdfPCell cell3 = new PdfPCell(p3);
sectionTable2.addCell(cell3);
Phrase phrase4 = new Phrase("2 Eng", FontFactory.getFont("Times New Roman", 10, Font.NORMAL));
Paragraph p4 = new Paragraph(phrase4);
p4.setAlignment(Element.ALIGN_RIGHT);
PdfPCell cell4 = new PdfPCell(p4);
sectionTable2.addCell(cell4);
table.addCell(new PdfPCell(sectionTable2));
}
I have a lot of small tables, which i encapsulate in a sorrounding 1x1 table, and set the SplitRows attribute to false on the sorrounding table. This way, i can avoid my table getting split when it reaches the bottom of a page. When i get to the end of a page, and there is a little space for text, but not enough for the next table, iText doesn't add the table at all, but continues to add the next table in the list.
If there is not enough space for the table on the current page, id like to send it to the next. What can i do?
http://compgroups.net/comp.text.pdf/Avoid-page-breaks-in-PdfPTable-using-iText-1.2
This is my code:
public static void CreateMatrixProcentQuestionTable(ShowQuestionViewModel model, Document doc)
{
ShowMatrixQuestionViewModel sm = (ShowMatrixQuestionViewModel)model;
Font fontsize = new Font(Font.FontFamily.HELVETICA, 9f);
Font QuestionFont = new Font(Font.FontFamily.HELVETICA, 12f);
PdfPTable table = new PdfPTable(sm.columns.Count + 2);
// Tilføj spørgsmålet i en række for sig selv, ellers er der chance for at
// svarmulighederne ikke kommer med ved page breaks
PdfPCell question = new PdfPCell(new Phrase(sm.Question_Wording + Environment.NewLine, QuestionFont));
question.Border = Rectangle.NO_BORDER;
question.Colspan = table.NumberOfColumns;
table.AddCell(question);
// Tilføj et mellemrum mellem spørgsmålet og svarmulighederne
PdfPCell mellemrum = new PdfPCell(new Phrase(Environment.NewLine));
mellemrum.Border = Rectangle.NO_BORDER;
mellemrum.Colspan = table.NumberOfColumns;
table.AddCell(mellemrum);
// Tilføj rækker og kolonner
// Dette er den første tomme celle
table.AddCell(new PdfPCell(new Phrase("", fontsize)));
foreach (MatrixColumns column in sm.columns)
{
PdfPCell cell = new PdfPCell(new Phrase(column.Column_Description, fontsize));
cell.HorizontalAlignment = 1;
table.AddCell(cell);
}
PdfPCell ialt = new PdfPCell(new Phrase("I alt", fontsize));
ialt.HorizontalAlignment = 1;
table.AddCell(ialt);
foreach (var pair in sm.columnrow)
{
MatrixRows row = pair.Key;
PdfPCell rowcell = new PdfPCell(new Phrase(row.Row_Description == null ? "*" : row.Row_Description, fontsize));
rowcell.HorizontalAlignment = 1;
table.AddCell(rowcell);
foreach (MatrixColumns column in pair.Value)
{
PdfPCell cell = new PdfPCell(new Phrase("%", fontsize));
cell.HorizontalAlignment = Element.ALIGN_RIGHT;
table.AddCell(cell);
}
PdfPCell sumcell = new PdfPCell(new Phrase("100%", fontsize));
sumcell.HorizontalAlignment = Element.ALIGN_RIGHT;
table.AddCell(sumcell);
}
// Man laver en 1x1 table uden om den rigtige table, og sætter
// SplitRows = False. Dette gør at tabellen ikke bliver knækket over
// ved page breaks
PdfPTable sorroundingTable = new PdfPTable(1);
PdfPCell innerTable = new PdfPCell(table);
innerTable.Border = Rectangle.NO_BORDER;
sorroundingTable.AddCell(innerTable);
sorroundingTable.SplitRows = false;
doc.Add(sorroundingTable);
doc.Add(new Phrase(Environment.NewLine));
}
This solves the problem:
table.setKeepTogether(true)
document.add(table)