Avoid orphan headers at the end of a page when repeating table headers on PDF

Hi SF,

I'm using the Blink converter with print media to support auto-repeating table headers but I'm ending up with some orphan headers at the end of a page when the content doesn't fit on the same page. Is there any way to display the table headers only when at least one row of content can fit on the page?

Also, is there a way to avoid page break for groups of rows?, I'm grouping my rows with separate tags and using this style: tbody { page-break-inside: avoid; } but it doesn't work with the PDF. 

Thanks,

8 Replies

SL Sowmiya Loganathan Syncfusion Team March 20, 2020 11:44 AM UTC

Hi Juan,   
  
Thank you for using Syncfusion products.   
  
We have tried to reproduce the reported issue, but it is working properly and the table repeat header is rendered properly in the PDF documents. We were not able to reproduce the issue in our end. So, we suspect that the issue may occur with the specific input document. So, kindly provide more details such as complete input HTML file/URL (with all resources style, scripts, etc.,), complete code snippet, output documents, product version and simple sample to reproduce the issue in our end. So, that it will be helpful for us to analyze and assist you further on this.    
 
Regards, 
Sowmiya Loganathan 



JJ Juan Jiminez March 20, 2020 05:54 PM UTC

Hi Sowmiya,

I'm attaching a full sample. There's 2 issues here:

1. The header displays on the first page even though there's no rows displaying and then repeats on the second page. It should skip the first page altogether if there's not at least one content row.

2. Rows starting with "Data Set A" and "Data Set B" are in different tbody tags which I'm expecting to break and display on different pages by using page-break-inside: avoid; and given not all records of "Data set B" fit on the same page.

Thanks for checking it,

 

Attachment: Table_page_break_issues_b951493.zip


SL Sowmiya Loganathan Syncfusion Team March 23, 2020 11:05 AM UTC

Hi Juan,   
  
Thank you for providing details.   
  
Queries   
Response   
The header displays on the first page even though no rows are displaying and then repeats on the second page. It should skip the first page altogether if there's not at least one content row.   
We have analyzed the provided sample, but we could not prevent this header skip issue in our end.  The content HTML will be rendered with available space on the first page so that the table header is started on the first page, then the table row was not fit on the first page, it will automatically be moved to the next page.    
  
To overcome this issue, we can adjust the HTML content size in the PDF document by using viewport size. Based on the provided size, the content will be scaled in the PDF document. Please try the below viewport settings in your sample and let me know the result.   
// Set viewport size    
settings.ViewPortSize = newsystem.Drawing.Size(1200, 0);   
   
Rows starting with "Data Set A" and "Data Set B" are in different tbody tags which I'm expecting to break and display on different pages by using page-break-inside: avoid; and given not all records of "Data set B" fit on the same page.   
We have checked this page break issue, we canpage-break properties apply only to block-level elements so that you are not getting page-breaks on <tbody>. To overcome this, you have to apply page-break to a block-level pseudo-element on the <tbody> instead of directly applying it to tbody.   
  
However, we have to define proper page-context and appropriate margins and dimensions. Please try the above solutions at your end and let me know your result.   
  
Please let us know if you have any other further assistance on this.   
 
Regards, 
Sowmiya Loganathan 



JJ Juan Jiminez March 24, 2020 03:16 AM UTC

Hi Sowmiya,

The viewport size approach won't work for us because we have dynamic content, so we really don't know which size to use or if the table will be cut off at all.

Regarding the second issue, I tried the pseudo element approach (it's in the sample I attached on my previous comment) but it still doesn't work, page isn't breaking on the tbody row groups.

Best,


JJ Juan Jiminez March 24, 2020 11:47 PM UTC

Working some more on this issue, this is my Javascript attempt:


 $(function () {
            // prevent orphan headers

            let docMarginOffset = 40;
            let pageSize = 1600 + docMarginOffset;
            let docSize = $('body').height();
            let pageStart = 0;

            while (pageStart <= docSize) {
                let pageEnd = pageStart + pageSize;

                $("thead").each(function () {
                    let th = $(this);
                    let thOffset = th.offset().top;

                    if (thOffset >= pageStart && thOffset <= pageEnd) {
                        let table = th.parents('table');
                        let firstRow = table.find('tbody tr').first();
                        let frBottom = firstRow.offset().top + firstRow.outerHeight(true);
                        if (frBottom >= pageEnd) {                       
                            table.css('page-break-before', 'always');
                            // update document height as it increases
                            docSize = ('body').height();
                        }
                    }
                });

                pageStart += pageSize;
            }
        });


This makes the entire table jump to the next page if there's not at least one data row rendered within the same page but I'm still not sure about the page size itself. Can you shed some light on the ratio between the Viewport and the actual PDF page size in pixels?, it seems a 1200 Viewport renders 1600px PDf pages? (plus PDF doc margins).


SL Sowmiya Loganathan Syncfusion Team March 25, 2020 01:50 PM UTC

Hi Juan, 

Thank you for your update. 

As we said earlier, we could not prevent this header skip for dynamic content. We can only change the HTML content size by using viewport size, we tried this (1200, 0) with your provided sample, the content will scaled properly and the table row rendered with available space on the first page. We have attached the documents for your reference. Please try the below viewport settings in your sample and let me know the result.    

BlinkConverterSettings settings = new BlinkConverterSettings 
            { 
                EnableJavaScript = true, 
                Margin = new PdfMargins { Top = 20, Bottom = 20, Left = 20, Right = 20 }, 
                Orientation = PdfPageOrientation.Portrait, 
                ViewPortSize = new Size(1200, 0), 
                PdfPageSize = PdfPageSize.A4, 
                MediaType = MediaType.Print, 
            }; 


We have checked the page break issue in our end, the page-break properties could not apply to <tbody> <tr> element. We have try to change the styles of <tbody>  as display : table-row-group to display:block, but the table alignment was not preserved properly. To overcome this issue, you have to handle apply page-break to a block-level pseudo-element on the <tbody> instead of directly applying it to tbody from webpage itself and apply the proper page context, appropriate margins and dimensions. 

Regards, 
Sowmiya Loganathan 
 



JJ Juan Jiminez March 26, 2020 09:48 PM UTC

Hi Sowmiya,

Thanks for your help. I ended up with a custom JS solution for both issues. I'm attaching my sample code for future reference.

Best,

Attachment: Table_page_break_d490a6ab.zip


SL Sowmiya Loganathan Syncfusion Team March 27, 2020 07:32 AM UTC

Hi Juan,   
 
Thank you for the update. We glad to know that the issue was resolved in your end.   
 
Regards,  
Sowmiya Loganathan  
 


Loader.
Up arrow icon