Setting Alignment for each Element when more than one Element added to a PDFPcell - itext

In a table, I have a few cells that contain multiple elements. For Example, to indicate address , the cell may contain a phrase containing an "ADDRESS:" header Chunk followed by another chunk containing the actual address:
FROM: -- Chunk 1 in Phrase
123 Main St, Some City, ST -- Chunk 2 in Phrase
As of now, to align the cell contents, I am using the following code in the PDFPcell:
cell.VerticalAlignment = Element.ALIGN_MIDDLE;
However, this aligns all of the cell contents to the middle of the cell. If I want to put Chunk 1 at TOP_LEFT and Chunk 2 at BOTTOM_LEFT, is it possible to achieve it with iTextSharp? Essentially, I am looking for a way to align various elements within a cell at different locations.

Unfortunately the only way to do what you want is to add a sub-table in place of your multiple chunks.
t.AddCell("Row 1");
PdfPTable subTable = new PdfPTable(1);
subTable.DefaultCell.VerticalAlignment = Element.ALIGN_TOP;
subTable.DefaultCell.HorizontalAlignment = Element.ALIGN_LEFT;
subTable.AddCell("Top Align");
subTable.DefaultCell.VerticalAlignment = Element.ALIGN_BOTTOM;
subTable.DefaultCell.HorizontalAlignment = Element.ALIGN_RIGHT;
subTable.AddCell("Bottom Align");
t.AddCell(subTable);
doc.Add(t);

Related

iText 7 - text overlay in a table, how to span over all possible columns

there is a picture visualizing my problem.
I have a table with let's say 5 columns and 5 rows. The first row and first column has a long text. The text won't fit in to the cell but I want to show the entire text in a line, spanning all the following columns.
It is not a real colspan as the column-borders should still be visible. So it's more an overlay.
I am experimenting with the example "Fit text in cell" with the custom cell renderer but I don't really understand the different occupied areas, boxes and the dimensions coming with it.
Not to say that the dimension and positioning thing in iText is not really intuitive.
I appreciate any help.
Thanks.
So you want something like this ?
C# example
//Create a table with 5 columns
var table = new Table(new float[] { 3,3,3,3,3}).SetWidth(UnitValue.CreatePercentValue(100)).SetFixedLayout();
// Creat the cell with the long text
Cell cell = new Cell(1, 5).Add(new Paragraph("Long text that spans over the 5 Columns"));
//Add the top row 5 cells
table.AddCell("Column 1 text")
table.AddCell("Column 2 text")
table.AddCell("Column 3 text")
table.AddCell("Column 4 text")
table.AddCell("Column 5 text")
//Add the long text
table.AddCell(cell);

Footer image printed twice when printing certificates in iText

When we print certificate all most print in certificate but footer image is printing twice. I am using Pdfptable for printing footer image.
table = new PdfPTable(1);
int footerWidth[] = {100};
table.setWidths(footerWidth);
table.setWidthPercentage(100);
Image image2 = Image.getInstance("footerImage.jpg");
cell = new PdfPCell(image2,true);
cell.setBorder(0);
table.setTotalWidth(document.getPageSize().width()-document.leftMargin()-document.rightMargin());
table.addCell(cell);
//write the footer
table.writeSelectedRows(0, -1, document.leftMargin(), table.getTotalHeight()+document.bottomMargin(), writer.getDirectContent());
EventLog.write(appName,"done adding footer",logFile);
document.add(table);
Your table is added twice because you add it twice.
You add it a first time when you use writeSelectedRows():
table.writeSelectedRows(0, -1, document.leftMargin(), table.getTotalHeight()+document.bottomMargin(), writer.getDirectContent());
This adds the table at a very specific position defined by the coordinates:
x = document.leftMargin();
y = table.getTotalHeight()+document.bottomMargin();
You add the table a second time, when you do this:
document.add(table);
This adds the table at whichever position the page cursor is at, which is usually immediately after the previous content that was added with a document.add() method.
PS:
Headers and footers are usually added in an OnEndPage() page event. You're adding the footer only once. You may want to use page events to add the footer on every page.

How to add inline spacing in pdfPCell

I need to add Space between two lines in iTextSharp pdfPCell
Chunk chunk = new Chunk("Received Rs(In Words) : " + " " + myDataTable.Tables[1].Rows[0]["Recieved"].ToString(), font8);
PdfPTable PdfPTable = new PdfPTable(1);
PdfPCell PdfPCell =new PdfPCell(new Phrase(Chunk ));
PdfPCell .Border = PdfCell.NO_BORDER;
PdfPTable .AddCell(PdfPCell );
Please take a look at the following screen shot:
Based on your code snippet, I assume that you want to separate "Received Rs (in Words):" from "Priceless", but it's not clear to me what you want to happen if there is more than one line, so I have written 3 examples:
Example 1:
table = new PdfPTable(2);
table.setHorizontalAlignment(Element.ALIGN_LEFT);
table.setWidthPercentage(60);
table.setSpacingAfter(20);
cell = new PdfPCell(new Phrase("Received Rs (in Words):"));
cell.setBorder(PdfPCell.LEFT | PdfPCell.TOP | PdfPCell.BOTTOM);
table.addCell(cell);
cell = new PdfPCell(new Phrase("Priceless"));
cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
cell.setBorder(PdfPCell.RIGHT | PdfPCell.TOP | PdfPCell.BOTTOM);
table.addCell(cell);
document.add(table);
In this example, I put "Received Rs (in Words):" and "Priceless" in two different cells, and I align the content of the first cell to the left and the content of the second cell to the right. This creates space between the two Chunks.
Example 2
// same code as above, except for:
table.setWidthPercentage(50);
I decreased the width of the table to show you what happens if some content doesn't fit a cell. As we didn't define any widths for the columns, the two columns will have an equal width, but as "Received Rs (in Words):" needs more space than "Priceless", the text doesn't fit the width of the cell and it is wrapped. We could avoid this, by defining a larger with for the first column when compared to the second column.
Example 3:
table = new PdfPTable(1);
table.setHorizontalAlignment(Element.ALIGN_LEFT);
table.setWidthPercentage(50);
Phrase p = new Phrase();
p.add(new Chunk("Received Rs (In Words):"));
p.add(new Chunk(new VerticalPositionMark()));
p.add(new Chunk("Priceless"));
table.addCell(p);
document.add(table);
This example is very close to what you have, but instead of introducing space characters to create space, I introduce a special chunk: new VerticalPositionMark()). This chunk will separate the two parts of the Phrase by introducing as much space as possible.
If this doesn't answer your question, you were probably looking for the concept known as leading. Leading is the space between the baseline of two lines of text. If that is the case, please read the following Q&As:
Changing text line spacing
Spacing/Leading PdfPCell's elements
Paragraph leading inside table cell
Adding more text to a cell in table in itext
How to maintain indentation if a paragraph takes new line in PdfPCell?
If your question isn't about leading, then maybe you're just looking for the concept known as non-breaking space:
How to use non breaking space in iTextSharp
Generating pdf file using Itext

How to align a label versus its content?

I have a label (e.g. "A list of stuff") and some content (e.g. an actual list). When I add all of this to a PDF, I get:
A list of stuff: test A, test B, coconut, coconut, watermelons, apple, oranges, many more
fruites, carshow, monstertrucks thing
I want to change this so that the content is aligned like this:
A list of stuff: test A, test B, coconut, coconut, watermelons, apple, oranges, many more
fruites, carshow, monstertrucks thing, everything is startting on the
same point in the line now
In other words: I want the content to be aligned so that it every line starts at the same X position, no matter how many items are added to the list.
There are many different ways to achieve what you want: Take a look at the following screen shot:
This PDF was created using the IndentationOptions example.
In the first option, we use a List with the label ("A list of stuff: ") as the list symbol:
List list = new List();
list.setListSymbol(new Chunk(LABEL));
list.add(CONTENT);
document.add(list);
document.add(Chunk.NEWLINE);
In the second option, we use a paragraph of which we use the width of the LABEL as indentation, but we change the indentation of the first line to compensate for that indentation.
BaseFont bf = BaseFont.createFont();
Paragraph p = new Paragraph(LABEL + CONTENT, new Font(bf, 12));
float indentation = bf.getWidthPoint(LABEL, 12);
p.setIndentationLeft(indentation);
p.setFirstLineIndent(-indentation);
document.add(p);
document.add(Chunk.NEWLINE);
In the third option, we use a table with columns for which we define an absolute width. We use the previously calculated width for the first column, but we add 4, because the default padding (left and right) of a cell equals 2. (Obviously, you can change this padding.)
PdfPTable table = new PdfPTable(2);
table.getDefaultCell().setBorder(Rectangle.NO_BORDER);
table.setTotalWidth(new float[]{indentation + 4, 519 - indentation});
table.setLockedWidth(true);
table.addCell(LABEL);
table.addCell(CONTENT);
document.add(table);
There may be other ways to achieve the same result, and you can always tweak the above options. It's up to you to decide which option fits best in your case.

Itextsharp V 5.x:image cell height in pdfptable

I am creating table and adding cells to table with text or image content.
var pdfTable = new PdfPTable(2);
nCell = new PdfPCell(new Phrase("A")) {HorizontalAlignment = 1};
pdfTable.AddCell(nCell);
pdfTable.AddCell("B");
pdfTable.AddCell(qrImg);
pdfTable.AddCell(image39);
pdfTable.AddCell("C");
pdfTable.AddCell("D");
pdfTable.SpacingBefore = 20f;
pdfTable.SpacingAfter = 30f;
document.Add(pdfTable);
renders 3 rows and displays image in row2
if I add cells by creating pdfpcell object first:
var cell = new PdfPCell(qrImg};
pdfTable.AddCell(nCell);
only rows 1 and 3 are visible.
If I add height property to cell then the image gets diaplayed.
my questions ( 3 but related);
is it required for us to specify height when adding cell with image ( cells added with text content - phrase resenders correctly) ?
Is there something I am missing when creating a new cell, which prevents images to be rendered?
should I always be using Addcell(image) when adding image content?
Thank you all,
Mar
Its easier to understand what's going on if you browse the source. A table within iText keeps a property around called DefaultCell that gets reused over and over. This is done so that the basic cell properties are kept from cell to cell. When you call AddCell(Image) the DefaultCell's image is set to the image, then added to the table, and finally the image get's null'd out.
543 defaultCell.Image = image;
544 AddCell(defaultCell);
545 defaultCell.Image = null;
The PdfCell(Image) constructor actually internally calls an overload PdfPCell(Image, bool) and passes false as the second parameter, fit. Here's the constructor's conditional on fit:
152 if (fit) {
153 this.image = image;
154 Padding = borderWidth / 2;
155 }
156 else {
157 column.AddText(this.phrase = new Phrase(new Chunk(image, 0, 0, true)));
158 Padding = 0;
159 }
If you pass false to fit, which is the default, you'll see that the image is added in a much more complicated way.
So basically you can add an image in three main ways (okay, lots more actually if you use nested tables or chunks or phrases), the first below picks up the defaults and is probably what you want. The second is more raw but gets you closer to what you probably want. The third is the most raw and assumes that you know what you're doing.
var qrImg = iTextSharp.text.Image.GetInstance(sampleImage1);
//Use the DefaultCell, including any existing borders and padding
pdfTable.AddCell(qrImg);
//Brand new cell, includes some padding to get the image to fit
pdfTable.AddCell(new PdfPCell(qrImg, true));
//Brand new cell, image added as a Chunk within a Phrase
pdfTable.AddCell(new PdfPCell(qrImg));