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.
Related
I have an existing PDF, a simple 2 page form. I need to load the PDF, and in relevant pages in the form, insert text so that it's unique to each person that downloads the PDF.
My initial idea was the load the PDF, and on page one simply overlay the text in the relevant place, however when I try the code below, all this does is add the text to the end of page 1, rather than at the top where I'm telling it to position it.
PdfReader pdfReader = new PdfReader(inputFile);
PdfStamper pdfStamper = new PdfStamper(pdfReader, new FileOutputStream(outputFile));
for(int i=1; i<= pdfReader.getNumberOfPages(); i++){
PdfContentByte content = pdfStamper.getOverContent(i);
if (i == 1) {
//Text over the existing page
BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.EMBEDDED);
content.beginText();
content.setFontAndSize(bf, 18);
content.showTextAligned(PdfContentByte.ALIGN_LEFT, "This is some text " + i, 0, 0, 0);
content.endText();
}
}
Could someone advise where I might be going wrong please?
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?
I am in the process of converting the contents page of my PDF from using page numbers as a hyperlink, to anchors because of a few circumstantial limitations and the linking needs to be more dynamic.
I have omitted outer-loop code, but I am attempting to create a hyperlinked entry in the contents page using the following:
PdfPCell cell = new PdfPCell();
Paragraph p = new Paragraph();
Anchor anchor = new Anchor("page18 link");
anchor.setReference("#page18");
p.add(anchor);
cell.addElement(p);
table.addCell(cell);
Once the contents page has been generated (i.e. all the rows have been added), I then use the writeSelectedRows on the table:
table.writeSelectedRows(0, -1, PageSize.A4.getWidth()*.05f, PageSize.A4.getHeight()-100, stamper.getOverContent(prevSectionPageCount+currentIndexPage+1));
On doing this, I get the following exception:
Cause Exception was: Error in StamperPDFPlugin. null
java.lang.NullPointerException at
com.itextpdf.text.pdf.internal.PdfAnnotationsImp.addPlainAnnotation(PdfAnnotationsImp.java:125)
at com.itextpdf.text.pdf.PdfDocument.localGoto(PdfDocument.java:2115)
at
com.itextpdf.text.pdf.PdfDocument.writeLineToContent(PdfDocument.java:1612)
at com.itextpdf.text.pdf.ColumnText.go(ColumnText.java:1025) at
com.itextpdf.text.pdf.ColumnText.go(ColumnText.java:877) at
com.itextpdf.text.pdf.ColumnText.goComposite(ColumnText.java:1381) at
com.itextpdf.text.pdf.ColumnText.go(ColumnText.java:882) at
com.itextpdf.text.pdf.ColumnText.go(ColumnText.java:877) at
com.itextpdf.text.pdf.ColumnText.go(ColumnText.java:866) at
com.itextpdf.text.pdf.PdfPRow.writeCells(PdfPRow.java:549) at
com.itextpdf.text.pdf.PdfPTable.writeSelectedRows(PdfPTable.java:767)
at
com.itextpdf.text.pdf.PdfPTable.writeSelectedRows(PdfPTable.java:897)
at
com.itextpdf.text.pdf.PdfPTable.writeSelectedRows(PdfPTable.java:845)
at
com.itextpdf.text.pdf.PdfPTable.writeSelectedRows(PdfPTable.java:823)
at
com.ems.rendition.cts.plugin.StamperPDFPlugin.transform(StamperPDFPlugin.java:584)
at
com.ems.rendition.cts.plugin.StamperPDFPlugin.transform(StamperPDFPlugin.java:328)
at
com.ems.rendition.cts.plugin.StamperPDFPlugin.executeProfile(StamperPDFPlugin.java:171)
On seeing the stack trace entry for localGoto, I took out the line anchor.setReference("#18.pdf"); and it completed fine without error (but obviously with the absence of the hyperlinks - only plain text).
What is going wrong here? Am I adding the anchor to the cell incorrectly?
Thanks
Please take a look at LinkInPositionedTable:
public void createPdf(String dest) throws IOException, DocumentException {
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(dest));
document.open();
Anchor target = new Anchor("top");
target.setName("page18");
document.add(target);
PdfPTable table = new PdfPTable(1);
table.setTotalWidth(500);
PdfPCell cell = new PdfPCell();
Paragraph p = new Paragraph();
Anchor anchor = new Anchor("page18 link");
anchor.setReference("#page18");
p.add(anchor);
cell.addElement(p);
table.addCell(cell);
table.writeSelectedRows(0, -1, 36, 700, writer.getDirectContent());
document.close();
}
In this example, I create an anchor with name page18 (although it just refers to the top of the page) and a reference to that anchor added to a PdfPTable using your code snippet.
You can find the result here: link_in_positioned_table.pdf
This works for me, when using iText 5.5.7 (which is the most recent version).
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();
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