2012-05-11 44 views
3

我正在使用ITextSharp將HTML文檔轉換爲PDF。我使用HTMLWorker.ParseToList並依次循環遍歷每個項目。這工作正常,但是第一頁需要爲後續頁面設置不同的邊距。我可以通過調用MyDocument.NewPage()並調用MyDocument.SetMargins()來完成此操作。

嘗試檢測頁面轉換時發生了我的問題。

我可以使用一個循環來跟蹤頁面轉換,然後調用NewPage()並重置頁邊距,但是,只有當我實際添加了一個包裝到新頁面的段落時,纔會發生這種情況,從而留下整個頁面這幾乎是空白的。

我需要一種先發制人的方式來檢測頁面是否會改變,如果我添加某個段落對象。 我試過使用ColumnText.Go(真)來模擬它(如果結果是ColumnText.NO_MORE_COLUMN,那麼使它成爲分頁符),不幸的是,似乎是最好的flakey,並傾向於檢測分頁符在完全錯誤的地方。

這裏是我當前的代碼:Itextsharp - 檢查添加元素是否會創建新頁面

  ColumnText simulation = new ColumnText(Writer.DirectContent); 
      simulation.SetSimpleColumn(Writer.PageSize); 
      bool FirstPage = true; 
      foreach (var item in ItemList) 
      { 
       var para = new Paragraph("", Normal); 
       para.AddAll(item.Chunks);      
       para.SpacingAfter = 10; 
       foreach (Chunk c in item.Chunks) 
       { 
        simulation.AddText(c); 
       } 
       if(FirstPage) { 
        int simresult = simulation.Go(true); 
        if(simresult == (int)ColumnText.NO_MORE_COLUMN) 
        { 
         textDocument.SetMargins(100,100,100,100); 
         textDocument.NewPage();  
         FirstPage = false;     
        } 
       } 

       textDocument.Add(para); 
      } 

這導致它無法檢測到分頁符,直到第2頁的到底哪款是沒有好處的。

我發現得到它的唯一方法是使半身進入simulation.SetSimpleColumn。

它的工作原理,但我不知道爲什麼,說實話,這是不好的。如果任何人都可以給我任何洞察力,那會很棒。



感謝亞歷克西斯我已經完成了。 ITextSharp完全遵循Java事件模型,這是令人討厭的,因爲我直接在Writer和Document中查找事件。 首先,我不得不創建一個類,推翻PdfPageEventHelper:

internal class MainTextEventsHandler : PdfPageEventHelper 
{ 
    public override void OnStartPage(PdfWriter writer, Document document) 
    { 
     document.SetMargins(document.LeftMargin, document.LeftMargin, document.TopMargin, document.BottomMargin); //Mirror the horizontal margins 
     document.NewPage(); //do this otherwise the margins won't take 
    } 
} 

接下來,我設置Writer對象的PageEvent財產,我修改了循環去除模擬。

 Writer.PageEvent = new MainTextEventsHandler(); 
     foreach (var item in ItemList) 
     { 
      var para = new Paragraph("", Normal); 
      para.AddAll(item.Chunks); 
      /* per-paragraph stuff here */ 
      para.SpacingAfter = 10;      
      textDocument.Add(para); 
     } 

回答

2

看一看Page Events,特別是onStartPage和/或onEndPage,以確定是否需要更改文檔的頁邊距。

請注意,這些示例適用於Java版本,但轉換爲iTextSharp應該很簡單。

+0

它確實看起來就像他們直接將Java移植到C#並忽略了C#事件模型一樣。我必須創建一個帶有單個函數的獨立迷你類(覆蓋OnStartPage),它繼承了PdfPageEventHelper,並將.SetMargins和.NewPage()調用放在那裏。現在工作正常,甚至不需要模擬,但只是給對象本身的事件出了什麼問題? – GeeItSomeLaldy

+0

@Canazza我不是iText-committer,所以我真的不知道。也許你可以在[iText郵件列表](https://lists.sourceforge.net/lists/listinfo/itext-questions)上提問。請注意,您必須訂閱該列表才能在該列表中發帖。 –

2

試試這個代碼:

public const string pageBreakHtmlMarker = "<!-- pageBreak -->"; 
public MemoryStream htmlToPdf(string html) 
{ 
    MemoryStream msOutput = new MemoryStream(); 
    string[] sep = new string[] { pageBreakHtmlMarker }; 
    string[] arrHtml = html.Split(sep, 9999, StringSplitOptions.RemoveEmptyEntries); 
    htmlToPdf(arrHtml, ref msOutput); 
    return msOutput; 
} 
private void htmlToPdf(string[] arrHtmlPages, ref MemoryStream msOutput) 
{ 
    using (Document document = new Document(PageSize.A4, 30, 30, 30, 30)) 
    { 
     using (HTMLWorker worker = new HTMLWorker(document)) 
     { 
      PdfWriter writer = PdfWriter.GetInstance(document, msOutput); // writer to listen doc ad direct a XML-stream to a file    
      document.Open(); 
      worker.StartDocument(); 
      foreach (string html in arrHtmlPages) 
      { 
       TextReader reader = new StringReader(html); // parse the html into the document 
       worker.Parse(reader); 
       document.Add(Chunk.NEXTPAGE); 
      } 
      worker.EndDocument(); 
     } 
    } 
} 
+0

你能解釋這個答案嗎?我不明白這將如何解決OP的問題。 –

0

示例代碼段在Visual Basic

LoadPage只需使用:

Dim pdfPageEvents As pdfPageEvents = New pdfPageEvents 
writer = PdfWriter.GetInstance(doc, memMemoryStream) 
writer.CloseStream = False 
writer.PageEvent = pdfPageEvents 
doc.Open() 

把這個類て同一個文件或命名空間

Public Class pdfPageEvents 
    Inherits iTextSharp.text.pdf.PdfPageEventHelper 
    Private _strTitle As String, _strPrintFeatures As String 

    Public Sub New(ByVal Title As String, ByVal PrintFeatures As String) 
     _strTitle = Title 
     _strPrintFeatures = PrintFeatures 
    End Sub 

    Public Overrides Sub OnStartPage(ByVal writer As PdfWriter, ByVal doc As Document) 
     If InStr(_strPrintFeatures, "header") > 0 Then 
      Dim fntFont As Font = FontFactory.GetFont("Tahoma", BaseFont.CP1250, True, 10, Font.NORMAL, New BaseColor(128, 128, 128)) 
      Dim imgImage As iTextSharp.text.Image = iTextSharp.text.Image.GetInstance(HttpContext.Current.Server.MapPath("../LocalResources/Images/print_company_logo_medium.png")) 
      Dim tblTable As New PdfPTable(2) 
      Dim celRightCell As PdfPCell 

      tblTable.WidthPercentage = 100 
      tblTable.HorizontalAlignment = Element.ALIGN_CENTER 
      imgImage.ScalePercent(70) 

      Dim celLeftCell As New PdfPCell(New Phrase(_strTitle, fntFont)) 
      celLeftCell.HorizontalAlignment = Element.ALIGN_LEFT 
      celLeftCell.Border = 0 
      celLeftCell.BorderWidthBottom = 0.5 
      celLeftCell.BorderColorBottom = New BaseColor(128, 128, 128) 
      celLeftCell.VerticalAlignment = Element.ALIGN_BOTTOM 
      celLeftCell.PaddingBottom = 3 
      tblTable.AddCell(celLeftCell) 

      If InStr(_strPrintFeatures, "logo") > 0 Then 
       celRightCell = New PdfPCell(imgImage) 
      Else 
       celRightCell = New PdfPCell(New Paragraph("")) 
      End If 

      celRightCell.HorizontalAlignment = Element.ALIGN_RIGHT 
      celRightCell.Border = 0 
      celRightCell.BorderWidthBottom = 0.5 
      celRightCell.BorderColorBottom = New BaseColor(128, 128, 128) 
      celRightCell.VerticalAlignment = Element.ALIGN_BOTTOM 
      celRightCell.PaddingBottom = 3 
      tblTable.AddCell(celRightCell) 

      doc.Add(tblTable) 
      doc.Add(New Paragraph(vbNewLine)) 
     End If 
    End Sub 

    Public Overrides Sub OnEndPage(ByVal writer As PdfWriter, ByVal doc As Document) 
     If InStr(_strPrintFeatures, "footer") > 0 Then 
      Dim fntFont As Font = FontFactory.GetFont("Tahoma", BaseFont.CP1250, True, 10, Font.NORMAL, New BaseColor(128, 128, 128)) 
      Dim tblTable As New PdfPTable(2) 
      Dim strDate As String = IIf(InStr(_strPrintFeatures, "date") > 0, FormatDateTime(Date.Today, DateFormat.GeneralDate), "") 

      tblTable.TotalWidth = doc.PageSize.Width - doc.LeftMargin - doc.RightMargin 
      tblTable.HorizontalAlignment = Element.ALIGN_CENTER 

      Dim celLeftCell As New PdfPCell(New Phrase(strDate, fntFont)) 
      celLeftCell.HorizontalAlignment = Element.ALIGN_LEFT 
      celLeftCell.Border = 0 
      celLeftCell.BorderWidthTop = 0.5 
      celLeftCell.BorderColorTop = New BaseColor(128, 128, 128) 
      celLeftCell.VerticalAlignment = Element.ALIGN_BOTTOM 
      tblTable.AddCell(celLeftCell) 

      Dim celRightCell As New PdfPCell(New Phrase(CStr(doc.PageNumber), fntFont)) 
      celRightCell.HorizontalAlignment = Element.ALIGN_RIGHT 
      celRightCell.Border = 0 
      celRightCell.BorderWidthTop = 0.5 
      celRightCell.BorderColorTop = New BaseColor(128, 128, 128) 
      celRightCell.VerticalAlignment = Element.ALIGN_BOTTOM 
      tblTable.AddCell(celRightCell) 
      tblTable.WriteSelectedRows(0, -1, doc.LeftMargin, (doc.BottomMargin), writer.DirectContent) 
     End If 
    End Sub 
End Class 
+0

你能解釋這個答案嗎?我不明白這將如何解決OP的問題。 –

相關問題