Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting margins, headers and footers for PDF without overlap

I need some help with tweaking my PDF header/footer alongside my text areas. The first page looks okay and it just gets worse from there. Is the header and footer eating into my existing margin spaces?

I would like to know what is going wrong and what I can tweak to set the below:

  1. Page widths
  2. Margin widths
  3. Header
  4. Footer
  5. Text area

margins

PDF

My header override function is as below:

public partial class Header : PdfPageEventHelper
{
public override void OnStartPage(PdfWriter writer, Document doc)
    {
    PdfPTable headerTbl = new PdfPTable(2);
    headerTbl.SetWidths(new float[] { 4, 1 });
    headerTbl.TotalWidth = doc.PageSize.Width;

    iTextSharp.text.Image logo = iTextSharp.text.Image.GetInstance(HttpContext.Current.Server.MapPath("~/Images/view.gif"));
    logo.ScalePercent(5);
    PdfPCell cell = new PdfPCell(logo);
    cell.HorizontalAlignment = Element.ALIGN_RIGHT;
    cell.PaddingRight = 20;
    cell.Border = Rectangle.NO_BORDER;


    Font timesH = new Font(Font.FontFamily.TIMES_ROMAN, 20);
    Font times = new Font(Font.FontFamily.TIMES_ROMAN, 10);
    Chunk c1= new Chunk("THIS IS MY HEADER TEXT", timesH);
    Chunk c = new Chunk("\n", times);
    Chunk c2=new Chunk("PLEASE HAVE A NICE DAY", times);
    Phrase p = new Phrase();
    p.Add(c1);
    p.Add(c);
    p.Add(c2);
    PdfPCell cell2 = new PdfPCell(p);
    cell2.Border = Rectangle.NO_BORDER;

    headerTbl.AddCell(cell2);
    headerTbl.AddCell(cell);

    headerTbl.WriteSelectedRows(0, -1, 0, (doc.PageSize.Height - 10), writer.DirectContent);

    }
}

stringWrite is a StringWriter that contains a bunch of data. More clarity HERE.

I create the pdf as follows:

    StringReader sr = new StringReader(stringWrite.ToString());
    Document pdfDoc = new Document(new Rectangle(288f, 144f), 10f, 10f, 30f, 30f);
    pdfDoc.SetPageSize(PageSize.A4.Rotate());
    HTMLWorker htmlparser = new HTMLWorker(pdfDoc);
    PdfWriter pdfwriter = PdfWriter.GetInstance(pdfDoc, HttpContext.Current.Response.OutputStream);
    pdfwriter.PageEvent = new Footer();
    pdfwriter.PageEvent = new Header();
    pdfDoc.Open();
    htmlparser.Parse(sr);
    pdfDoc.Close();
    HttpContext.Current.Response.Write(pdfDoc);
    HttpContext.Current.Response.End();

I'm using iTextSharp, C#, Asp.net in my application.

like image 943
divinediu Avatar asked Apr 25 '14 05:04

divinediu


1 Answers

You initialize the document creation with

Document pdfDoc = new Document(new Rectangle(288f, 144f), 10f, 10f, 30f, 30f);

This means especially that you reserve 10 units both left and right and 30 units both top and bottom as margin. The whole remaining inner space can be used by the automatic content layout mechanisms.

Header material, therefore, has to be drawn in that margin area, otherwise it may overlap with page content.

Your code, on the other hand, creates a paragraph with two lines, the first one set in a 20 unit font, the second one in a 10 unit font, and wraps it in a table. Thus, this table has a height of more than 30 units (the combined height of those two lines plus some inter-line space and possibly some table cell margin overhead). Then it draws it like this

headerTbl.WriteSelectedRows(0, -1, 0, (doc.PageSize.Height - 10), writer.DirectContent);

So it starts 10 units beneath the top of the page. You defined the top page margin to be merely 30, though. Thus, the header and the page content overlap in a stripe more than 10 units high.

Thus, I would propose you increase the top margin by 20 (more than ten plus some distance for the looks of it):

Document pdfDoc = new Document(new Rectangle(288f, 144f), 10f, 10f, 50f, 30f);

The reason why the first page looked all right most likely is that your HTML starts with some empty space (at least as far as the HTMLWorker is concerned).

Additional remarks:

  • Adding content in OnStartPage is discouraged. You should use OnEndPage for all such manipulations of the content, headers, footers, background images, ...

  • HTMLWorker is deprecated. You should use XMLWorker.

  • Is there a reason why you don't set the final page size from the start (in new Document) but instead separately?

like image 67
mkl Avatar answered Sep 28 '22 03:09

mkl