在 React 应用程序中插入分页符 <table>

IT技术 html css twitter-bootstrap reactjs
2021-05-16 08:57:06

所以基本上,我的表格有一堆子标题,我希望在这么多小节之后插入一个分页符,并防止在其中一个节的中间自动分页。大概是这个样子。灰色区域是分页符之前的子标题,如果它像第 4、8、12 等小节。

桌子

我遇到的两个主要问题可能是 React 独有的,也可能不是。另外,我正在使用 Bootstrap。

1)<div>作为<table>, <tbody>,<thead>问题的孩子

我最初的想法是<div className='pagebreak'>在每 4 次之后插入<th>这将触发错误(释义)为<div> cannot be a child of <table>/<tbody>/<thead>.

因此,不允许执行以下操作:

let i = 1;

return _.map(section, s => {
    i++;
    return (
        <table>
            <tbody>
                <tr>
                    <th colSpan='6'>{s.subSectionTitle}</th>
                </tr>
                <tr>
                    <td>{s.data1}</td>
                    <td>{s.data2}</td>
                    <td>{s.data3}</td>
                    <td>{s.data4}</td>
                    <td>{s.data5}</td>
                    <td>{s.data6}</td>
                </tr>
                { i = 4 ? <div className='pagebreak'></div> : null }
            </tbody>
        </table>
    )
})

我还有其他一些没有用的好主意是做这样的事情:

{ i = 4 ? <tr className='pagebreak'></tr> : null }

或者:

{ i = 4 ? <th><td className='pagebreak'></th></tr> : null }

或者:

{ i = 4 ? <tr><th><div className='pagebreak'></div></th></tr> : null }

虽然这些会绕过那里的错误,但他们不会做任何事情。它会忽略pagebreak

似乎您不能在<table>标签内放置任何类型的分页符。

2)<table>为每个小节创建一个新的。

它看起来就像废话,因为列宽会因表格而异,除非我将宽度设为静态,而我不想这样做。想要保持它们动态,同时让所有列的宽度始终相同,这取决于给定列中数据点的最大宽度。

话虽如此,这确实有效,因为它实际上插入了一个分页符:

    return (
        <table>
            <tbody>
                <tr>
                    <th colSpan='6'>{s.subSectionTitle}</th>
                </tr>
                <tr>
                    <td>{s.data1}</td>
                    <td>{s.data2}</td>
                    <td>{s.data3}</td>
                    <td>{s.data4}</td>
                    <td>{s.data5}</td>
                    <td>{s.data6}</td>
                </tr>
            </tbody>
        </table>
        <div className='pagebreak'></div>
        <table>
            <tbody>
                <tr>
                    <th colSpan='6'>{s.subSectionTitle}</th>
                </tr>
                <tr>
                    <td>{s.data1}</td>
                    <td>{s.data2}</td>
                    <td>{s.data3}</td>
                    <td>{s.data4}</td>
                    <td>{s.data5}</td>
                    <td>{s.data6}</td>
                </tr>
            </tbody>
        </table>   
    )

有关如何处理此问题的任何建议?

2个回答

以 Rounin 的回应为基础,展示 React 示例中的工作原理:

@media print {

    tr {
        display: block;
    }

    .pagebreak {
        break-after: always !important;
        page-break-after: always !important;
        page-break-inside: avoid !important;
    }
}

// component.jsx
import React, { Component } from 'react';
import ReactDOM from 'react-dom';

import styles from '../assets/scss/app.scss';

class TestPrint extends Component {
    constructor(props) {
        super(props);
        this.state = {
            data: [
                'test', 'test', 'test', 'test', 'test', 'test',
                'test', 'test', 'test', 'test', 'test', 'test',
                'test', 'test', 'test', 'test', 'test', 'test',
                'test', 'test', 'test', 'test', 'test', 'test',
                'test', 'test', 'test', 'test', 'test', 'test',
                'test', 'test', 'test', 'test', 'test', 'test',
                'test', 'test', 'test', 'test', 'test', 'test',
                'test', 'test', 'test', 'test', 'test', 'test'
            ]
        }
    }

    renderContent() {
        let i = 0;
        return this.state.data.map((d) => {
            i++
            if (i % 10 === 0) {
                return (
                    <tr key={i} className='pagebreak'>
                        <td key={i}>{i} - {d}</td>
                    </tr>                    
                )
            } else {
                return (
                    <tr key={i}>
                        <td key={i}>{i} - {d}</td>
                    </tr>
                )
            }
        });
    }

    render() {
        return (
            <table>
                <tbody>
                    { this.renderContent() }
                </tbody>
            </table>
        )
    }
}

ReactDOM.render(<TestPrint />, document.getElementById('app'));

这是对的:

一个<div>不能为的子<table><tbody><thead>

但是没有什么可以阻止您标记和样式化您的表格,以便您经常有一行样式为块级元素,它代表一个分页符,在 CSS 中使用以下命令声明:

page-break-before: always;

并且包含一个单一的无内容数据单元,使用:

<td colspan="7">

您还可以使用以下方法避免传统表格行中的分页符:

page-break-before: avoid 

工作示例:

table {
border-collapse: collapse;
}

td {
height: 12px;
padding: 6px 24px;
border: 1px solid rgb(0, 0, 0);
}

tr {
page-break-before: avoid;
}

tr.page-break {
display: block;
page-break-before: always;
}

tr.page-break td {
border: 1px solid rgba(0, 0, 0, 0);
}
<table>
<tr class="page-break">
<td colspan="7">
</tr>

<tr>
<td>A1</td>
<td>A2</td>
<td>A3</td>
<td>A4</td>
<td>A5</td>
<td>A6</td>
<td>A7</td>
</tr>

<tr>
<td>B1</td>
<td>B2</td>
<td>B3</td>
<td>B4</td>
<td>B5</td>
<td>B6</td>
<td>B7</td>
</tr>

<tr>
<td>C1</td>
<td>C2</td>
<td>C3</td>
<td>C4</td>
<td>C5</td>
<td>C6</td>
<td>C7</td>
</tr>

<tr>
<td>D1</td>
<td>D2</td>
<td>D3</td>
<td>D4</td>
<td>D5</td>
<td>D6</td>
<td>D7</td>
</tr>

<tr>
<td>E1</td>
<td>E2</td>
<td>E3</td>
<td>E4</td>
<td>E5</td>
<td>E6</td>
<td>E7</td>
</tr>

<tr>
<td>F1</td>
<td>F2</td>
<td>F3</td>
<td>F4</td>
<td>F5</td>
<td>F6</td>
<td>F7</td>
</tr>

<tr class="page-break">
<td colspan="7">
</tr>

<tr>
<td>G1</td>
<td>G2</td>
<td>G3</td>
<td>G4</td>
<td>G5</td>
<td>G6</td>
<td>G7</td>
</tr>
</table>


进一步阅读 page-break-* 属性:

https://css-tricks.com/almanac/properties/p/page-break/