KoolReport's Forum

Official Support Area, Q&As, Discussions, Suggestions and Bug reports.
Forum's Guidelines

PDF Page Breaks #1498

Open Andrew Guattery opened this topic on on Jun 22, 2020 - 9 comments

Andrew Guattery commented on Jun 22, 2020

Hello,

I'm using the Export PDF package and I'm finding that my table rows are breaking awkwardly between pages.

Is there a way to control page breaks?

Thank you

David Winterburn commented on Jun 23, 2020

Hi Andrew,

There's a page break option in pdf export but it's for manual page break:

https://www.koolreport.com/docs/export/get_started/#page-break

To void page break inside a table row, please try to add the following CSS rules to your PDF view page:

tr, td, th, tbody, thead, tfoot {
    page-break-inside: avoid !important;
} 

Let us know if this works for you. Thanks!

Andrew Guattery commented on Jun 23, 2020

Hi David,

I added the code you provided to my PDF view page directly inside <style> tags, it did not correct the issue.

I then removed the code from my PDF view page and placed it in my stylesheet, same result.

I even commented out my entire stylesheet except for the page break code in case something was interfering, that did not work either.

Here's the code from my stylesheet:

/*report-content wraps the entire page*/
.report-content
{
    margin-left: 25%;
    margin-right: 25%;
}
/*innerContent wraps pay period table, user select box and date pickers*/
.innerContent
{
    padding-left: 25%;
    padding-right: 25%;
}
/*datePicker1 styles the left date picker*/
.datePicker1
{
    width: 30%;
    float: left;
}
/*datePicker2 styles the right date picker*/
.datePicker2
{
    width: 30%;
    float: right;
}
.loadBtn
{
    padding-top:  7%;
    padding-left: 37%;
}
/*text at the top of the page*/
h1
{
    text-align: center;
    padding-left: 5%;
    padding-right: 5%;
    padding-bottom: 1%;
    padding-top: 1%;
    margin-top: 0%;
    font-size: 20;
}
/*sub-headings*/
h2
{
    text-align: center;
    padding-left: 5%;
    padding-right: 5%;
    padding-bottom: 1%;
    padding-top: 1%;
    font-size: 15;
}
td
{    
    border-width: 0px;
    padding: 0px;

}
/*header rows between each user in table*/
thead
{
    background-color: lightgray !important;
}
tr, td, th, tbody, thead, tfoot 
{
    page-break-inside: avoid !important;
} 
/*<th> in table*/
.cssHeader
{ 
    font-size: 12px;
    padding: 1px;
}
/*<tr> in table*/
.cssRow
{
    font-size: 12px;
    border-width: 0px;
    padding: 0px;
}
/*<tr> that contains the totals for each user*/
.row-group
{
    font-size: 15px;
}
/*styles the pdf by overwriting the bootstrap @media print css*/
@media  print 
{
.table > thead > tr > th 
{
    background-color: lightgray !important; 
    
}
}

Could something be overwriting the page-break? I could be missing something obvious with CSS, I'm no expert with this stuff.

Thanks

David Winterburn commented on Jun 25, 2020

Hi Andrew,

This seems to be a bug of PhantomJS. Please try the following solution to see if it fixes the problem:

<style>
.avoid-break {
  page-break-inside: avoid;
  margin: 0;
  padding: 0;
}
</style>

<table>
  <tr>
   <td>
     <div class="avoid-break">
       <!-- content goes here -->
     </div>
   </td>
 </tr>
</table> 

Let us know the result. Thanks!

Andrew Guattery commented on Jun 25, 2020

I added the code provided, issue persists

PDF View Page:

<style>
.avoid-break {
  page-break-inside: avoid;
  margin: 0;
  padding: 0;
}
</style>
<table>
  <tr>
   <td>
     <div class="avoid-break">
<?php
 
    Table::create(array(
  
//table code...
    ));
?>
     </div>
   </td>
 </tr>
</table> 

I think I'm including the code the way you intended

Thanks for the help

David Winterburn commented on Jun 26, 2020

Hi Anrew,

I've tested many solutions to avoid page break inside table row but it seems nothing works with PhantomJS. And PhantomJS development has been suspended indefinitely so we can not do much with this issue.

If this is a make or break issue for you, please check our cloud export solution which hopefully is more beautiful:

https://www.koolreport.com/packages/cloudexport

Andrew Guattery commented on Jun 26, 2020

Good morning David, I've been reading up on this issue, and you are correct there is no 'easy' fix. I have read multiple hacks where each table cell has a nested div with 'page-break-avoid' class set.... and this seems to work. Is there a way to add a div inside each td in the Table::create? so we would end up with

<td><div class="avoid-break">This may work!</div></td>

maybe? Andy

David Winterburn commented on Jun 29, 2020

Hi Andrew,

Yes, it's possible to add an inner div inside <td> like that:

            Table::create(array(
                      "name" => "table1",
                      "dataStore" => $this->dataStore('orders'),
                      "columns" => [
                            "customerName" => [
                                "formatValue" => "<div class='avoid-break'>@value</div>"
                            ],
                            "productName" => [
                                "formatValue" => "<div class='avoid-break'>@value</div>"
                            ]
                        ]
                    )); 

This are but one of our test solutions without much success. Let us know your result. Thanks!

Andrew Guattery commented on Jun 29, 2020

Good morning David, yes, this is a bit of a conundrum, and playing around with this I have some fixes, thoughts and some improvement: First, I noticed in pdf.js:

if(Object.keys(settings).length==0)
{
    settings = {
        format:'A4',
        orientation:'Portrait',
        margin:'1in',
    };
}

var os = system.os;

var dpi = settings.dpi?settings.dpi:72;
var viewportRatio = settings.viewportRatio?settings.viewportRatio:2;
var zoom = (os.name=="linux"?0.5:1);
zoom = settings.zoom?settings.zoom:zoom;


var format = {
    "a3":[11.69 , 16.53],
    "a4":[8.26 , 11.69],
    "a5":[5.8 , 8.3],
    "legal":[8.5 , 14],
    "letter":[8.5 , 11],
    "tabloid":[11 , 17]
};

Notice in the settings array format is 'A4' while in the format array it is 'a4' - I did not think this would matter however changing settings format to 'a4' definitely changed the behavior of the output. Then I spent 9,000 hours goofing around with the page-break css trying to get it to work only to realize it was 'sort of' working all along! Page-breaking a row in my mind I was expecting to see the border of the row complete on the last row before the break and then see it complete on the following row as well. This doesn't make sense as the row is the data INSIDE the cell if we are adding the '<div class="page-beak">' inside the table cells! So I scrapped all the custom cell formatting and instead played around with the margins for the page, eventually coming up with this:

<body style="margin:36pt 65pt 18pt 75pt;">

and that produces a page break in the table like this:

Not perfect, but a start. Perhaps we could avoid this issue better if KoolReport had a 'table-less' css div table to use for pdf export. Apparently Google Puppeteer handles this better, but when it comes to tables I'm sure there will be issues no matter what is used for export... so a table-less table may be a good project. Andy

David Winterburn commented on Jun 30, 2020

Oh, that's a lot of hard work you did! It seems we must come to a conclusion that page break inside table is not perfect. We will think your suggestion of using div pseudo-table. In the meantime I think the cloud export solution using headless chrome renders table to pdf rather good in comparison with Phantomjs in export package.

Build Your Excellent Data Report

Let KoolReport help you to make great reports. It's free & open-source released under MIT license.

Download KoolReport View demo
None yet

None