Невозможно разбить страницу, чтобы не нарушить форматирование таблицы

У меня возникли проблемы с разрывами страниц в таблицах. Думал, что у меня есть решение, поскольку он отлично работает в этом вопросе SO:

Вставка разрыва страницы в <table> в приложении React

Это отлично сработало для таблицы с одним столбцом, но теперь, когда я работаю с несколькими столбцами, это беспорядок.

По сути, мне нужно включить display: block, чтобы разрыв страницы работал правильно, но это заставляет его перейти от хорошо отформатированной таблицы к следующему:

Невозможно разбить страницу, чтобы не нарушить форматирование таблицы

Я прошел по списку в MDN, просто пробуя что-нибудь, что может сработать.

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

Кроме того, разрывы страниц работают только в том случае, если они используются отдельно от <tr>, что нежелательно, поскольку генерирует пустую страницу. Разобрался с этим, переместив pagebreak в <tr> вместо <td>.

Мне не удалось решить эти проблемы; есть предложения о том, как подойти к этой проблеме?

Не уверен, насколько полезен JSFiddle при печати, но вот скомпилированный HTML. Я никогда не смогу заставить JSFiddle работать с React:

https://jsfiddle.net/5gz62d91/

Лучше всего, вероятно, будет репозиторий Github:

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

Вот код отдельно:

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;
    }
}

Сообщения здесь и здесь могут иметь отношение.

MarsAndBack 02.09.2018 19:18
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Travel Booking Angular Template один из лучших Travel & Tour booking template in the world. 30+ валидированных HTML5 страниц, которые помогут...
11
1
915
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я придумал еще более жесткий метод кодирования (так что вызов отлично решит вашу проблему). Я должен сказать, что это не элегантно.

Основная идея моего метода - заменить tbody на display:block (как обычно), но добавить .pagebreak для целевого tbody.

Однако этот метод отключает tbody из таблицы и, таким образом, больше не выравнивает thead. Вот почему я добавляю tr для печати рекламного ролика и удаляю исходный thead при печати.

Добавлена ​​печать, не отображаются в обычном режиме

//Thead part, add a printing thead only shown in Print
//As originaly thead will has alloction problem
{ i % 2 === 1 ?
  <tr className='printing-thead'>
    <td colspan = "3">Results</td>
    <td>1</td>
    <td>2</td>
    <td>3</td>
  </tr> : null
}
....
...
//Corrected Page break
</tbody>
<tbody class = "pagebreak">
    <tr>
        <td colspan = "7"></td>
    </tr>
</tbody>
<tbody>
...

Соответствующий CSS

table {
  border-spacing: 0;
  table-layout: fixed;
  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;
      }
    }
  }
  tr.printing-thead {
    display: none;
  }
}

@media print {
  thead {
    display: none;
  }
  tbody {
    display: block;
    tr.printing-thead {
      display: contents;
      font-weight: bold;
      text-align: center;
    }
  }
  .pagebreak {
    height: 0px;
    break-before: always !important;
    page-break-before: always !important;
    page-break-inside: avoid !important;
    td {
      display: none;
    }
  }
}

Файл JSfiddle.

И версия реакции

Версия JSfiddle React

Поздний ответ из-за отсутствия на работе, извините. Спасибо за помощь! Это действительно решает проблему, о которой спрашивают. Однако здесь возникают две проблемы, об одной из которых вы говорили: столбцы <thead> и <tbody> не совпадают; заголовок не повторяется на каждой странице. Я поиграю с этим еще, чтобы посмотреть, что я могу сделать. Спасибо!

cjones 31.08.2018 17:25

@sockpuppet, вам лучше не выбирать в первую очередь. Может быть у кого-то есть решение получше, я тоже его ищу.

MT-FreeHK 31.08.2018 17:54

@sockpuppet, я обновляю решение для решения упомянутых вами проблем.

MT-FreeHK 03.09.2018 04:01

Привет, можно было бы показать render() для компонента, который отображал HTML в JSFiddle? Я не получаю тех же результатов и на самом деле сталкиваюсь с проблемами, когда он скрывает разделы, где есть разрыв страницы. Очевидно, должно быть условие, в котором есть <tbody> как в условиях true, так и в false, но одно из них содержит имя класса pagebreak. Однако это также пропускает разделы. Наличие тройки на <tbody className> также заставляет его скрывать разделы, где находится разрыв страницы.

cjones 13.09.2018 20:34

@sockpuppet, я обновляю jsfiddle версии реакции в контенте, пожалуйста, посмотрите.

MT-FreeHK 17.09.2018 04:20

Другие вопросы по теме