title: iTextSharp apply different margins to different pages
body: <p>(using itextsharp 5.4.3)</p>
  
  <p>I have created an application in which the user can create custom xhtml headers and footers that surround the main content of the page. so the generated pdf looks like this:</p>
  
  <pre><code>------------------------
  |  xhtml parsed Header |
  ------------------------
  |                      |
  | xhtml parsed content |
  |                      |
  ------------------------
  |  xhtml parsed Footer |
  ------------------------
  </code></pre>
  
  <p>I have got the pdf generating correctly however I only want the header to appear on the first page, and to be able to (re)set the margins for the remaining pages. currently it displays the header on the first page only (correct) but maintains the margins for the  remaining pages(incorrect) without displaying the header(correct).
  So a 3 page generated pdf would look like</p>
  
  <pre><code>------------------------
  |  xhtml parsed Header |
  ------------------------
  |                      |
  | xhtml parsed content |
  |                      |
  ------------------------
  |  Page 1              |
  ------------------------
  ------------------------
  |                      |
  ------------------------
  |                      |
  | xhtml parsed content |
  |                      |
  ------------------------
  |  Page 2              |
  ------------------------
  ------------------------
  |                      |
  ------------------------
  |                      |
  | xhtml parsed content |
  |                      |
  ------------------------
  |  Page 3              |
  ------------------------
  </code></pre>
  
  <p>The Content are parsed using XML Parser and PageEvents as such
  (Code for the generate button)</p>
  
  <pre><code>Protected Sub btnPreview_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnPreview.Click
      Dim bytes As Byte()
      Dim replaced As String = HttpUtility.HtmlDecode(letterRadEdit.Content.Replace("&lt;br&gt;", "&lt;br /&gt;"))
      Dim replaced2 As String = HttpUtility.UrlDecode(replaced)
      bytes = System.Text.Encoding.UTF8.GetBytes(letterRadEdit.Content)
      Dim tagProcessor As tool.xml.html.DefaultTagProcessorFactory()
  
      Using input As New MemoryStream(bytes, False)
          Dim ms As New MemoryStream()
          Dim document As New iTextSharp.text.Document(iTextSharp.text.PageSize.LETTER, 36.0F, 36.0F, 52.0F, 52.0F)
          Dim headerFooter As New iTextSharpHeaderFooter()
  
          If Not String.IsNullOrEmpty(ddlHeaders.SelectedValue) Or Not String.IsNullOrEmpty(ddlFooters.SelectedValue) Then
              Using db As New dbEntities()
                  If Not String.IsNullOrEmpty(ddlHeaders.SelectedValue) Then
                      'Get header content
                      Dim headerGuid As Guid = New Guid(ddlHeaders.SelectedValue)
                      Dim selectedheader As New LetterHeaderFooter()
                      selectedheader = (From hf In db.LetterHeaderFooters
                                          Where hf.HeadFootID = headerGuid And hf.HeadFootType = 1
                                          Select hf).FirstOrDefault()
                      Dim headerbytes As Byte()
                      headerbytes = System.Text.Encoding.UTF8.GetBytes(HttpUtility.HtmlDecode(selectedheader.HeadFootContent.Replace("&lt;br&gt;", "&lt;br /&gt;").Trim()))
                      headerFooter.HeaderHTML = HttpUtility.HtmlDecode(selectedheader.HeadFootContent.Replace("&lt;br&gt;", "&lt;br /&gt;").Trim())
                      headerFooter.HeaderContent = headerbytes
  
                      'Start building header into table
                      Dim page As New Rectangle(document.PageSize.Width - 72.0F, document.PageSize.Height)
                      Dim cellHeight As Single = document.TopMargin
                      Dim header As New PdfPTable(1)
  
                      header.TotalWidth = page.Width
                      Dim c As New PdfPCell()
                      c.HorizontalAlignment = Element.ALIGN_LEFT
                      c.Border = PdfPCell.BOTTOM_BORDER
  
                      Dim mh As SampleHandler = New SampleHandler()
                      Using sr As TextReader = New StringReader(headerFooter.HeaderHTML)
                          XMLWorkerHelper.GetInstance().ParseXHtml(mh, sr)
                      End Using
                      For Each el As IElement In mh.elements
                          c.AddElement(el)
                      Next
  
                      header.AddCell(c)
                      Dim startingMargin As Single = (header.TotalHeight + document.TopMargin)
                      document.SetMargins(document.LeftMargin, document.RightMargin, startingMargin, document.BottomMargin)
                      headerFooter.PageHeader = header
  
                  End If
  
              End Using
          End If
  
          Dim writer As PdfWriter = PdfWriter.GetInstance(document, ms)
          writer.PageEvent = headerFooter
          writer.CloseStream = False
          document.Open()
  
          Dim htmlContext As HtmlPipelineContext = New HtmlPipelineContext(Nothing)
          htmlContext.SetAcceptUnknown(True)
          htmlContext.SetTagFactory(Tags.GetHtmlTagProcessorFactory())
          Dim cssResolver As ICSSResolver = XMLWorkerHelper.GetInstance().GetDefaultCssResolver(True)
          cssResolver.AddCssFile(HttpContext.Current.Server.MapPath("~/assets/css/pdf.css"), True)
  
          Dim pipeline As New CssResolverPipeline(cssResolver, New HtmlPipeline(htmlContext, New PdfWriterPipeline(document, writer)))
          Dim pdfworker As New XMLWorker(pipeline, True)
  
          Dim p As New XMLParser(True, pdfworker, New System.Text.UTF8Encoding)
  
          Try
              p.Parse(input)
          Catch
  
          Finally
              pdfworker.Close()
  
          End Try
  
          document.Close()
          ms.Position = 0
  
          Response.ContentType = "application/pdf"
          Response.AppendHeader("Expires", "0")
          Response.AppendHeader(
              "Cache-Control",
              "must-revalidate, post-check=0, pre-check=0"
            )
          Response.AppendHeader("Pragma", "public")
          Response.AppendHeader("content-disposition", "attachment; filename=preview.pdf")
          Response.BinaryWrite(ms.ToArray())
          ms.Flush()
      End Using
  End Sub
  </code></pre>
  
  <p>The iTextSharpHeaderFooter class is below</p>
  
  <pre><code>Public Class iTextSharpHeaderFooter
      Inherits PdfPageEventHelper
  
      Private _HeaderStream As Byte()
      Private _FooterStream As Byte()
      Private _HeaderHTML As String
      Private _FooterHTML As String
      Private _headerPdf As Document
      Private _footerPdf As Document
      Private _usesHeader As Boolean
      Private _pageHeader, _pageFooter As PdfPTable
  
      'This is the contentbyte object of the writer
      Dim cb As PdfContentByte
  
      ' we will put the final number of pages in a template
      Dim template As PdfTemplate
  
      ' this is the BaseFont we are going to use for the header / footer
      Dim bf As BaseFont = Nothing
  
      ' This keeps track of the creation time
      Dim PrintTime As DateTime = DateTime.Now
  
      Public Property HeaderContent() As Byte()
          Get
              Return _HeaderStream
          End Get
          Set(ByVal value As Byte())
              _HeaderStream = value
          End Set
      End Property
      Public Property FooterContent() As Byte()
          Get
              Return _FooterStream
          End Get
          Set(ByVal value As Byte())
              _FooterStream = value
          End Set
      End Property
  
      Public Property HeaderHTML() As String
          Get
              Return _HeaderHTML
          End Get
          Set(ByVal value As String)
              _HeaderHTML = value
          End Set
      End Property
      Public Property FooterHTML() As String
          Get
              Return _FooterHTML
          End Get
          Set(ByVal value As String)
              _FooterHTML = value
          End Set
      End Property
  
      Public Property letterHeader() As Document
          Get
              Return _headerPdf
          End Get
          Set(ByVal value As Document)
              _headerPdf = value
          End Set
      End Property
      Public Property letterFooter() As Document
          Get
              Return _footerPdf
          End Get
          Set(ByVal value As Document)
              _footerPdf = value
          End Set
      End Property
  
      Public Property UsesHeader() As Boolean
          Get
              Return _usesHeader
          End Get
          Set(ByVal value As Boolean)
              _usesHeader = value
          End Set
      End Property
  
      Public Property PageHeader() As PdfPTable
          Get
              Return _pageHeader
          End Get
          Set(ByVal value As PdfPTable)
              _pageHeader = value
          End Set
      End Property
  
      Public Property PageFooter() As PdfPTable
          Get
              Return _pageFooter
          End Get
          Set(ByVal value As PdfPTable)
              _pageFooter = value
          End Set
      End Property
  
  
      ' we override the onOpenDocument method
      Public Overrides Sub OnOpenDocument(ByVal writer As PdfWriter, ByVal document As Document)
          MyBase.OnOpenDocument(writer, document)
          Try
              PrintTime = DateTime.Now
          Catch de As DocumentException
          Catch ioe As System.IO.IOException
          End Try
  
      End Sub
  
      Public Overrides Sub OnStartPage(ByVal writer As PdfWriter, ByVal document As Document)
          MyBase.OnStartPage(writer, document)
      End Sub
  
  
      Public Overrides Sub OnEndPage(ByVal writer As PdfWriter, ByVal document As Document)
          MyBase.OnEndPage(writer, document)
  
          Dim pageSize As Rectangle = document.PageSize
  
          Dim htmlContext As HtmlPipelineContext = New HtmlPipelineContext(Nothing)
          htmlContext.SetAcceptUnknown(True)
          htmlContext.SetTagFactory(Tags.GetHtmlTagProcessorFactory())
  
          If Not HeaderContent Is Nothing And HeaderContent.Length &gt; 0 And writer.PageNumber &lt; 2 Then
              Dim page As New Rectangle(document.PageSize.Width - 72.0F, document.PageSize.Height)
              PageHeader.WriteSelectedRows(0, -1, 0, -1, document.LeftMargin, page.Height, writer.DirectContent)
          End If
          If writer.PageNumber &gt; 1 Then
              document.SetPageSize(New Rectangle(36.0F, 36.0F, 52.0F, PageFooter.TotalHeight))
          End If
  
  
          If Not FooterContent Is Nothing And FooterContent.Length &gt; 0 Then
              Dim page As New Rectangle(document.PageSize.Width - 72.0F, document.PageSize.Height)
              PageFooter.WriteSelectedRows(0, -1, 0, -1, document.LeftMargin, PageFooter.TotalHeight, writer.DirectContent)
          End If
  
  
          Dim fontSize As Integer = 160
          Dim xPosition As Integer = 300
          Dim yPosition As Integer = 400
          Dim angle As Integer = 45
          Dim under As PdfContentByte = writer.DirectContentUnder
          Dim baseFont As BaseFont = baseFont.CreateFont(baseFont.HELVETICA, baseFont.WINANSI, baseFont.EMBEDDED)
          under.BeginText()
          under.SetColorFill(BaseColor.LIGHT_GRAY)
          under.SetFontAndSize(baseFont, fontSize)
          under.ShowTextAligned(PdfContentByte.ALIGN_CENTER, "Preview", xPosition, yPosition, angle)
          under.EndText()
  
  
      End Sub
  
  
      Public Overrides Sub OnCloseDocument(ByVal writer As PdfWriter, ByVal document As Document)
          MyBase.OnCloseDocument(writer, document)
      End Sub
  End Class
  </code></pre>
  
  <p>I have tried altering the page margins in OnEndPage and OnStartPage, but neither have any result. I looked at this previous question "<a href="https://stackoverflow.com/questions/12320267/how-do-i-change-the-margin-for-the-second-page-in-a-pdf-using-itextsharp">How do I change the margin for the second page in a PDF using iTextsharp?</a>" but can't see where I would (or should) add page.NewPage() Where does NewPage come in on the page events?</p>
  
  <p>(Also as a subquestion, my pdfs keep saying "Do you want to save changes" when closing in Acrobat Reader X, I looked at a previous SO question where it says to use ToArray() instead of ToBuffer() , am i missing something?)</p>