20

I have a C# application that generates a PDF invoice. In this invoice is a table of items and prices. This is generated using a PdfPTable and PdfPCells.

I want to be able to right-align the price column but I cannot seem to be able to - the text always comes out left-aligned in the cell.

Here is my code for creating the table:

PdfPTable table = new PdfPTable(2);
table.TotalWidth = invoice.PageSize.Width;
float[] widths = { invoice.PageSize.Width - 70f, 70f };
table.SetWidths(widths);
table.AddCell(new Phrase("Item Name", tableHeadFont));
table.AddCell(new Phrase("Price", tableHeadFont));

SqlCommand cmdItems = new SqlCommand("SELECT...", con);

using (SqlDataReader rdrItems = cmdItems.ExecuteReader())
{
    while (rdrItems.Read())
    {
        table.AddCell(new Phrase(rdrItems["itemName"].ToString(), tableFont));
        double price = Convert.ToDouble(rdrItems["price"]);
        PdfPCell pcell = new PdfPCell();
        pcell.HorizontalAlignment = PdfPCell.ALIGN_RIGHT;
        pcell.AddElement(new Phrase(price.ToString("0.00"), tableFont));
        table.AddCell(pcell);
    }
}

Can anyone help?

colincameron
  • 2,696
  • 4
  • 23
  • 46
  • 2
    I've met with the same problem, and found no workable solution for a `Phrase` object. THe best I can suggest is that you use a `Paragraph` instead of `Phrase` and set the alignment for the Paragraph itself. – Mihai Jan 05 '13 at 19:54

6 Answers6

25

I'm the original developer of iText, and the problem you're experiencing is explained in my book.

You're mixing text mode and composite mode.

In text mode, you create the PdfPCell with a Phrase as the parameter of the constructor, and you define the alignment at the level of the cell. However, you're working in composite mode. This mode is triggered as soon as you use the addElement() method. In composite mode, the alignment defined at the level of the cell is ignored (which explains your problem). Instead, the alignment of the separate elements is used.

How to solve your problem?

Either work in text mode by adding your Phrase to the cell in a different way. Or work in composite mode and use a Paragraph for which you define the alignment.

The advantage of composite mode over text mode is that different paragraphs in the same cell can have different alignments, whereas you can only have one alignment in text mode. Another advantage is that you can add more than just text: you can also add images, lists, tables,... An advantage of text mode is speed: it takes less processing time to deal with the content of a cell.

Bruno Lowagie
  • 75,994
  • 9
  • 109
  • 165
11
private static PdfPCell PhraseCell(Phrase phrase, int align)
{
    PdfPCell cell = new PdfPCell(phrase);
    cell.BorderColor = BaseColor.WHITE;
    // cell.VerticalAlignment = PdfCell.ALIGN_TOP;
    //cell.VerticalAlignment = align;
    cell.HorizontalAlignment = align;
    cell.PaddingBottom = 2f;
    cell.PaddingTop = 0f;
    return cell;
}
2

Here is my derivation of user2660112's answer - one method to return a cell for insertion into a bordered and background-colored table, and a similar, but borderless/colorless variety:

private static PdfPCell GetCellForBorderedTable(Phrase phrase, int align, BaseColor color)
{
    PdfPCell cell = new PdfPCell(phrase);
    cell.HorizontalAlignment = align;
    cell.PaddingBottom = 2f;
    cell.PaddingTop = 0f;
    cell.BackgroundColor = color;
    cell.VerticalAlignment = PdfPCell.ALIGN_CENTER;
    return cell;
}

private static PdfPCell GetCellForBorderlessTable(Phrase phrase, int align)
{
    PdfPCell cell = new PdfPCell(phrase);
    cell.HorizontalAlignment = align;            
    cell.PaddingBottom = 2f;
    cell.PaddingTop = 0f;
    cell.BorderWidth = PdfPCell.NO_BORDER;
    cell.VerticalAlignment = PdfPCell.ALIGN_CENTER;
    return cell;
}

These can then be called like so:

Font timesRoman9Font = FontFactory.GetFont(FontFactory.TIMES_ROMAN, 9, BaseColor.BLACK);
Font timesRoman9BoldFont = FontFactory.GetFont(FontFactory.TIMES_BOLD, 9, BaseColor.BLACK);

Phrase phrasesec1Heading = new Phrase("Duckbills Unlimited", timesRoman9BoldFont);
PdfPCell cellSec1Heading = GetCellForBorderedTable(phrasesec1Heading, Element.ALIGN_LEFT, BaseColor.YELLOW);
tblHeadings.AddCell(cellSec1Heading);

Phrase phrasePoisonToe = new Phrase("Poison Toe Toxicity Level (Metric Richter Scale, adjusted for follicle hue)", timesRoman9Font);
PdfPCell cellPoisonToe = GetCellForBorderlessTable(phrasePoisonToe, Element.ALIGN_LEFT);
tblFirstRow.AddCell(cellPoisonToe);
B. Clay Shannon-B. Crow Raven
  • 8,547
  • 144
  • 472
  • 862
0

I ended up here searching for java Right aligning text in PdfPCell. So no offense if you are using java please use given snippet to achieve right alignment.

private PdfPCell getParagraphWithRightAlignCell(Paragraph paragraph) {

 PdfPCell cell = new PdfPCell(paragraph);
 cell.setBorderColor( BaseColor.WHITE);
 cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
 return cell;

}   

In getParagraphWithRightAlignCell pass paragraph
Thanks

Kunchok Tashi
  • 2,413
  • 1
  • 22
  • 30
-1

Perhaps its because you are mixing the different ways to add the cells? Have you tried explicitly creating a cell object, massaging it however you want then adding it for every cell?

Another thing you could try is setting the vertical alignment as well as the horizontal.

aledford
  • 15
  • 1
-1
cell.HorizontalAlignment = Element.ALIGN_RIGHT;
Dharman
  • 30,962
  • 25
  • 85
  • 135