iTextPDF 5.5 : Why 2 times table created when used table.writeSelectedRows()? - itext

I want to add table middle of page after header.
Found method 'writeSelectedRows' which can be used to move table location on page.
But with this method, table is created 2 times, one at the start of the page, other at the specified location.
Please help in resolving this.
//Using iTextPDF 5.5.10
document.open();
PdfPTable table = new PdfPTable(1);
// table.setPaddingTop(250);
table.setTotalWidth(100);
table.setWidthPercentage(100);
PdfPCell cell = new PdfPCell(new Phrase("Some text here"));
// cell.setFixedHeight(13);
cell.setBorder(Rectangle.NO_BORDER);
cell.setColspan(1);
cell.setBackgroundColor(BaseColor.CYAN);
table.addCell(cell);
table.writeSelectedRows(0, -1, 50, 650, writer.getDirectContent());
document.add(table);
document.open();
This generates following output.
I want to add table at given location one time only and not at start of the page.

The table appears twice in your document because you add it twice! First you add it at the desired position:
table.writeSelectedRows(0, -1, 50, 650, writer.getDirectContent());
And then you add it for automatic layout, putting it at the top of the page:
document.add(table);
If you only want it once, add it only once, i.e. remove one of those lines.

Related

iText(Sharp) - Text is different when drawn with cell event vs. directly

I've got a PdfPTable in which I am drawing simple text:
BaseFont bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
Font f2 = new Font(bf, 10.0f);
PdfPTable tab = new PdfPTable(2);
table.AddCell(new PdfPCell(new Phrase("Dude", f2)));
And that's all fine and dandy. But then in order to do some fancier stuff, I'm trying to get cell events to work:
Font f2 = new Font(bf, 10.0f); // Pretend this is a global
class CellEvent : IPdfPCellEvent
{
void IPdfPCellEvent.CellLayout(PdfPCell cell, Rectangle r, PdfContentByte[] canvases)
{
ColumnText ct = new ColumnText(canvases[0]);
ct.SetSimpleColumn(r);
ct.AddElement(new PdfPCell(new Phrase("Dude", f2)));
ct.Go();
}
}
BaseFont bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
PdfPTable tab = new PdfPTable(2);
PdfPCell ce = new PdfPCell();
ce.CellEvent = new CellEvent();
table.AddCell(ce);
When I do this though, the cell is drawn quite differently. My actual text is multiple lines long, and when drawn directly (adding the phrase directly to the cell) the text lines are quite close together vertically; when drawn via the cell event, there is a lot of space between the text lines and it doesn't fit in the box the PdfPTable provides for me.
Is there a different, more preferred method for drawing text inside IPdfPCellEvent.CellLayout()? Or are there just some formatting parameters I need to copy from PdfPCell into ColumnText?
There is something very wrong with this snippet:
ColumnText ct = new ColumnText(canvases[0]);
ct.SetSimpleColumn(r);
ct.AddElement(new PdfPCell(new Phrase("Dude", f2)));
ct.Go();
More specifically:
ct.AddElement(new PdfPCell(new Phrase("Dude", f2)));
You can not use the PdfPCell object outside of the context of a PdfPTable.
As for the differences between content in PdfPCell and ColumnText, you may want to read the answers to these questions:
itext ColumnText ignores alignment
Right aligning text in PdfPCell
The content of a PdfPCell is actually stored in a ColumnText object, but a PdfPCell may have a padding.
There's also text mode versus composite mode. You are talking about the distance between two lines. In text mode, this distance is defined at the level of the PdfPCell/ColumnText using the setLeading() method. In composite mode, this parameter is ignored. Instead, the leading of the elements added to the PdfPCell/ColumnText is used.
For instance: if p1, p2 and p3 are three Paragraph objects, each having a different leading, then ct will have text with three different leadings if you do this:
ct.addElement(p1);
ct.addElement(p2);
ct.addElement(p3);

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 do I insert right justified text in itextsharp?

I have a PDF into which I need to define very precise rectangles into which I need to inject text. i.e. the PDF is a template and I need to be able to specify a rectangular area and then have text aligned to the bottom of the rectangle and to the right.
I have tried something like this:-
PdfContentByte over = ps.GetOverContent(1);
font = new Font(bf, 47, Font.NORMAL, new Color(190, 210, 49));
ct = new ColumnText(over);
myText = new Phrase("3.5", font);
ct.Alignment = Element.ALIGN_RIGHT | Element.ALIGN_BOTTOM;
ct.SetSimpleColumn(myText, 446.5f, 314.5f, 536.5f, 294.5f, 47, Element.ALIGN_RIGHT | Element.ALIGN_BOTTOM);
ct.Go();
Not sure what I am doing wrong but it doesn't work....
Instead of giving absolute positions to the text, why dont you develop a table structure and then place text inside the cells.
Give the alignments and all to the cells
Use PdfPCell and PdfPTable

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

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);