3
votes

I'm using iTextSharpText to build a PDF.

I was asked to add some dynamic text over an image. I've already tried some examples that I found on this forum and other websites, but I can't seem to get this right, and it's really driving me nuts.

I followed this thread (iTextSharp Adding Text plus Barcode in a single cell?), and tried both answers.

First I tried:

            var img_operacao = Image.GetInstance(String.Format("{0}{1}", Settings.Default.SiteRootURL, "/PublishingImages/PDF_operacao.png"));
            img_operacao.ScaleToFit(150, 41);

            img_operacao.Alignment = Image.UNDERLYING;

            var ph0 = new Phrase(title0, pageHeader);
            var cell = new PdfPCell();

            cell.AddElement(ph0);
            cell.AddElement(new Phrase(new Chunk(img_operacao, 0, 0)));
            table.AddCell(cell);

And I got this: http://imageshack.us/photo/my-images/515/25265113.png/

My second attempt:

            var img_operacao = Image.GetInstance(String.Format("{0}{1}", Settings.Default.SiteRootURL, "/PublishingImages/PDF_operacao.png"));
            img_operacao.ScaleToFit(150, 41);

            img_operacao.Alignment = Image.UNDERLYING;

            var cell = new PdfPCell
                       {
                           Border = Rectangle.NO_BORDER,
                           PaddingTop = 0,
                           PaddingBottom = 0,
                           HorizontalAlignment = Element.ALIGN_CENTER,
                           VerticalAlignment = Element.ALIGN_MIDDLE
                       };

            var ph0 = new Phrase();
            ph0.Add(new Chunk(title0, pageHeader));
            ph0.Add(new Chunk(img_operacao, 0, 0, true));

            cell.AddElement(ph0);
            table.AddCell(cell);

And I got: http://imageshack.us/photo/my-images/688/89424619.png/

I've tried several other variations with chunks, paragraphs, etc, but I can't get the text over the image!!!

If there is someone that can help me, I would really appreciate it. I'm stuck right now...

Thanks a lot

Paula

2

2 Answers

3
votes

It looks like you want to add a background image to a PdfPCell. The recommended approach is to implement the IPdfPCellEvent interface. As documented, you only need to write one method, CellLayout, when you write the custom class that implements IPdfPCellEvent. From your code it looks like you're in a web environment, so this simple example HTTP handler (.ashx) should be easy to follow:

<%@ WebHandler Language="C#" Class="cellEvent" %>
using System;
using System.Web;
using iTextSharp.text;
using iTextSharp.text.pdf;

public class cellEvent : IHttpHandler {
  public void ProcessRequest (HttpContext context) {
    HttpServerUtility Server = context.Server;
    HttpResponse Response = context.Response;
    Response.ContentType = "application/pdf";
    // replace with your image
    string imagePath = Server.MapPath("./Image1.png");
    Image image = Image.GetInstance(imagePath);
    using (Document document = new Document()) {
      PdfWriter.GetInstance(document, Response.OutputStream);      
      document.Open();
      PdfPTable table = new PdfPTable(2);
      for (int i = 1; i < 10; ++i) {
        PdfPCell cell = new PdfPCell(new PdfPCell());
        // add the text
        cell.Phrase = new Phrase(string.Format("CELL 1, ROW {0}", i));
        // your class that adds the background image
        cell.CellEvent = new TestCellEvent() { 
          CellImage = image
        };
        table.AddCell(cell);
        // add __new__ cell; CellEvent no longer applies;
        // (no background image)
        table.AddCell(new PdfPCell(new Phrase(
          string.Format("CELL 2, ROW {0}", i
        ))));
      }
      document.Add(table);
    }
  }
  public bool IsReusable { get { return false; } }

// custom class to implement a cell background image
  class TestCellEvent : IPdfPCellEvent {
    public Image CellImage;
    public void CellLayout(
      PdfPCell cell, Rectangle position, PdfContentByte[] canvases
    ) 
    {
      PdfContentByte cb = canvases[PdfPTable.BACKGROUNDCANVAS];
      // scale image to the cell's __full__ height
      CellImage.ScaleAbsoluteHeight(cell.Height);
      // scale image to the cell's __full__ width
      CellImage.ScaleAbsoluteWidth(cell.Width);
      // you must also explcitly set the image position!
      CellImage.SetAbsolutePosition(position.Left, position.Bottom);
      // add the image to the cell
      cb.AddImage(CellImage);
    }
  }
}

Hopefully the inline comments make sense. Notice that the Image object was instantiated once. If you're reusing the same image doing it this way greatly reduces the file size, versus repeatedly instantiating the Image for each cell, since the image data is only added once to the PDF.

Good luck.

0
votes

I stumbled across a solution while trying to resolve this issue for my own needs. I created a Table object and defined multiple columns. The first column was set to a minimum width, and the rest the appropriate widths to position text being positioned on the form. I am producing an image about 1"x7". The image was added to the cell in the first column of a table row. It's dimensions as set by SetAbsoluteHeight and SetAbsoluteWidth far exceeded the size of the column, so the image kind of bled into/under the remaining columns of the row. For the text being overlaid onto the image, column widths, adding Chunk.Newlines, and paragraph SetLeading (to effect line spacing) were used to adjust text positioning.