Itextpdf adding a caption under an image - java

Is it possible in the same cell to add an image and it's caption ?
I've tried with a paragraph but with no luck.
Image img = null;
try {
img = Image.getInstance(Base64.decode(val));
} catch (Exception e) {
throw new Exception("Problem in decoding image");
}
Paragraph paragraph = new Paragraph("this is a Caption");
valueCell.setImage(img);
valueCell.addElement(paragraph);
Create a subtable with two cell, one with the image and the other one with the caption I think Is gonna mess with some logic used in this table that is composed of key/value pair cells.

I resolved using the addElement method.
PdfPCell valueCell = new PdfPCell();
Paragraph paragraph = new Paragraph("this is a Caption");
valueCell.addElement(img);
valueCell.addElement(paragraph);

Related

OpenPDF: Table not located in footer

When I add a table to the footer of the page, the footer resizes to the right size, however, the table does not stay within this footer, however it locates itself at the top of the page.
I have created a test scenario to illustrate what I mean.
public class TestClass {
public static void main(String[] args) {
try {
Document document = new Document(PageSize.A4);
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("fail.pdf"));
PdfPTable table = new PdfPTable(2);
table.setWidthPercentage(100);
table.addCell(new PdfPCell(new Paragraph("CONTENT")));
table.addCell(new PdfPCell(new Paragraph("CONTENT")));
Paragraph footerParagraph = new Paragraph();
footerParagraph.add(table);
HeaderFooter footer = new HeaderFooter(footerParagraph, false);
footer.setAlignment(Element.ALIGN_CENTER);
document.setFooter(footer);
document.open();
document.add(new Paragraph("Hello World"));
document.close();
} catch (Exception ex) {
System.out.println(ex);
}
}
}
In this example the the footer has the correct size for the table:
However as mentioned the table is not located at the bottom, but at the top:
You need to know the page size and calculate from there.
You can use
showTextAligned(ELEMENT.ALIGN_BOTTOM)
This was a bug with OpenPDF, which should have been fixed now.
https://github.com/LibrePDF/OpenPDF/issues/373

align cell in itextpdf java

I'm using itextpdf to create my pdf with tables. While creating table i need to align some column to right, but its now working properly , can you guys help me.
I tried googling too, but didt work out for me. im using itextpdf 5.4 version.
public void generateMonthlySubReport(String[][] StrArray,String dueMonth,int Amt){
try {
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream(MON_SUB_FILE));
PdfPTable pt = new PdfPTable(StrArray[0].length);
pt.setTotalWidth(new float[]{ 55,120,360,140});
pt.setLockedWidth(true);
PdfPCell pcell = new PdfPCell();
document.open();
addKvLogo(document);
Chunk glue = new Chunk(new VerticalPositionMark());
Paragraph p1 = new Paragraph("Monthly Subscription Report",catFont);
p1.setAlignment(Element.ALIGN_CENTER);
addEmptyLine(p1,2);
document.add(p1);
Paragraph p2 = new Paragraph("Month : "+dueMonth);
p2.add(new Chunk(glue));
p2.add("Per Member : Rs."+Amt);
addEmptyLine(p2,2);
document.add(p2);
for(int i=0;i<StrArray.length;i++){
for(int j=0;j<StrArray[i].length;j++){
pcell = new PdfPCell();
if(i==0){
pcell.setBackgroundColor(BaseColor.LIGHT_GRAY);
}else{
pcell.setBackgroundColor(BaseColor.WHITE);
}
pcell.setUseAscender(true);
pcell.setMinimumHeight(22);
pcell.setPaddingLeft(10);
pcell.setHorizontalAlignment(Element.ALIGN_RIGHT);
pcell.setVerticalAlignment(Element.ALIGN_MIDDLE);
pcell.addElement(new Phrase(StrArray[i][j]));
pt.addCell(pcell);
}
}
pt.setTotalWidth(PageSize.A4.getWidth()-(document.leftMargin()*2));
pt.setLockedWidth(true);
document.add(pt);
document.close();
} catch (Exception e) {
e.printStackTrace();
}
} `
You are mixing text mode with composite mode.
This is text mode:
pcell = new PdfPCell(new Phrase(StrArray[i][j]));
pcell.setHorizontalAlignment(Element.ALIGN_RIGHT);
In this case, the alignment of the cell will be used for the alignment of the text.
This is composite mode:
pcell = new PdfPCell();
Paragraph p = new Parapgraph(StrArray[i][j])
p.setAlignment(Element.ALIGN_RIGHT);
pcell.addElement(p);
In this case, the alignment of the cell is ignored, in favor of the alignment of the element.
How to know the difference between text mode and composite mode?
iText automatically switches from text mode to composite mode in a PdfPCell the moment you use the addElement() method. As soon as you do this, some properties defined at the cell level are ignored. This explains why the content you are adding isn't right-aligned.

Use different Table Header on first page

I'm using iText and create a dynamic table which has a a reoccurring header in the method createTabularHeader:
PdfPTable table = new PdfPTable(6);
// fill it with some basic information
table.setHeaderRows(1);
Yet on the first page I would like to display different information. (but the table structure/size remains the same)
Due to the dynamic content which is obtained in a different method I can't say when a new page starts.
I tried with the most primitive variant - just adding a white rectangle over the text and insert the different text. As it's just on the first page all I have to do is creating that rectangle between both methods.
But the white rectangle doesn't have any opacity and can' cover anything.
Yet by trying around I found the method writer.getDirectContent().setColorStroke(BaseColor.WHITE); which set the text to white. Later I just set the BaseColor of my cells manually to black. But the even though the new text is applied after the calling of my createTabularHeader-method its layer is under the layer of the original text and the letters are covering the new text partly.
Using the answer to How to insert invisible text into a PDF? brought me to the idea of using myPdfContentByte.setTextRenderMode(PdfContentByte.TEXT_RENDER_MODE_INVISIBLE); was not so helpful as it resets only on the 2nd page regardless what I do and the regular text on the first page stays invisible.
I'm unable to find a proper solution... How can the table-header be modified only on the first page?
The solution is not really nice, but works... and as some sort of bonus I want to add how you can modify the indentions on the first page.
public void createPdf() {
document = new Document();
try {
PdfWriter writer = PDFHead.getWriter(document);
//If it's a letter we have a different indention on the top
if (letterPDF) {
document.setMargins(36, 36, 100, 36);
} else {
document.setMargins(36, 36, 36, 36);
}
document.open();
document.add(createTabularContent());
document.close();
} catch (DocumentException | FileNotFoundException ex) {
try {
document = new Document();
PdfWriter.getInstance(document, new FileOutputStream(FILENAME));
document.open();
document.add(new Phrase(ex.getLocalizedMessage()));
document.close();
Logger.getLogger(Etikette.class.getName()).log(Level.SEVERE, null, ex);
} catch (FileNotFoundException | DocumentException ex1) {
Logger.getLogger(Etikette.class.getName()).log(Level.SEVERE, null, ex1);
}
}
}
The PDFHead is used to create a regular header (the one which appears on every page, not only on pages with the table):
public static PdfWriter getWriter(Document document) throws FileNotFoundException, DocumentException {
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(filename));
HeaderFooter event = new HeaderFooter("Ing. Mario J. Schwaiger", type + " " + DDMMYYYY.format(new java.util.Date()), 835, isLetterPDF(), customerNumber);
writer.setBoxSize("art", new Rectangle(36, 54, 559, 788));
writer.setPageEvent(event);
return writer;
}
And in that HeaderFooter-Event I use the fact the function is called after the PDF is basically created (for the page number for instance):
#Override
public void onEndPage(PdfWriter writer, Document document) {
if (isLetter) {
//That's only for the first page, apparently 1 is too late
//I'm open for improvements but that works fine for me
if (writer.getPageNumber() == 0) {
//If it's a letter we use the different margins
document.setMargins(36, 36, 100, 36);
}
if (writer.getPageNumber() == 1) {
PdfContentByte canvas = writer.getDirectContent();
float llx = 460;
float lly = 742;
float urx = 36;
float ury = 607;
//As I add the rectangle in the event here it's
//drawn over the table-header. Seems the tableheader
//is rendered afterwards
Rectangle rect1 = new Rectangle(llx, lly, urx, ury);
rect1.setBackgroundColor(BaseColor.WHITE);
rect1.setBorder(Rectangle.NO_BORDER);
rect1.setBorderWidth(1);
canvas.rectangle(rect1);
ColumnText ct = new ColumnText(canvas);
ct.setSimpleColumn(rect1);
PdfPTable minitable = new PdfPTable(1);
PdfPCell cell = PDFKopf.getKundenCol(PDFHeader.getCustomer(customerNumber));
cell.setBorder(Rectangle.NO_BORDER);
minitable.addCell(cell);
//A single cell is not accepted as an "Element"
//But a table including only a single cell is
ct.addElement(minitable);
try {
ct.go();
} catch (DocumentException ex) {
Logger.getLogger(HeaderFooter.class.getName()).log(Level.SEVERE, null, ex);
}
//In any other case we reset the margins back to normal
//This could be solved in a more intelligent way, feel free
} else {
document.setMargins(36, 36, 36, 36);
}
}
//The regular header of any page...
PdfPTable table = new PdfPTable(4);
try {
table.setWidths(new int[]{16, 16, 16, 2});
table.setWidthPercentage(100);
table.setTotalWidth(527);
table.setLockedWidth(true);
table.getDefaultCell().setFixedHeight(20);
table.getDefaultCell().setBorder(Rectangle.BOTTOM);
table.addCell(header);
PdfPCell cell;
cell = new PdfPCell(new Phrase(mittelteil));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setBorder(Rectangle.BOTTOM);
table.addCell(cell);
table.getDefaultCell().setHorizontalAlignment(Element.ALIGN_RIGHT);
table.addCell(String.format("Page %d of ", writer.getPageNumber()));
cell = new PdfPCell(Image.getInstance(total));
cell.setBorder(Rectangle.BOTTOM);
table.addCell(cell);
table.writeSelectedRows(0, -1, 34, y, writer.getDirectContent());
} catch (DocumentException de) {
throw new ExceptionConverter(de);
}
}

IText : Add an image on a header with an absolute position

I want to place a header on each page of my PDF.
The text part of the header is done but I can't find a way to place an image.
public static class Header extends PdfPageEventHelper {
public void onEndPage(PdfWriter writer, Document document) {
try{
PdfContentByte cb = writer.getDirectContent();
/*
Some code to place my text in the header
*/
Image imgSoc = Image.getInstance("C:\\...\\Logo.jpg");
imgSoc.scaleToFit(110,110);
imgSoc.setAbsolutePosition(390, 720);
ColumnText ct = new ColumnText(cb);
ct.addText(new Chunk(imgSoc,0,0));
ct.go();
}catch(Exception e){
e.printStackTrace();
}
}
}
I'm not really sure I'm doing this the right way.
There already are two answers using tables.
Tables can be very helpful to create a dynamic layout of different header parts (document title, document version, page number, logo, ...).
But if you don't need that, already have everything in place like the OP has, you can simply add the image at a fixed position with a fixed size:
public static class Header extends PdfPageEventHelper {
public void onEndPage(PdfWriter writer, Document document) {
try
{
PdfContentByte cb = writer.getDirectContent();
/*
Some code to place some text in the header
*/
Image imgSoc = Image.getInstance("C:\\...\\Logo.jpg");
imgSoc.scaleToFit(110,110);
imgSoc.setAbsolutePosition(390, 720);
cb.addImage(imgSoc);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
PS: If you really use the same logo on all pages, you had better read the image file into an Image instance only once (e.g. in the constructor or onOpenDocument), hold that instance in a variable and re-use it again and again. This way you include the image data only once in the PDF.
A way to achieve this is to create the header as a table:
PdfPTable table = new PdfPTable(1);
Image imgSoc = Image.getInstance("C:\\...\\Logo.jpg");
imgSoc.scaleToFit(110,110);
PdfPCell cell = new PdfPCell(imgSoc , true);
cell.setBorder(0);
table.addCell(cell);
float[] columnWidths = new float[] { 100};
table.setWidthPercentage(100f);
table.setWidths(columnWidths);
ColumnText ct = new ColumnText(cb);
ct.addElement(table);
ct.setSimpleColumn(36, 0, 559, 806); //Position goes here
ct.go();
You could use iText Table in such a way that , you can show your logo either left or right depending upon the user choice.
Chunk header = new Chunk("your header text", headerFont);
Image logo = Image.getInstance("../../..");
// your image path
logo.scaleAbsolute(80f, 80f);
logo.scalePercent(100);
table = new PdfPTable(3);
table.setWidthPercentage(100);
PdfPCell detailCell = new PdfPCell(new Phrase(header));
detailCell.setBorder(Rectangle.NO_BORDER);
detailCell.setHorizontalAlignment(alignment);
detailCell.setVerticalAlignment(Element.ALIGN_TOP);
PdfPCell logoRightCell = new PdfPCell();
logoRightCell.setFixedHeight(80);
logoRightCell.setBorder(Rectangle.NO_BORDER);
logoRightCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
PdfPCell logoLeftCell = new PdfPCell();
logoLeftCell.setFixedHeight(80);
logoLeftCell.setBorder(Rectangle.NO_BORDER);
logoLeftCell.setHorizontalAlignment(Element.ALIGN_LEFT);
if (true) {
String logoAlign = "left";
if (logoAlign.compareTo("Left") == 0) {
logo.setAlignment(Element.ALIGN_LEFT);
logoLeftCell.addElement(logo);
} else {
logo.setAlignment(Element.ALIGN_RIGHT);
logoRightCell.addElement(logo);
}
}
String headerAlign = "Center";
if (headerAlign.compareTo("Center") == 0) {
table.setWidths(new int[] { 2, 7, 2 });
table.addCell(logoLeftCell);
table.addCell(detailCell);
table.addCell(logoRightCell);
} else if (headerAlign.compareTo("Left") == 0) {
table.setWidths(new int[] { 7, 2, 2 });
table.addCell(detailCell);
table.addCell(logoLeftCell);
table.addCell(logoRightCell);
} else {
table.setWidths(new int[] { 2, 2, 7 });
table.addCell(logoLeftCell);
table.addCell(logoRightCell);
table.addCell(detailCell);
}
//
table.setTotalWidth(document.getPageSize().getWidth()
- document.leftMargin() - document.rightMargin());
table.writeSelectedRows(0, -1, document.leftMargin(), document
.getPageSize().getHeight() - document.topMargin() + 20,
writer.getDirectContent());
}
document.add(table);

Setting font to paragraph in pdf using iText java

I was trying to create pdf using iText in java. And am failed when I tried to set font to paragraph. The exact problem is only the font size is not getting applied. I used the following code.
StringReader strReader = new StringReader(content);
arrList = HTMLWorker.parseToList(strReader, null);
Font font = new Font(BaseFont.createFont("c:\\ARIALUN0.ttf", BaseFont.IDENTITY_H,
BaseFont.EMBEDDED), 6, Font.BOLD, new Color(0, 0, 0));
Paragraph para = new Paragraph();
para.setFont(font);
for (int k = 0; k < arrList.size(); ++k) {
para.add((com.lowagie.text.Element)arrList.get(k));
}
Can anyone help me to find a solution?
//use this code.Sometimes setfont() willnot work with Paragraph
try
{
FileOutputStream out=new FileOutputStream(name);
Document doc=new Document();
PdfWriter.getInstance(doc, out);
doc.open();
Font f=new Font(FontFamily.TIMES_ROMAN,50.0f,Font.UNDERLINE,BaseColor.RED);
Paragraph p=new Paragraph("New PdF",f);
p.setAlignment(Paragraph.ALIGN_CENTER);
doc.add(p);
doc.close();
}
catch(Exception e)
{
System.out.println(e);
}
}
I was pretty confused and almost posted the wrong answer to this.
Your paragraph is having its font set correctly. Just try inserting a String to see.
Your problem lies in your for loop. To the paragraph, you're adding a Element objects. An Element is composed of Chunk objects, which each have their own Font data.
Try setting the Font of the Chunks in your Elements when they are instantiated. That should solve your problem.
Try this ,It will save the style of the text:
Paragraph _p = new Paragraph();
_p.setFont(regular);
ArrayList htmlObjs = (ArrayList) HTMLWorker.parseToList(new StringReader(text_), null);
for (int k = 0; k < htmlObjs.size(); ++k)
{
ArrayList<Chunk> chunk = ((Paragraph) htmlObjs.get(k)).getChunks();
for (int l = 0; l < chunk.size(); l++)
{
Font _original_chunk_font = chunk.get(l).getFont();
Font _newchunk_font = new Font(unicode);
_newchunk_font.setFamily(_original_chunk_font.getFamilyname());
_newchunk_font.setStyle(_original_chunk_font.getStyle());
_newchunk_font.setSize(_original_chunk_font.getSize());
_newchunk_font.setColor(_original_chunk_font.getColor());
chunk.get(l).setFont(_newchunk_font);
}
_p.add((Element)htmlObjs.get(k));
}
I'm new in this.
but i'm showing u a simplest way to set font to
paragraph.
document.open();
document.add(new Paragraph(" Hello World ", FontFactory.getFont(FontFactory.TIMES_ROMAN,18, Font.BOLD, BaseColor.BLACK)));
document.close();
By this way i'm changing the font, font size , color etc.
this worked for me..
Happy coding..
For adding Font to itextpdf Paragraph you can simply use a Chunk then you can set Font to Chunk add that Chunk to Paragraph afterwards.
Example:
Font f3 = new Font(Font.FontFamily.TIMES_ROMAN, 18.0f, Font.BOLD, BaseColor.BLACK);
Chunk c3 = new Chunk("INVOICE", f3);
c3.setBackground(BaseColor.WHITE);
Paragraph p3 = new Paragraph(c3);
p3.setAlignment(Element.ALIGN_CENTER);

Categories

Resources