itext7: InvalidCastException: Unable to cast object of type iText.Html2pdf.Attach.Impl.Layout.HtmlPageBreak to type iText.Layout.Element.IBlockElement

  1. Using itext7 (7.2.0) AND itext7.pdfhtml (4.0.0) AND .Net Core 5.0

  2. Converting itext5 report to itext7

  3. Getting the error, when forcing a page break using html style 'page-break-before: always;'

     public FileResult PrintHtmlToPDFPageBreak()
     {
         StringBuilder sbBody = new StringBuilder();
         sbBody.Append("<html>");
         sbBody.Append("<body>");
         sbBody.Append("<p>This is first page</p>");
         sbBody.Append("<div style='page-break-before: always;'></div>");
         sbBody.Append("<p>This is second page</p>");
         sbBody.Append("</body>");
         sbBody.Append("</html>");
         string htmlContent = sbBody.ToString();
         bool isPortrait = true;
         string reportTitle = "Testing iText7 in .Net5";
         //generate the byte array for the Pdf
         byte[] pdfContent = null;
         //Create a System.IO.MemoryStream object
         using (MemoryStream memoryStream = new MemoryStream())
         {
             //Initialize PDF writer
             PdfWriter pdfWriter = new PdfWriter(memoryStream);
             //Initialize PDF document
             PdfDocument pdfDocument = new PdfDocument(pdfWriter);
             //Initialize document
             Document document = (isPortrait ? new Document(pdfDocument, PageSize.LETTER) : new Document(pdfDocument, PageSize.LETTER.Rotate()));
             var headerHeight = String.IsNullOrEmpty(reportTitle) ? 70f : 120f;
             document.SetMargins(headerHeight, 10f, 56f, 10f); //top, right, bottom, left
             #region HTML to PDF
             //Convert to Elements
             ConverterProperties converterProperties = new ConverterProperties();
             IList<IElement> elements = HtmlConverter.ConvertToElements(htmlContent, converterProperties);
             foreach (var element in elements)
                 document.Add((IBlockElement)element);
             #endregion
             //Close the Document
             document.Close();
             pdfContent = memoryStream.ToArray();
             //Close the MemoryStream
             memoryStream.Close();
         }
         //return the byte array in the form of FileContentResult for browser download
         var fileName = "ConvertHtmlToPDF.pdf";
         return File(pdfContent, System.Net.Mime.MediaTypeNames.Application.Pdf, fileName);
     }
    

Solution 1:

You haven't attached the stacktrace but I am pretty sure the problem is in these two lines:

foreach (var element in elements)
   document.Add((IBlockElement)element);

You are just casting without checking whether the cast is legitimate. Just process the case when an element is an instance of AreaBreak.

Solution 2:

Thank you Alexey your solution worked.

Old code:

foreach (var element in elements)
         document.Add((IBlockElement)element);

New code:

foreach (var element in elements)
{
     if (element.GetType().Name == "HtmlPageBreak")  
        document.Add(new AreaBreak(AreaBreakType.NEXT_PAGE));  
     else  
        document.Add((IBlockElement)element);  
}