Search code examples
htmlcssprintingprinting-web-page

Non Repeating Table Footer That Avoids Breaking Over Printed Pages CSS


So I have a weird situation were I have a table footer that I only need to repeat once so I decided to just add the "footer" trs to the end of the tbody so it would only appear once at the end of the table and look like a footer without the repeating on each printed page.

<table>
    <tbody>
        @foreach(var item in Model.Items)
        {
            <tr><td>@item.Name</td></tr>
            <tr><td>@item.Total</td></tr>
        }
        <tr>
            <td>Total</td>
            <td>@Model.Items.Sum(x  => x.Total)</td>
        </tr>
        <tr>
            <td>Discount</td>
            <td>@(Model.Items.Sum(x => x.Total) / 50)</td>
        </tr>
    </tbody>
</table>

This was fine until Model.Items had enough rows that it pushed the second row of the footer onto the next page when I need to keep the two footer rows together.

I've also tried using the actual tfoot tag like so with a page-break-inside:avoid style.

<table>
    <tbody>
        @foreach (var item in Model.Items)
        {
            <tr><td>@item.Name</td></tr>
            <tr><td>@item.Total</td></tr>
        }
    </tbody>
    <tfoot style="page-break-inside:avoid;">
        <tr>
            <td>Total</td>
            <td>@Model.Items.Sum(x => x.Total)</td>
        </tr>
        <tr>
            <td>Discount</td>
            <td>@(Model.Items.Sum(x => x.Total) / 50)</td>
        </tr>
    </tfoot>
</table>

This kept the footer together but its now repeating on each page instead of once. Someone on another Stack Overflow question suggested using the following style on the tfoot to stop it repeating which worked, but now it ignores the page-break-inside:avoid style.

<tfoot style="display: table-row-group"></tfoot>

Does anyone know how to get a footer to appear once and avoid breaking over multiple printed pages?


Solution

  • I got it working but I had to apply a few styles to make it looks like one table. I put the original footer HTML into a tr > td > table like so:

    <table>
        <tbody>
            @foreach (var item in Model.Items)
            {
                <tr><td>@item.Name</td></tr>
                <tr><td>@item.Total</td></tr>
            }
    
            <tr style="page-break-inside:avoid;">
                <td colspan="2">
                    <table>
                        <tr>
                            <td>Total</td>
                            <td>@Model.Items.Sum(x => x.Total)</td>
                        </tr>
                        <tr>
                            <td>Discount</td>
                            <td>@(Model.Items.Sum(x => x.Total) / 50)</td>
                        </tr>
                    </table>
                </td>
            </tr>
        </tbody>
    </table>
    

    This allowed the footer to stay together while only appearing once at the end of the page.