2015-11-20 326 views
1

我有一個模板分成3個文件(標題,正文和頁腳),所有這些都在html中。我需要使用Itextsharp在頁面末尾插入頁腳

itextsharp庫導出pdf文件。

我使用下面的代碼來做到這一點。

功能將文件

public string GeneratePDF(Dictionary<string, object> fieldValues, string pdfPath, string templatePath) 
     { 
      //Inicializes a New Document 
      Document document = new Document(PageSize.A4,0,0,0,0); 

      try 
      { 
       PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(pdfPath, FileMode.Create));     
       PdfPageEvents events = new PdfPageEvents(); 
       //Initializes page events 
       writer.PageEvent = events; 
       //Open Document 
       document.Open(); 

       //Gerar efetivamente o html 
       TemplateHelper objTemplate = new TemplateHelper(); 
       //This function is not important, only replaces the content by a dictionary 
       string htmlContent = objTemplate.GenerateHTML(fieldValues, templatePath); 

       //Gerar o PD 
       StringReader reader = new StringReader(htmlContent); 
       XMLWorkerHelper.GetInstance().ParseXHtml(writer, document, reader); 
      } 
      catch (Exception ex) 
      { 
       throw; 
      } 
      finally 
      { 
       document.Close(); 
      } 

      return pdfPath; 
     } 

和頁面事件導出

public class PdfPageEvents : PdfPageEventHelper 
{ 
    public override void OnStartPage(PdfWriter writer, Document document) 
    { 
      StreamReader template = new StreamReader(@"d:\Header.html"); 
      string htmlContent = template.ReadToEnd(); 
      StringReader reader = new StringReader(htmlContent); 

      ElementList e = XMLWorkerHelper.ParseToElementList(htmlContent, ""); 
      PdfDiv div = (PdfDiv)e.First(); 
      document.Add(div.Content.First()); 
      template.Close(); 

     template = new StreamReader(@"d:\Footer.html"); 
     htmlContent = template.ReadToEnd(); 
     reader = new StringReader(htmlContent); 

    } 
    //começa com o cabeçalho 
    public override void OnEndPage(PdfWriter writer, Document document) 
    { 
     StreamReader template = new StreamReader(@"d:\Footer.html"); 
     string htmlContent = template.ReadToEnd(); 
     StringReader reader = new StringReader(htmlContent); 
     ElementList elementListFooter = XMLWorkerHelper.ParseToElementList(htmlContent, ""); 
     PdfDiv div = (PdfDiv)elementListFooter.First(); 
     PdfPTable t = (PdfPTable)div.Content.First(); 

     document.Add(t); 
     template.Close(); 
    } 
} 

當我導出爲PDF,頭工作正常,但頁腳不工作。我試圖將頁腳內容放在頁腳

的文件中,但未成功。如果主體的內容很大以適合一頁,則頁腳內容被設置爲

低於頁眉並低於最後一頁上的內容。 下圖顯示了這個問題。

PDF with one page. The footer is below of the content, but not positioned on the bottom of the page

Footer on the top of the first page and before body content

enter image description here

+1

請**不要**在'onStartPage()'方法中添加任何內容。這可能會導致各種不良的副作用。這個註釋並不能解決你的問題,但是你在'onStartPage()'方法中添加頭部的事實證明你忽略了文檔。 –

+1

請**不要**使用'document.Add()'在'onEndPage()'中添加內容。傳遞給事件的'document'對象是一個特殊的'PdfDocument'對象,應該只用於*只讀*目的。這是導致你的問題的原因。它也證明你忽略了文檔。 –

+0

無關的注意事項,'Document'和'PdfWriter'都實現了'IDisposable',所以你可以使用''using'範例而不是'try/catch',並保證'Close()'被調用爲您在處置期間自動處理。 –

回答

1

要解釋什麼是布魯諾說,在更詳細一點的意見,如果你在一個頁面事件Add()內容,你可以想見,導致文檔生成一個新頁面,這會導致您的頁面事件再次觸發。更有趣的是,如果你的頁面事件添加了太多的內容,你實際上可能會遇到無限循環的添加,溢出,新頁面,重複。

如果您想要一個真正的頁眉和頁腳,請將Document頁邊距設置爲考慮兩者的高度,並且正常Document.Add()代碼將尊重它。如果您不知道每次您可以嘗試使用this code to calculate the height時,您的頁眉和/或頁腳將會有多高。

然後,您可以使用頁面事件或雙向傳遞來使用DirectContentColumnText添加頁眉和頁腳以及已知的固定位置。您的內容看起來相當簡單,因此您可以將其轉換爲正常的iTextSharp命令,但是如果您希望保留爲HTML和頁眉和頁腳,請參閱this post將HTML解析爲元素列表並將其添加到ColumnText

+0

您可能還想鏈接到http://stackoverflow.com/questions/33394158/add-header-to-pdf-from-html-using-itext –