Itextsharp - check if an element will add an element to a new page

I use ITextSharp to convert an HTML document to PDF. I use HTMLWorker.ParseToList and iterate over each item in turn. This works fine, but the first page requires different margin sizes for subsequent pages. I can do this by calling MyDocument.NewPage () and calling MyDocument.SetMargins ().

My problem occurs when trying to detect page transitions.

I can use a loop to track page transitions and then call the fields NewPage () and reset, however this can only happen after I really add a paragraph that wraps on a new page, leaving a whole page, almost white space.

I need a way to proactively detect if a page changes if I add some Paragraph object. I tried using ColumnText.Go (true) to mimic it (and if the result is ColumnText.NO_MORE_COLUMN and then make it a page break), unfortunately, this seems to be at best erroneous and tends to detect page breaks in completely incorrect places.

Here is my current code:

            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);
            }

This leads to the fact that he does not detect page breaks until the end of page 2. What's wrong.

The only way I found it to work is to GET the height going to the simulation. SetSimpleColumn.

It works, but I don’t know why, and honestly, that’s nothing good. If anyone can let me know, that would be great.




Thanks to Alexis, I dealt with this. ITextSharp tracks the Java event model quite carefully, which is annoying since I searched for events in Writer and Document directly. First I had to create a class that overrides 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
    }
}

Then I set the PageEvent property of the Writer object, and I changed my loop to remove the simulation.

        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);
        }
+3
source share
3 answers

See Page Events , in particular onStartPage and / or onEndPage , to determine if document fields need to be changed.

Note that these examples are for the Java version, but converting to iTextSharp should be simple.

+2
source

Try this code:

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();
        }
    }
}
+2

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
source

All Articles