Issue with Adding TextField to PdfPCell - java

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));

Related

iText library exception throwing on adding blank Cell with space

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.

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.

Align Paragraph at the center of the page

I am using itext to generate pdf file. I want to align my title in the middle of the page. Presently i am using like this
Paragraph preface = new Paragraph();
for (int i = 0; i < 10; i++) {
preface.add(new Paragraph(" "));
}
Is it correct or is there any another best way to do this.
Use Paragraph#setAlignment(int) :
Paragraph preface = new Paragraph();
preface.setAlignment(Element.ALIGN_CENTER);
See the ALIGN_* constants in the Element interface for more possible values.
Not sure if this is an old version, but for PdfWriter these methods weren't there. Instead I used:
Paragraph p = new Paragraph("This too shall pass");
p.Alignment = Element.ALIGN_CENTER;
public static final String DEST = "results/tables/centered_text.pdf";
public static void main(String[] args) throws IOException, DocumentException {
File file = new File(DEST);
file.getParentFile().mkdirs();
new CenteredTextInCell().createPdf(DEST);
}
public void createPdf(String dest) throws IOException, DocumentException {
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream(dest));
document.open();
Font font = new Font(FontFamily.HELVETICA, 12, Font.BOLD);
Paragraph para = new Paragraph("Test", font);
para.setLeading(0, 1);
PdfPTable table = new PdfPTable(1);
table.setWidthPercentage(100);
PdfPCell cell = new PdfPCell();
cell.setMinimumHeight(50);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.addElement(para);
table.addCell(cell);
document.add(table);
document.close();
}
If you are looking for a solution to Itext7 then you can use the method setTextAlignment(...).
Example:
Paragraph preface = new Paragraph();
// add text
preface.setTextAlignment(TextAlignment.CENTER);
If any one is looking for .NET/C# version, below is how I achieved the CENTER alignment.
I am using iText7 library for .NET/C#, and I achieved this using :
Paragraph preface = new Paragraph();
preface.SetTextAlignment(iText.Layout.Properties.TextAlignment.CENTER);
This is what worked for me (itext 5.0.5 ):
Paragraph p3= new Paragraph("Hello" );
p3.setAlignment(Element.ALIGN_CENTER);
I have searching solution for this to align PdfPCell text into right and also center. After modify and change the code sequence it is work.
This code is not work to align text to center.
PdfPCell cell = new PdfPCell();
cell.addElement(new Phrase("Testing Page");
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
table.addCell(cell);
After modifying code with this , it is working now.
Paragraph p = new Paragraph("Testing Page");
//Pass Paragraph object into PdfPCell
PdfPCell cell = new PdfPCell(p);
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
table.addCell(cell);

How to set underline to PdfContentByte -- iText

I'm having trouble to set underline and overline by using PdfContentByte in iText. I want to set underline to all field in sectionArea == 1 || section Area == 3 as mentioned in getFontForFormat. So far i can only do bold style and i need it to be underlined and overlined too.
Here is the code:
public void doOutputField(Field field) {
String fieldAsString = field.toString();
BaseFont baseFont = getFontForFormat(field);
float fontSize = 11;
Point bottomLeft = bottomLeftOfField(field, 11, baseFont);
int align;
align = PdfContentByte.ALIGN_LEFT;
//PdfContentByte content
content.beginText();
content.setFontAndSize(baseFont, fontSize);
content.setColorFill(Color.BLACK);
double lineHeight = field.getOutputHeight();
content.showTextAligned(align, fieldAsString, (float) bottomLeft.x,
(float) bottomLeft.y, 0f);
bottomLeft.y -= lineHeight;
content.endText();
}
public BaseFont getFontForFormat(Field field) {
try {
if (field.getSection().getArea().getArea() == 1
|| field.getSection().getArea().getArea() == 3) {
BaseFont bf = BaseFont.createFont(BaseFont.TIMES_BOLD,
BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
return bf;
} else {
BaseFont bf = BaseFont.createFont("Times-Roman",
BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
return bf;
}
} catch (Exception e) {
}
return null;
}
Thanks in advance
Edit (Solved by Bruno Lowagie):
This problem can be solved by utilizing ColumnText.
if (field.getSection().getArea().getArea() == 1
|| field.getSection().getArea().getArea() == 3) {
Chunk chunk = new Chunk(fieldAsString);
chunk.setUnderline(+1f, -2f);
if (field.getSection().getArea().getArea() == 3) {
chunk.setUnderline(+1f, (float) field.getBoundHeight());
}
Font font = new Font();
font.setFamily("Times Roman");
font.setStyle(Font.BOLD);
font.setSize((float) 11);
chunk.setFont(font);
Paragraph p = new Paragraph();
p.add(chunk);
ColumnText ct = new ColumnText(content);
ct.setSimpleColumn(p, (float)bottomLeft.x, (float)bottomLeft.y,
(float)field.getBoundWidth() + (float)bottomLeft.x,
(float)field.getBoundHeight() + (float)bottomLeft.y,
(float)lineHeight, align);
try {
ct.go();
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Thanks
You're making it yourself difficult by using PdfContentByte.showTextAligned(). Is there any reason why you don't want to use ColumnText?
With PdfContentByte, you have to handle the text state —beginText() and endText()—, the font —setFontAndSize()—, and you can only add String values. If you want to add lines (e.g. to underline), you need moveTo(), lineTo(), stroke() operations. These operators need coordinates, so you'll need to measure the size of the line using the BaseFont in combination with the String and the font size. There's some math involved.
If you use ColumnText, you have the option of adding one line at a time using ColumnText.showTextAligned(). Or you can define a column using setSimpleColumn() and let iText take care of distributing the text over different lines. In both cases, you don't have to worry about handling the text state, nor about the font and size. ColumnText accepts Phrase objects, and these objects consists of Chunk objects for which you can define underline and overline values. In this case, iText does all the math for you.

jxl.WritableCellFormat definition

Is it possible to create one jxl.WritableCellFormat attribute which contains Font, NumberFormat, BackgroundColor and Border?
This works:
public static final NumberFormat numberformatter = new NumberFormat("#,###0.00");
public static final WritableFont defaultfont = new WritableFont(WritableFont.TAHOMA, 10);
public static final WritableCellFormat numberCellFormat = new WritableCellFormat(defaultfont, numberformatter); '
but I can't get borders and colors, thought same kind of cell is needed many times when creating sheets.
You can set the border and background via the WritableCellFormat.setBorder() and WritableCellFormat.setBackground() methods after having instanciated your cell.
You can see the API there.
If you have to do that a lot, you can make a helper function like this :
public static makeCell(NumberFormat format, WritableFont font, Color backgrd, Border border){
final WritableCellFormat result = new WritableCellFormat(defaultfont, numberformatter);
result.setBorder(border);
result.setBackground(backgrd);
return result;
}
You Can do this by 2 steps
Create a WritableFont
Create a WritableCellFormat with WritableFont,NumberFormats as a parameter
Attaching the code snippet
int fontSize = 8;
WritableFont wfontStatus = new WritableFont(WritableFont.ARIAL, fontSize);
wfontStatus.setColour(Colour.BLACK);
wfontStatus.setBoldStyle(WritableFont.BOLD);
WritableCellFormat fCellstatus = new WritableCellFormat(wfontStatus, NumberFormats.TEXT); // You can use any NumberFormats I have used TEXT for my requirement
try {
fCellstatus.setWrap(true);
fCellstatus.setBorder(Border.ALL,BorderLineStyle.THIN);
fCellstatus.setAlignment(Alignment.CENTRE);
fCellstatus.setBackground(Colour.YELLOW);
}
catch (WriteException e) {
e.printStackTrace();
}

Categories