iText library exception throwing on adding blank Cell with space - java

I tried to add a blank cell with space (" ") into my pdf file. i.e
PdfPCell blankCell = ContentHandler.getNormalCell(" ", language,fontsize);
It throws this error
Message: java.lang.NullPointerException
com.itextpdf.text.DocumentException: java.lang.NullPointerException
at com.itextpdf.text.pdf.PdfDocument.add(PdfDocument.java:727)
at com.itextpdf.text.Document.add(Document.java:282)
Then i removed space from cell.. i.e
PdfPCell blankCell = ContentHandler.getNormalCell("", language,fontsize);
I resolved my issue this way but pdf is in bad beauty.
Can somebody help me out with, is there any solution available for this, apart from what i am doing
Edited:
public static PdfPCell getNormalCell(String string, String language, float size) throws DocumentException, IOException {
// TODO Auto-generated method stub
Font f = new Font();
if(string!=null && !"".equals(string)){
f = getFontForThisLanguage(language);
}
if(size==-1) //Using a condition to make color RED as per need in view report
{
f.setColor(BaseColor.RED);
}
f.setSize(size);
Chunk chunk = new Chunk(new String(string.getBytes(), "UTF-8"),f);
PdfPCell pdfCell1 = new PdfPCell(new Phrase(string, f));
pdfCell1.setHorizontalAlignment(Element.ALIGN_LEFT);
return pdfCell1;
}

First the answer to your question: I have created an example called CellMethod and I can perfectly add a " " to a PdfPCell without causing a NullPointerException. This is my code:
public void createPdf(String dest) throws IOException, DocumentException {
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream(dest));
document.open();
PdfPTable table = new PdfPTable(2);
table.addCell("Winansi");
table.addCell(getNormalCell("Test", null, 12));
table.addCell("Winansi");
table.addCell(getNormalCell("Test", null, -12));
table.addCell("Greek");
table.addCell(getNormalCell("\u039d\u03cd\u03c6\u03b5\u03c2", "greek", 12));
table.addCell("Czech");
table.addCell(getNormalCell("\u010c,\u0106,\u0160,\u017d,\u0110", "czech", 12));
table.addCell("Test");
table.addCell(getNormalCell(" ", null, 12));
table.addCell("Test");
table.addCell(getNormalCell(" ", "greek", 12));
table.addCell("Test");
table.addCell(getNormalCell(" ", "czech", 12));
document.add(table);
document.close();
}
public static PdfPCell getNormalCell(String string, String language, float size)
throws DocumentException, IOException {
if(string != null && "".equals(string)){
return new PdfPCell();
}
Font f = getFontForThisLanguage(language);
if(size < 0) {
f.setColor(BaseColor.RED);
size = -size;
}
f.setSize(size);
PdfPCell cell = new PdfPCell(new Phrase(string, f));
cell.setHorizontalAlignment(Element.ALIGN_LEFT);
return cell;
}
public static Font getFontForThisLanguage(String language) {
if ("czech".equals(language)) {
return FontFactory.getFont(FONT, "Cp1250", true);
}
if ("greek".equals(language)) {
return FontFactory.getFont(FONT, "Cp1253", true);
}
return FontFactory.getFont(FONT, null, true);
}
The resulting PDF can be found here: cell_method.pdf
Now about the comments. It's as if you don't want to accept that your code is badly written. Instead, you claim that there's a problem with iText. It is a bad craftsman who blames his tools.
You did an attempt to improve your method, but let's take a look at your method and add some comments:
public static PdfPCell getNormalCell(String string, String language, float size)
throws DocumentException, IOException {
// The next line will create an instance of Helvetica, 12pt.
Font f = new Font();
// I don't understand this check. Why is it important to check string here?
if(string!=null && !"".equals(string)){
// are you sure you didn't want to check if language is not null?
f = getFontForThisLanguage(language);
// we have no idea what getFontForThisLanguage is doing
// what if language is null, does it throw an exception?
}
// This is ridiculous. See the next comment to find out why
if(size==-1) //Using a condition to make color RED as per need in view report
{
f.setColor(BaseColor.RED);
}
// In some situations, you are setting the font size to -1, that doesn't make sense
f.setSize(size);
// This line doesn't make sense either.
// (1.) string should already be in unicode.
// why are you getting the bytes and creating a UTF-8 string?
// (2.) why are you creating this chunk object? you never use it
Chunk chunk = new Chunk(new String(string.getBytes(), "UTF-8"),f);
// See: you're creating a Phrase with string, you don't use chunk!
PdfPCell pdfCell1 = new PdfPCell(new Phrase(string, f));
pdfCell1.setHorizontalAlignment(Element.ALIGN_LEFT);
return pdfCell1;
}
Please compare with my version of the method.

Related

How to count the number of tabs need to cover a string

I am trying to create a string by arranging my data in two columns.
String s = "";
List selectedItems = listView.getSelectionModel().getSelectedItems();
s = s + (String) selectedItems.get(0);
String t;
for (int i = 1 ; i<selectedItems.size();i++){
t = (String) selectedItems.get(i);
if (i%2!=0){
s = s + "\t\t\t";
}
else{
s = s + "\n";
}
s = s + (String) t;
}
My idea is to use a code like this for the task. but depending on the length of the strings, I can't get the second column to one line.
I am thinking there is a way to count the number of tabs need to cover one string an change the number of extra tabs I add instead of adding 3 tabs to every line. but I can't figure out how to count this.
how can I fix this problem?
current results:
one two
three four
five six
expected results:
one two
three four
five six
this is the result of after fill the string with " " with a total length of 30.
i am only using jfx to get the data. itextPdf us used to write the string to a pdf
Accordin to this document you have 3 options:
Assuming you have such data:
public static final String[][] DATA = {
{"John Edward Jr.", "AAA"},
{"Pascal Einstein W. Alfi", "BBB"},
};
1: use a table
public void createPdf(String dest) throws IOException, DocumentException {
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream(dest));
document.open();
PdfPTable table = new PdfPTable(2);
table.setWidthPercentage(50);
table.setHorizontalAlignment(Element.ALIGN_LEFT);
table.setWidths(new int[]{5, 1});
table.getDefaultCell().setBorder(Rectangle.NO_BORDER);
table.addCell("Name: " + DATA[0][0]);
table.addCell(DATA[0][1]);
table.addCell("Surname: " + DATA[1][0]);
table.addCell(DATA[1][1]);
table.addCell("School: " + DATA[2][0]);
table.addCell(DATA[1][1]);
document.add(table);
document.close();
}
2: use tabs
public void createPdf(String dest) throws FileNotFoundException, DocumentException {
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream(dest));
document.open();
document.add(createParagraphWithTab("Name: ", DATA[0][0], DATA[0][1]));
document.add(createParagraphWithTab("Surname: ", DATA[1][0], DATA[1][1]));
document.add(createParagraphWithTab("School: ", DATA[2][0], DATA[2][1]));
document.close();
}
public Paragraph createParagraphWithTab(String key, String value1, String value2) {
Paragraph p = new Paragraph();
p.setTabSettings(new TabSettings(200f));
p.add(key);
p.add(value1);
p.add(Chunk.TABBING);
p.add(value2);
return p;
}
3: use spaces and a monospaced font
public void createPdf(String dest) throws DocumentException, IOException {
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream(dest));
document.open();
BaseFont bf = BaseFont.createFont(FONT, BaseFont.CP1250, BaseFont.EMBEDDED);
Font font = new Font(bf, 12);
document.add(createParagraphWithSpaces(font, String.format("%s: %s", "Name", DATA[0][0]), DATA[0][1]));
document.add(createParagraphWithSpaces(font, String.format("%s: %s", "Surname", DATA[1][0]), DATA[1][1]));
document.add(createParagraphWithSpaces(font, String.format("%s: %s", "School", DATA[2][0]), DATA[2][1]));
document.close();
}
public Paragraph createParagraphWithSpaces(Font font, String value1, String value2) {
Paragraph p = new Paragraph();
p.setFont(font);
p.add(String.format("%-35s", value1));
p.add(value2);
return p;
}
To achieve the desired output you don't need to count anything - you just use System.out.printf:
public class Main {
public static void main(String[] args) {
System.out.printf("%-10s %-10s\n", "test", "test1");
System.out.printf("%-10s %-10s\n", "longertest", "test2");
}
}
Result:
test test1
longertest test2
As was mentioned in the comment - that will not fix a problem if the font that you use is not monospaced, so I would suggest changing the font as well.
BaseFont bf = BaseFont.createFont(FONT, BaseFont.CP1250, BaseFont.EMBEDDED);
Font font = new Font(bf, 12);

java.io.IOException: The document has no pages. Working fine locally but not working after deploying in aws

Hi I am trying to create an PDF using itextpdf.
It is working fine when tested locally.
But after aws deployment I am getting 406 Not Acceptable with java.io.IOException: The document has no pages excpetion.
Many answers are there but those are not related to deployment issues.
Do I need to check any network configuration or problem lies in the pdf generation code?
Following is my code implementation:
Please suggest some solution.
public byte[] createPdf(List<Participant> participantList) throws IOException,
DocumentException, com.google.zxing.WriterException {
Document document = new Document();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
PdfWriter.getInstance(document, byteArrayOutputStream);
document.open();
document.add(createMainTable(participantList));
document.close();
return byteArrayOutputStream.toByteArray();
}
public static PdfPTable createMainTable(List<Participant> optionalParticipant) throws BadElementException,
IOException, com.google.zxing.WriterException {
PdfPTable table = new PdfPTable(2);
logger.info("Main Table was created");
for (int i = 0; i < optionalParticipant.size(); i++) {
PdfPCell cell1 = new PdfPCell();
cell1.setBorderWidth(0);
cell1.setPadding(10f);
cell1.addElement(createSubTable(optionalParticipant.get(i)));
table.addCell(cell1);
}
return table;
}
public static PdfPTable createSubTable(Participant participant) throws BadElementException,
IOException, com.google.zxing.WriterException {
BaseColor baseColor = new BaseColor(150, 150, 150);
PdfPTable table = new PdfPTable(2);
table.setWidthPercentage(100);
PdfPCell cell, cell1, cell2;
Font font = new Font();
font.setSize(10f);
font.setColor(BaseColor.WHITE);
String participantName = participant.getFirstName() + " " + participant.getLastName();
Chunk chunk = new Chunk(participantName, font);
Paragraph head = new Paragraph(" "+chunk);
head.setFont(font);
cell = new PdfPCell(head);
cell.setColspan(2);
cell.setBackgroundColor(baseColor);
cell.setPadding(2f);
table.addCell(cell);
String qrData = participant.getQrCodeData();
Image img = getQRCodeImage(qrData);
font = new Font();
font.setSize(5f);
chunk = new Chunk("\n" + "Event ID: " + participant.getEvent().getEventId() +
"\n\n" + "Unique ID: " + participant.getUniqueId() +
"\n\n" + "Email ID: " + participant.getEmail(), font);
Paragraph body = new Paragraph(chunk);
cell1 = new PdfPCell(body);
cell1.setBorderWidthRight(0);
cell1.setPadding(10f);
cell2 = new PdfPCell();
cell2.addElement(img);
cell2.setBorderWidthLeft(1);
cell2.setPadding(10f);
table.addCell(cell1);
table.addCell(cell2);
logger.info("Sub Table was created");
return table;
}
Please check participantList is not null and contains elements. You can use logger to print size of list before start using it.
logger.info("No of participants: "+participantList.size());
Also, Immediately after opening document, always add an empty chunk to document so that you can avoid this exception.
document.open();
document.add(new Chunk(""));

Issue with Adding TextField to PdfPCell

I'm using itext to generate editable Calendar pdf.
Im trying to add TextField to the PdfPCell using this code,
//To create PdfPCell for a specific day
public PdfPCell getDayCell(Calendar calendar, Locale locale) {
PdfPCell cell = new PdfPCell();
cell.setPadding(3);
// set the background color, based on the type of day
if (isSunday(calendar))
cell.setBackgroundColor(BaseColor.GRAY);
else if (isSpecialDay(calendar))
cell.setBackgroundColor(BaseColor.LIGHT_GRAY);
else
cell.setBackgroundColor(BaseColor.WHITE);
// set the content in the language of the locale
Chunk chunk = new Chunk(String.format(locale, "%1$ta", calendar), small);
chunk.setTextRise(5);
// a paragraph with the day
Paragraph p = new Paragraph(chunk);
// a separator
p.add(new Chunk(new VerticalPositionMark()));
// and the number of the day
p.add(new Chunk(String.format(locale, "%1$te", calendar), normal));
cell.addElement(p);
cell.setCellEvent(new MyCellField(locale+""+calendar));
cell.setFixedHeight(80);
return cell;
}
// Adding TextField to the cellEvent
class MyCellField implements PdfPCellEvent {
protected String fieldname;
public MyCellField(String fieldname) {
this.fieldname = fieldname;
}
public void cellLayout(PdfPCell cell, Rectangle rectangle, PdfContentByte[] canvases) {
final PdfWriter writer = canvases[0].getPdfWriter();
final TextField textField = new TextField(writer, rectangle, fieldname);
textField.setAlignment(Element.ALIGN_TOP);
textField.setOptions(TextField.MULTILINE);
try {
final PdfFormField field = textField.getTextField();
writer.addAnnotation(field);
} catch (final IOException ioe) {
throw new ExceptionConverter(ioe);
} catch (final DocumentException de) {
throw new ExceptionConverter(de);
}
}
}
When I render the calendar pdf, the Cell focus is vertical not horizontal.
Kindly help me to find out what I'm missing.
NOTE: Please don't negative vote, I really want to figure out how to solve this. I referred other links like ITextSharp - text field in PdfPCell which where not helpful.
I tried adding
float textboxheight = 12f;
Rectangle rect = rectangle;
rect.Bottom = rect.Top - textboxheight;
rect.Bottom is showing error "The final field Rectangle.BOTTOM cannot be assigned".
Im using iText5
I think it's odd, because the behavior you describe isn't supposed to happen in the official iText version. (That makes me wonder: where did you get your version?)
However, you could try replacing this line:
Document document = new Document(PageSize.A4);
With this line:
Document document = new Document(new Rectangle(842, 595));

When i am generating pdf form I want to add form number on top left of the pdf using itext java

Hi When I am generating form using java with itext I want to add form number on top left of the document
above the header.Please let me know the ways to do it.
PdfPTable table = new PdfPTable(3); // 3 columns.
table.setWidthPercentage(100);
PdfPCell cell1 = new PdfPCell(new Paragraph("Cell 1"));
PdfPCell cell2 = new PdfPCell(new Paragraph("Cell 2"));
PdfPCell cell3 = new PdfPCell(new Paragraph("Cell 3"));
cell1.setBorder(0);
cell2.setBorder(0);
cell3.setBorder(0);
table.addCell(cell1);
table.addCell(cell2);
table.addCell(cell3);
How can I set the table alignment to start of the page margin.
Your question is very confusing. You say you are creating a form, but when you say form, you don't seem to be referring to an interactive form, but to an ordinary PDF containing a table.
You say you want to add a number above the header, but you are not telling us what you mean by header. You are assuming that the people reading your question can read your mind.
I guess you want to use a page event to add a String in the top left corner of each page. That would make your question almost a duplicate of itextsharp: How to generate a report with dynamic header in PDF using itextsharp?
You can create a subclass of PdfPageEventHelper like this:
public class Header extends PdfPageEventHelper {
protected Phrase header;
public void setHeader(Phrase header) {
this.header = header;
}
#Override
public void onEndPage(PdfWriter writer, Document document) {
PdfContentByte canvas = writer.getDirectContentUnder();
ColumnText.showTextAligned(canvas, Element.ALIGN_LEFT, header, 36, 806, 0);
}
}
You can then use this Header class like this:
public void createPdf(String filename) throws IOException, DocumentException {
// step 1
Document document = new Document();
// step 2
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(filename));
Header event = new Header();
writer.setPageEvent(event);
// step 3
document.open();
// step 4
List<Integer> factors;
for (int i = 2; i < 301; i++) {
factors = getFactors(i);
if (factors.size() == 1) {
document.add(new Paragraph("This is a prime number!"));
}
for (int factor : factors) {
document.add(new Paragraph("Factor: " + factor));
}
event.setHeader(new Phrase(String.format("THE FACTORS OF %s", i)));
document.newPage();
}
// step 5
document.close();
}
In your case, you wouldn't have:
event.setHeader(new Phrase(String.format("THE FACTORS OF %s", i)));
You'd have something like:
event.setHeader(new Phrase(number));
Where number is the number you want to add at the coordinate x = 36, y = 806.

Inserting greater than or equal symbol in to an iText PDF, ie >=

Does anyone know an easy way to include the greater than or equal symbol in an iText PDF document without resorting to custom fonts?
You need to add the unicode for this character. Also make sure that the char is included in the font you use.
document.add( new Paragraph("\u2265"));
Use the below code for the same. It's work for me.
//symbol for greater or equal then
public void process() throws DocumentException, IOException {
String dest = "/home/ashok/ashok/tmp/hello.pdf";
BaseFont bfont = BaseFont.createFont(
"/home/ashok/ashok/fonts/Cardo-Regular.ttf",
BaseFont.IDENTITY_H,
BaseFont.EMBEDDED);
Font font = new Font(bfont, 12);
try {
Document document=new Document();
PdfWriter.getInstance(document,new
FileOutputStream("/home/ashok/ashok/tmp/hello.pdf"));
document.open();
Chunk chunk = new Chunk("\u2265");
Paragraph p = new Paragraph("Mathematical Operators are ",font);
p.add(chunk);
document.add(p);
p = new Paragraph(" ",font);
chunk = new Chunk("\u2264");
p.add(chunk);
document.add(p);
document.close();
} catch (Exception e) {
e.printStackTrace();
}
}

Categories