I am trying to export records from database into pdf using itext pdf library in java..But i am getting following problems in alignment of pdf table inside pdf file..
1.Table is not showing in the full pdf page .It is leaving spaces from left and right of the pdf page.
2.Every page is showing values in half of the page only .Means pdf table is showing in half of the pdf pages..
Here is my code..
Document document = new Document();
PdfWriter.getInstance(document, fos);
PdfPTable table = new PdfPTable(10);
table.setWidthPercentage(100);
table.setSpacingBefore(0f);
table.setSpacingAfter(0f);
PdfPCell cell = new PdfPCell(new Paragraph("DateRange"));
cell.setColspan(10);
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setPadding(5.0f);
cell.setBackgroundColor(new BaseColor(140, 221, 8));
table.addCell(cell);
table.addCell("Calldate");
table.addCell("Calltime");
table.addCell("Source");
table.addCell("DialedNo");
table.addCell("Extension");
table.addCell("Trunk");
table.addCell("Duration");
table.addCell("Calltype");
table.addCell("Callcost");
table.addCell("Site");
while (rs.next()) {
table.addCell(rs.getString("date"));
table.addCell(rs.getString("time"));
table.addCell(rs.getString("source"));
table.addCell(rs.getString("destination"));
table.addCell(rs.getString("extension"));
table.addCell(rs.getString("trunk"));
table.addCell(rs.getString("dur"));
table.addCell(rs.getString("toc"));
table.addCell(rs.getString("callcost"));
table.addCell(rs.getString("Site"));
}
table.setSpacingBefore(5.0f); // Space Before table starts, like margin-top in CSS
table.setSpacingAfter(5.0f); // Space After table starts, like margin-Bottom in CSS
document.open();//PDF document opened........
document.add(Chunk.NEWLINE); //Something like in HTML :-)
document.add(new Paragraph("TechsoftTechnologies.com"));
document.add(new Paragraph("Document Generated On - " + new Date().toString()));
document.add(table);
document.add(Chunk.NEWLINE); //Something like in HTML :-)
document.newPage(); //Opened new page
//In the new page we are going to add list
document.close();
fos.close();
I had to read your question multiple times before I understood that you wanted to suppress the margins. I copy/pasted (and adapted) your example, and I thought I couldn't reproduce your problem because I (and many other developers) am used to the fact that pages have margins.
Anyway, this is my version of your example: FullPageTable and it creates the following PDF: full_page_table.pdf
I've made some minor changes, for instance: it doesn't make sense to pass a ´Paragraph´ as a parameter for a PdfPCell because that Paragraph will be treated as a Phrase, but I think the line you're looking for is:
Document document = new Document(PageSize.A4, 0, 0, 0, 0);
The zeros define the width of the margin, and if I understand your question correctly, you want to suppress those margins.
As for your allegation Every page is showing values in half of the page only .Means pdf table is showing in half of the pdf pages, I think you're causing that yourself by introducing document.newPage(); otherwise your allegation doesn't make sense ;-)
Related
I'm having an issue with PDF box flattening a PDF generated by Adobe Acrobat DC.
The Adobe Acrobat text field I created is absolutely the default text field.
In my example below, I have a PatientName field with the text value "Douglas McDouggelman".
When I flatten the PDF, here's what it looks like:
Anyone know what's up with this bizarre spacing?
It appears that the space + next character are combined. This is what it looks like when you try to select that character.
Code:
try (PDDocument document = PDDocument.load(pdfFormInputStream)) {
PDDocumentCatalog catalog = document.getDocumentCatalog();
PDAcroForm acroForm = catalog.getAcroForm();
acroForm.getField("PatientName").setValue("Douglas McDouggelman");
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
if (flattenPdfs) {
acroForm.flatten();
}
document.save(byteArrayOutputStream);
}
I realized this PDF was from some other group who made it and who knows what they did. So I found the source word document, repeated the creation of the form from Adobe DC, added the fields back to the document, then it was totally fine.
PDF box was not the problem... it was some unknown incorrect step that the person who originally prepared the pdf did.
I have the data containing emoji in database. I want to display in the generated document such as pdf or in excel format.
I am using spring boot application. Please suggest any java library for generating either PDF or excel which supports emoji.
iText supports this. Assuming
your emoji is a unicode character
you use a font that contains the correct glyph for this unicode character
Best way to test this is to try it.
This is how to get started with iText:
https://developers.itextpdf.com/content/itext-7-jump-start-tutorial/installing-itext-7
And this is a small code-snippet that adds text to a document with different fonts:
PdfDocument pdf = new PdfDocument(new PdfWriter(dest));
Document document = new Document(pdf);
PdfFont font = PdfFontFactory.createFont(FontConstants.TIMES_ROMAN);
PdfFont bold = PdfFontFactory.createFont(FontConstants.TIMES_BOLD);
Text title =
new Text("The Strange Case of Dr. Jekyll and Mr. Hyde").setFont(bold);
Text author = new Text("Robert Louis Stevenson").setFont(font);
Paragraph p = new Paragraph().add(title).add(" by ").add(author);
document.add(p);
document.close();
For more information check out the tutorials.
https://developers.itextpdf.com/content/itext-7-building-blocks/chapter-1
I'm working with iText in java to write PDF files. I'm trying to write a paragraph like heading and then text start very after the heading in the same line like
Heading: this a para now ...
Heading is bold and para is in normal text but I'm unable to do this using iText. I tried to use:
fonts[2] = new Font(Font.HELVETICA, 8, Font.BOLD);
Paragraph paranumber = new Paragraph(
fonts[2].getCalculatedLeading(1),
headingText.trim()
+ " ", fonts[0]);
Paragraph para = new Paragraph(
fonts[0].getCalculatedLeading(1), contentText.trim(), fonts[0]);
para.setAlignment(Element.ALIGN_JUSTIFIED);
para.setSpacingAfter(3f);
//Now adding the para to paraNumber that is having the heading and expecting
//that it will be added very after the heading, but this does not show correct
//result, formatting issue.
paranumber.add(para);
mct.addElement(paranumber);
I also tried to create a new paragraph and added both paras(heading para and normal text para) to that new one, but that is also not showing proper result. please see below chunk for that.
Paragraph newPara = new Paragraph();
newPara.add(paranumber);
newPara.add(para);
but this also not show proper formatting.
Or if anyone can advise me to use some other way to create PDF from HTML that will be good too, so that i may rewrite the module to create required PDF. Please advise.
Paragraphs typically use concepts like indentation and increased leading to set them apart visually. They are block level elements, not inline.
It doesn't make sense to add a paragraph inside another paragraph. The added paragraph would typically start on a new line, essentially making it a separate paragraph anyway.
To get a paragraph with different fonts, like your example, you can use Chunks in iText. A Chunk is basically a piece of text with an associated font.
Font fontbold = new Font(BaseFont.createFont(BaseFont.HELVETICA_BOLD,
BaseFont.WINANSI, BaseFont.NOT_EMBEDDED), 12);
Font fontregular = new Font(BaseFont.createFont(BaseFont.HELVETICA,
BaseFont.WINANSI, BaseFont.NOT_EMBEDDED), 12);
Chunk header = new Chunk("Heading: ", fontbold);
Chunk content = new Chunk("this is a para now ...", fontregular);
Paragraph paragraph = new Paragraph();
paragraph.add(header);
paragraph.add(content);
document.add(paragraph);
The result looks like this:
It's not clear from your question and code sample how HTML is involved. I assume you are somehow parsing HTML input and converting the parsed content to PDF using iText Elements. This is a valid approach. Alternatively, you can look into iText XML Worker, which does XHTML (+CSS) to PDF conversion.
I am trying to generate a pdf using Itext.where i need to build a table with header. But i am adding all the content on the page dyamically by iterating the list and adding the cells to the Table ,and finally adding table to the Document after the interation is done.
document.add(table);
My writer and document doesnt show me a updated page number if my content is moved on to the next page,until the table content is added to the document.I need to iterate and build the dynamic table where at the begining of the next page it should have the header of the table.I tried my level best following many approaches.But,I am unable to know when the content is moved on to next page in the middle of the iteration process.PDFWriter is showing me the page number before entering the loop.I need to get the updated pagenumber when ever the tables content goes on to next page.And i dont need this header to be on all pages.I need it only until the table content carries over.Please let me know which is the best way to handle this situation. Thanks
The other answer to this question isn't a real answer, it refers to an answer to another question. If that is actually the answer to this current question, the current question should have been marked as duplicate.
This being said, I think the answer is not entirely correct. I have written an example that produces something like this:
As you can see, there is no header on the first page, there is only a header on the second and third page that says "Table XYZ (Continued)". I even added a footer that says "Continue on next page". As you can see, this footer only appears at the moment the table is split. It isn't present on the last page. This wasn't asked in the question, and it is easy to remove from my code.
You can find the complete code sample here: SimpleTable5
These are the relevant parts:
PdfPTable table = new PdfPTable(5);
table.setWidthPercentage(100);
PdfPCell cell = new PdfPCell(new Phrase("Table XYZ (Continued)"));
cell.setColspan(5);
table.addCell(cell);
cell = new PdfPCell(new Phrase("Continue on next page"));
cell.setColspan(5);
table.addCell(cell);
table.setHeaderRows(2);
table.setFooterRows(1);
table.setSkipFirstHeader(true);
table.setSkipLastFooter(true);
for (int i = 0; i < 350; i++) {
table.addCell(String.valueOf(i+1));
}
document.add(table);
If you only want a header:
PdfPTable table = new PdfPTable(5);
table.setWidthPercentage(100);
PdfPCell cell = new PdfPCell(new Phrase("Table XYZ (Continued)"));
cell.setColspan(5);
table.addCell(cell);
table.setHeaderRows(1);
table.setSkipFirstHeader(true);
for (int i = 0; i < 350; i++) {
table.addCell(String.valueOf(i+1));
}
document.add(table);
The difference with your code, is that you add the following line to avoid that the header appears on the first page:
table.setSkipFirstHeader(true);
This is not mentioned in the answer to Repeat PdfPTable header in all the continuation pages using iText
I try to fill a PDF form with PDFBox and I managed to do it well with a portrait oriented document. But I have a problem when filling a document in landscape mode. The fields are filled up, but the text orientation is not good. It appear vertically like if it was still in portrait but in a rotation of 90 degrees.
Here is my simplified code:
PDDocument pdfDoc = PDDocument.load(MY_FILE);
PDDocumentCatalog docCatalog = pdfDoc.getDocumentCatalog();
PDAcroForm acroForm = docCatalog.getAcroForm();
acroForm.getField("aAddressLine1").setValue("ADDRESS1_HERE");
acroForm.getField("aAddressLine2").setValue("ADDRESS1_HERE");
acroForm.getField("country").setValue("COUNTRY_HERE");
pdfDoc.save(PATH_HERE);
pdfDoc.close();
Did you manage to fill a PDF document in landscape mode?
Thanks for your help.
The short answer
I'm afraid PDFBox does not yet (as of version 1.8.2) allow you to fill in landscape PDFs like the one you provided because it does not seem to query and factor in informations about the page the form field is located on.
The long answer
There are different ways you can define a page to be A4 landscape:
You can define it to have the A4 landscape dimensions directly by means of a media box definition:
/MediaBox [0, 0, 842, 595]
In this case the coordinates of your aAddressLine1 would be
/Rect[23.1711 86.8914 292.121 100.132]
or you can define it to have the A4 portrait dimensions and being rotated by 90° (or 270° obviously):
/MediaBox [0, 0, 595, 842]
/Rotate 90
In this case the coordinates of your aAddressLine1 are
/Rect[86.8914 23.1711 100.132 292.121]
Your example document uses the latter method.
Now PDFBox, when creating an appearance stream for that field, only looks at the rectangle defining the field but ignores the properties of the page. Thus, PDFBox sees a very narrow and very high textfield and fills it in just like that. It is completely unaware that the result will be rotated in a PDF viewer.
What it should have done is to also look at the page the field is located on. If that page has a /Rotate entry, it should create an appearance stream for the field which displays the text rotated in the opposite direction.
Alternatives
In a comment you also asked
Do you know another library I could use if PDFBox can't do what I want?
I have tested the feat with iText 5.4.2:
PdfReader reader = new PdfReader(MY_FILE);
OutputStream os = new FileOutputStream(PATH_HERE);
PdfStamper stamper = new PdfStamper(reader, os);
AcroFields acroFields = stamper.getAcroFields();
acroFields.setField("aAddressLine1", "ADDRESS1_HERE");
acroFields.setField("aAddressLine2", "ADDRESS1_HERE");
stamper.close();
(The free iText version is licensed under the AGPL; you have to decide whether that's ok for your project. There is a commercial license, too, if it's not ok.)
I'm sure other PDF libraries also can do that, it's not too exotic a feature after all...
But I also tested PDF Clown 0.1.3 (trunk version), which did not work either:
File file = new File(MY_FILE);
Document document = file.getDocument();
Form form = document.getForm();
form.getFields().get("aAddressLine1").setValue("ADDRESS1_HERE");
form.getFields().get("aAddressLine2").setValue("ADDRESS1_HERE");
file.save(new java.io.File(PATH_HERE), SerializationModeEnum.Incremental);
file.close();