user10454516
user10454516

Reputation: 1143

Avoid page break inside in header table with rowspan not working (printing)

I'm trying to generate a pdf with Puppeteer chrome.
The data in the pdf is dynamic.
The pdf contain multiple tables that I generate by looping through the data.
So, there are two loops, looping the tables and looping the data (<td>) inside each table.

The header of the table - inside <thead> - has rowspan. Unfortunately, the <thead> is not breaking as I expected.

Here is the current situation:

enter image description here

expected result

What I expect is that the <thead> wouldn't break.
If the <thead> does not fit, it should go to the next page.
I created the template using handlebars.

Here is the code of the template:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">

  <style>
    html,
    body {
      min-height: 150mm !important;
      max-width: 297mm !important;
    }

    @page {
      size: auto;
    }
  </style>
</head>

<body>
  <div>
    {{#each array as |data|}}
    <table>
      <thead style="page-break-inside: avoid !important">
        <tr>
          <th rowspan="2">
            One
          </th>
          <th rowspan="2">
            Two
          </th>
          <th colspan="2">
            Three
          </th>
          <th rowspan="2">
            Four
          </th>
          <th rowspan="2">
            Five
          </th>
          <th colspan="2">
            Six
          </th>
          <th colspan="2">
            Seven
          </th>
        </tr>
        <tr>
          <th>
            Three child 1
          </th>
          <th>
            Three child 2
          </th>
          <th>
            Six child 1
          </th>
          <th>
            Six child 2
          </th>
          <th>
            Seven child 1
          </th>
          <th>
            Seven child 2
          </th>
        </tr>
      </thead>
      <tbody>
        {{#each data.innerArray as |innerData|}}
        <tr>
          <td>
            {{innerData.one}}
          </td>
          <td>
            {{innerData.two}}
          </td>
          <td>
            {{innerData.three.one}}
          </td>
          <td>
            {{innerData.three.two}}
          </td>
          <td>
            {{innerData.four}}
          </td>
          <td>
            {{innerData.five}}
          </td>
          <td>
            {{innerData.six.one}}
          </td>
          <td>
            {{innerData.six.two}}
          </td>
          <td>
            {{innerData.seven.one}}
          </td>
          <td>
            {{innerData.seven.two}}
          </td>
        </tr>
        {{/each}}
      </tbody>
    </table>
    {{/each}}
  </div>
</body>

</html>

I’ve tried

  1. I’ve tried to set page-break-inside: avoid !important inside the <thead>, <tr>, <th> but it's not working.
  2. I’ve tried to wrap the <thead> with <div> and give page-break-inside: avoid !important to the div, still not working.

I don't know how to make this works. Any help, please?

update

I am open with answer that mix with plain javascript to solve this issue. I am thinking, could I try to detect the position of the <thead>, then, check if the <thead> is near (exact distance) the bottom of the page? If it match the condition, it will add style page-break-before true to that table only?

Upvotes: 9

Views: 4717

Answers (3)

Jedi NaJa
Jedi NaJa

Reputation: 1

Try This

   table, td, th {
       border: 1px solid;
       padding: 10px;
       page-break-inside: avoid;
   }
   tr, td {
       word-wrap: break-word;
       page-break-inside: avoid;
       page-break-after: auto;
   }

    table thead {
        display: table-header-group
    }

    tfoot {
        display: table-footer-group
    }

Upvotes: 0

GhastlyCode
GhastlyCode

Reputation: 268

Have you tried:

<thead style="page-break-before">

This will ensure that each heading is on a new page and should work if you only have one heading per table.

The only issue to this solution is that you will have a fresh table on each page no matter how big/small the table is. However, it will stop the headings from breaking.

Alternatively there's also This Article which further describes what you can do to stop page breaking from ruining tables.

Upvotes: 0

BHARATH V
BHARATH V

Reputation: 106

Try limiting each column's width as style="width: <somevalue>%;" in total it should meet 100% like below code. Change the % values and split to the columns according to the amount of content you maintain inside each column.

Example Code:

<tr>
  <th rowspan="2" style="width: 10%;">
    One
  </th>
  <th rowspan="2" style="width: 20%;">
    Two
  </th>
  <th colspan="2" style="width: 20%;">
    Three
  </th>
  <th rowspan="2" style="width: 5%;">
    Four
  </th>
  <th rowspan="2" style="width: 5%;">
    Five
  </th>
  <th colspan="2" style="width: 20%;">
    Six
  </th>
  <th colspan="2" style="width: 20%;">
    Seven
  </th>
</tr>

Upvotes: 3

Related Questions