Sunday, September 2, 2018

Can't page break to work without messing up the table formatting

Leave a Comment

I have been having issues with page breaks in tables. Thought I had a solution as it was working fine in this SO question:

Inserting a page break into of <table> in React app

This worked fine for a table with one column, but nowt that I am working with multiple columns, it is a mess.

Basically I have to include display: block to get the page break to work properly, but that makes it go from a well formatted table to this:

enter image description here

I have gone down the list in MDN just trying anything that might work.

https://developer.mozilla.org/en-US/docs/Web/CSS/display

Furthermore, page breaks are only working when on their own separate <tr> which is undesirable since it generates a blank page. Got this sorted out by moving the pagebreak to the <tr> instead of the <td>.

I haven't been able to resolve these issues; any suggestions on how to approach this problem?

Not sure how useful a JSFiddle will be given the printing issue, but here is the compiled HTML. I can never get JSFiddle working with React:

https://jsfiddle.net/5gz62d91/

Best would probably be the Github repo:

https://github.com/ishraqiyun77/page-breaks

Here is the code separately:

import React, { Component } from 'react'; import ReactDOM from 'react-dom';  import styles from '../assets/scss/app.scss';  class PageBreakIssues extends Component {      // Render the data points     renderDataPoint() {         let dataPoint = [];         for (let i = 1; i <= 3; i++) {             let num = (Math.random() * 100).toFixed(2);             dataPoint.push(                 <td className='data-point' key={ i }>                     { num < 25 ? null : num }                 </td>             )         }         return dataPoint;     }      // Start generating the row data     renderDataRow() {         let dataRow = [];         for (let i = 1; i <= 5; i++) {             dataRow.push(                 <tr key={ i }>                     <td className='data-name' colSpan='3' key={i}>Test - { i }</td>                     { this.renderDataPoint() }                 </tr>             )         }         return dataRow;     }      // Start generating table sections with the section name     // COMMENT THIS OUT TO TRY WITOUT ADDING A BLANK ROW     renderSections() {         let sections = [];         for (let i = 1; i <= 10; i++) {             sections.push(                 <tbody key={ i }>                      <tr key={ i }>                         <td colSpan='7' className='section-name' key={i} >                             Section - { i }                         </td>                     </tr>                     { this.renderDataRow() }                     {                         i % 2 === 0                             ?                             <tr className='pagebreak'>                                 <td colSpan='7'></td>                             </tr>                             :                             null                     }                 </tbody>             )         }            return sections;     }      // Start generating table sections with the section name     // UNCOMMENT THIS SECTION TO TRY WITHOUT INSERT BLANK TR     // renderSections() {     //     let sections = [];     //     for (let i = 1; i <= 10; i++) {     //         sections.push(     //             <tbody key={i}>     //                 <tr key={i}>     //                     <td colSpan='7' className={ i % 2 === 0? 'section-name pagebreak' : 'section-name'} key={i} >     //                         Section - {i}     //                     </td>     //                 </tr>     //                 {this.renderDataRow()}     //             </tbody>     //         )     //     }     //     return sections;     // }      // Render the table with <th>     render() {         return (             <table>                 <thead>                     <tr>                         <th colSpan='3'>Results</th>                         <th>1</th>                         <th>2</th>                         <th>3</th>                     </tr>                 </thead>                 { this.renderSections() }             </table>         )     } }  ReactDOM.render(<PageBreakIssues />, document.getElementById('app')); 

@mixin borders {     border: 1px solid black; }  %borders {     @include borders; }  table {     border-spacing: 0;      th {         text-align: center;     }      tr {         th{             @extend %borders;         }          td {             @extend %borders;             &.data-name {                 padding: 3px 100px 3px 3px;             }              &.data-point {                 text-align: center;                 padding: 3px 10px;             }              &.section-name {                 background-color: #999;             }         }     } }  @media print {     tr {         display: block;     }      .pagebreak {         break-before: always !important;         page-break-before: always !important;         page-break-inside: avoid !important;     } } 

1 Answers

Answers 1

I faced similar problem before, as can't find any solution from net, I come up with a somehow hard-coding method.

Please take this as fallback, if no other available solutions are posted before your deadline.

You need to put back the page-break to tbody and make it as following.

HTML:

... </tbody> <tbody class="pagebreak">     <tr>         <td colspan="7"></td>     </tr> </tbody> <tbody> ... 

SCSS

@media print {      thead {       display:table;       width: 100%;       th{         text-align: center;         padding: 3px 10px;       }     }      tbody {       display:block;     }     .pagebreak {         height:0px;         break-before: always !important;         page-break-before: always !important;         page-break-inside: avoid !important;     } } 

My method's main idea is changing tbody to display:block (as usual), but adding the .pagebreak to target tbody as well.

However, this method unattach tbody from the table and thus no longer align with thead. That's why I need to add back padding: 3px 10px; to thead so as to simulate the cell size of tbody

The whole working example based on your code is quite long, so I put in a JSfiddle.

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment