iTextPDF - Second PDF file generated displays text from First generated PDF file - java

I am using iTextPDF to generate PDFs getting data from some text inputs.
When I run the application and create first PDF, it is generated as expected.
Then I change some values and generate another, this is where problem arises. The last entry displayed on first PDF is printed on top of the first entry of the second generated PDF.
Not sure why this is happening? Is it being saved to a buffer or something, not really sure.
Here is the code for generating PDF:
public class ExportTicket implements Action{
PdfPCell titleCell = new PdfPCell();
PdfPCell contentCell = new PdfPCell();
public String performAction(HttpServletRequest request) throws PewException {
// CREATING DOCUMENT (ITEXTPDF)
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream("Ticket_" + ticketNo + ".pdf"));
// Fonts
Font headingFont = new Font(Font.FontFamily.UNDEFINED, 10, Font.BOLD, BaseColor.BLACK);
// Open Document to Write
document.open();
// Table Creation
PdfPTable table = new PdfPTable(2);
table.setTotalWidth(200);
table.setWidths(new int[]{ 5, 10 });
table.setHorizontalAlignment(Element.ALIGN_LEFT);
// Add Ticket Number
contentCell.addElement(new Chunk("Ticket Number: " + ticketNo, headingFont));
contentCell.setColspan(2);
table.addCell(contentCell);
// Add table to Document & Close Document
document.add(table)
document.close();
}
}
Please see attached images for output, First one displays first file generation and second one displays 2nd File generation,
First Generated PDF File for Ticket Number: 20170034
Second Generated PDF File for Ticket Number: 20170035

You have strange priorities. You think you should save processing time by creating a PdfPCell only once (in spite of the fact that you always need a new instance), but you waste processing time by creating the font over and over again (while you could easily reuse it).
This is an improved version of your class (I assumed that you get the ticketNo from the request):
public class ExportTicket implements Action{
// Fonts
Font headingFont = new Font(Font.FontFamily.UNDEFINED, 10, Font.BOLD, BaseColor.BLACK);
public String performAction(HttpServletRequest request) throws PewException {
String ticketNo = request.getParameter("ticketNo");
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream("Ticket_" + ticketNo + ".pdf"));
// Open Document to Write
document.open();
// Table Creation
PdfPTable table = new PdfPTable(2);
table.setTotalWidth(200);
table.setWidths(new int[]{ 5, 10 });
table.setHorizontalAlignment(Element.ALIGN_LEFT);
// Add Ticket Number
PdfPCell contentCell = new PdfPCell()
contentCell.addElement(new Chunk("Ticket Number: " + ticketNo, headingFont));
contentCell.setColspan(2);
table.addCell(contentCell);
// Add table to Document & Close Document
document.add(table)
document.close();
}
}

Could it be because you never reset 'contentCell'?
Or is it a value wich is resetted?

Related

Why on splitting table to new page page padding is changed?

Why on splitting table to new page page padding/margins is/are changed?
See what I mean:
Code:
//Some logic to get data.
PdfPTable table = new PdfPTable(cols);
table.setWidthPercentage(100);
table.setHorizontalAlignment(Element.ALIGN_JUSTIFIED_ALL);
Phrase headerText = new Phrase(header);
headerText.setFont(FontFactory.getFont(FontFactory.COURIER_BOLD,14.6f));
PdfPCell headerRow = new PdfPCell(headerText);
headerRow.setColspan(7);
headerRow.setBackgroundColor(BaseColor.LIGHT_GRAY);
headerRow.setHorizontalAlignment(Element.ALIGN_CENTER);
headerRow.setPadding(5);
table.addCell(headerRow);
Set<Integer> keys = data.keySet();
double sum = 0;
for (Integer key : keys) {
//There data is added in table...
}
//generate pdf
Document document = new Document();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
PdfWriter.getInstance(document,byteArrayOutputStream);
document.open();
document.setMargins(5,5,5,5);
document.add(table);
document.add(p);
document.add(paragraph);
document.addCreationDate();
document.addTitle("Tenant activity");
document.close();
logger.debug("Pdf generated");
File f = new File("activity.pdf");
logger.debug("File path: " + f.getAbsolutePath());
How can I set padding for page / margin for table same as on first page, to each page?
This is the wrong order:
document.open();
document.setMargins(5,5,5,5);
This is the right order:
document.setMargins(5,5,5,5);
document.open();
When you open the document, or when you invoke document.newPage(), the next page is initialized, and you can't change page properties such as size or margins of that page.
So if you change the page size or margins, those changes will only be valid on the next page, not on the current page.
Why is this? Well, this is PDF, everything is page based, and once a page has been initialized, you'd get some really weird side-effects if you change those properties while adding content.

iText- Appending arabic text in pdf table cell phrase at different positions in a page

I want to make a pdf report with English and Arabic texts. I have many tables/phrases across the page. I want to display Arabic text also along with English. I have seen the Arabic example in iText doxument also, using ColumnText. I couldn't help myself with that. My doubt is how to set canvas.setSimpleColumn(36, 750, 559, 780), the arguments in this method for tables/phrases at different positions. I have referred below questions also.Still I have issues.
Writing Arabic in pdf using itext,
http://developers.itextpdf.com/examples/font-examples/language-specific-exampleshe
Below is my code..
private static final String ARABIC = "\u0627\u0644\u0633\u0639\u0631 \u0627\u0644\u0627\u062c\u0645\u0627\u0644\u064a";
private static final String FONT = "resources/fonts/ARIALUNI.TTF";
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("test.pdf"));
document.open();
Font f = FontFactory.getFont(FONT, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
PdfPTable table = new PdfPTable(3);
Phrase phrase = new Phrase();
Chunk chunk = new Chunk("test value", inlineFont);
phrase.add(chunk);
// I want to add Arabic text also here..but direction is not //correct.also coming as single alphabets
p.add(new Chunk(ARABIC, f));
PdfPCell cell1 = new PdfPCell(phrase);
cell1.setFixedHeight(50f);
table.addCell(cell1);
document.add(table);
document.close();
Your code is kind of sloppy.
For example:
you define a PdfPTable with 3 columns, but you only add a single cell. That table will never be rendered.
you define a Phrase with name phrase, but later in your code you use p.add(...). There is no variable with name p in your code.
...
This lack of respect for the StackOverflow reader can result in not getting an answer, because you are expecting the reader not only to fix the actual problem –not being able to use English and Arabic text in a single PdfPCell—, but also to fix all the other (avoidable) errors in your code.
This is a working example:
public static final String FONT = "resources/fonts/NotoNaskhArabic-Regular.ttf";
public static final String ARABIC = "\u0627\u0644\u0633\u0639\u0631 \u0627\u0644\u0627\u062c\u0645\u0627\u0644\u064a";
public void createPdf(String dest) throws IOException, DocumentException {
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream(dest));
document.open();
Font f = FontFactory.getFont(FONT, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
PdfPTable table = new PdfPTable(1);
Phrase phrase = new Phrase();
Chunk chunk = new Chunk("test value");
phrase.add(chunk);
phrase.add(new Chunk(ARABIC, f));
PdfPCell cell = new PdfPCell(phrase);
cell.setUseDescender(true);
cell.setRunDirection(PdfWriter.RUN_DIRECTION_RTL);
table.addCell(cell);
document.add(table);
document.close();
}
The result looks like this:
As you can see, both the English and the Arabic text can be read fine. You may be surprised by the alignment and the order of the text. As we are working in the Right-to-Left writing system, left and right are switched. By default, text is left aligned, but as soon as we introduce the RTL run direction, this changes to right aligned.
In your code, you add the English text first, followed by the Arabic text. Text in Arabic is read from right to left. That's why you see the English text to the right, and why the Arabic text is added to the left of the English text.
All of this has been improved in iText 7. iText 7 has an extra pdfCalligraph module that takes care of other writing systems in a transparent way.

How to prevent first chapter on page two when table in header of pdf generated with iText?

When having a PdfPTable in the header of the document, the first Chapter added gets added too page two, leaving the first page blank. If having just text in the header all works fine (see the out commented line in code sample). Am I doing something wrong or are there a workaround for this problem? I'm using iText-2.1.7.
So to be clear: The code below generates a pdf with one empty page as the first page and if going with the out commented row instead there is no empty page first.
Another thing is that if having a table in the header the generated header gets no height making the text of the document placed over the header table. That one I can work around. But it could perhaps give some help in understanding what's happening...
Document vDocument = new Document();
PdfWriter.getInstance(vDocument, new FileOutputStream("C:/Test.pdf"));
PdfPTable vTable = new PdfPTable(1);
vTable.addCell(new PdfPCell (new Phrase("Header text")));
Phrase vPhr = new Phrase();
vPhr.add(vTable);
HeaderFooter vHeaderFooter = new HeaderFooter(vPhr, false);
// HeaderFooter vHeaderFooter = new HeaderFooter(new Phrase("Header text"), false);
vDocument.setHeader(vHeaderFooter);
vDocument.open();
vDocument.add(new Chapter("New Chapter", 0));
for (int i=0; i<1000; i++) {
vDocument.add(new Paragraph(" TEXT " + i));
}
vDocument.close();

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.

How to execute a function at a specified time set dynamically by user in java

I have a function in java which contains the code to generate the pdf file and save into the system local disk.Now as per my requirement i have to make a jsp page which contains a form from where user can dynamically set the date and time on which he needs pdf to be generated.Now pdf should be generated as per the user input given and user input is dynamic in nature it can be changed..
For example ..
Suppose user has set pdf to be created on 15 of every month at 10:00 am..Then this time it should generate the pdf on 15 at 10:00a am..
Now if his requirement change he can set it to 10 of every month at 10:00 am ..and so on..
I am not able to get the way to proceed..
Here is my pdf generation code in POJO file..
OutputStream file = new FileOutputStream(new File("D://timer.pdf"));
Document document = new Document();
PdfWriter.getInstance(document, file);
//Inserting Table in PDF
PdfPTable table = new PdfPTable(3);
PdfPCell cell = new PdfPCell(new Paragraph("Java4s.com"));
cell.setColspan(3);
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setPadding(10.0f);
cell.setBackgroundColor(new BaseColor(140, 221, 8));
table.addCell(cell);
table.addCell("Name");
table.addCell("Address");
table.addCell("Country");
table.addCell("Java4s");
table.addCell("NC");
table.addCell("United States");
table.setSpacingBefore(30.0f); // Space Before table starts, like margin-top in CSS
table.setSpacingAfter(30.0f); // Space After table starts, like margin-Bottom in CSS
//Inserting List in PDF
List list = new List(true, 30);
list.add(new ListItem("Java4s"));
list.add(new ListItem("Php4s"));
list.add(new ListItem("Some Thing..."));
//Text formating in PDF
Chunk chunk = new Chunk("Welecome To Java4s Programming Blog...");
chunk.setUnderline(+1f, -2f);//1st co-ordinate is for line width,2nd is space between
Chunk chunk1 = new Chunk("Php4s.com");
chunk1.setUnderline(+4f, -8f);
chunk1.setBackground(new BaseColor(17, 46, 193));
//Now Insert Every Thing Into PDF Document
document.open();//PDF document opened........
document.add(Chunk.NEWLINE); //Something like in HTML :-)
document.add(new Paragraph("Dear Java4s.com"));
document.add(new Paragraph("Document Generated On - " + new Date().toString()));
document.add(table);
document.add(chunk);
document.add(chunk1);
document.add(Chunk.NEWLINE); //Something like in HTML :-)
document.newPage(); //Opened new page
document.add(list); //In the new page we are going to add list
document.close();
file.close();
System.out.println("Pdf created successfully..");
Thanks in advance..
Use the java.util.Timer class. There is a lot of example on this site.
As someone mentioned in the comments that going with ScheduledExecutorService would be better. (The javadoc already has a tutorial on that subject.)
You can use Timer and Task classes which are of java

Categories