Как справиться с разрывами страниц при печати большой таблицы HTML

У меня есть проект, который требует печати таблицы HTML со многими строками.

моя проблема в том, как таблица печатается на нескольких страницах. Иногда он разрезает ряд пополам, делая его нечитаемым, потому что одна половина находится на кровоточащем краю страницы, а остальная часть напечатана в верхней части следующей страницы.

единственное правдоподобное решение, о котором я могу думать,-это использование stacked DIVs вместо таблицы и принудительных разрывов страниц, если это необходимо.. но прежде чем пройти через я думал, что смогу попросить об этом раньше.

11 ответов


<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test</title>
<style type="text/css">
    table { page-break-inside:auto }
    tr    { page-break-inside:avoid; page-break-after:auto }
    thead { display:table-header-group }
    tfoot { display:table-footer-group }
</style>
</head>
<body>
    <table>
        <thead>
            <tr><th>heading</th></tr>
        </thead>
        <tfoot>
            <tr><td>notes</td></tr>
        </tfoot>
        <tbody>
        <tr>
            <td>x</td>
        </tr>
        <tr>
            <td>x</td>
        </tr>
        <!-- 500 more rows -->
        <tr>
            <td>x</td>
        </tr>
    </tbody>
    </table>
</body>
</html>

Примечание:при использовании page-break-after: всегда для тега он создаст разрыв страницы после последнего бита таблицы, создавая полностью пустую страницу в конце каждый раз! Чтобы исправить это, просто измените его на page-break-after: auto. Он сломается правильно и не создаст дополнительную пустую страницу.

<html>
<head>
<style>
@media print
{
  table { page-break-after:auto }
  tr    { page-break-inside:avoid; page-break-after:auto }
  td    { page-break-inside:avoid; page-break-after:auto }
  thead { display:table-header-group }
  tfoot { display:table-footer-group }
}
</style>
</head>

<body>
....
</body>
</html>

расширение от решения Sinan Ünür:

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test</title>
<style type="text/css">
    table { page-break-inside:auto }
    div   { page-break-inside:avoid; } /* This is the key */
    thead { display:table-header-group }
    tfoot { display:table-footer-group }
</style>
</head>
<body>
    <table>
        <thead>
            <tr><th>heading</th></tr>
        </thead>
        <tfoot>
            <tr><td>notes</td></tr>
        </tfoot>
        <tr>
            <td><div>Long<br />cell<br />should'nt<br />be<br />cut</div></td>
        </tr>
        <tr>
            <td><div>Long<br />cell<br />should'nt<br />be<br />cut</div></td>
        </tr>
        <!-- 500 more rows -->
        <tr>
            <td>x</td>
        </tr>
    </tbody>
    </table>
</body>
</html>

Кажется, что page-break-inside: avoid в некоторых браузерах учитывается только для блочных элементов, а не для ячейки, таблицы, строки или встроенного блока.

Если вы пытаетесь отобразить: заблокируйте тег TR и используйте там page-break-inside:избегайте, он работает, но путается с макетом таблицы.


ни один из ответов здесь работал для меня в Chrome. AAverin на GitHub создал некоторые полезные JavaScript для этой цели и это сработало для меня:

просто добавьте js в свой код и добавьте класс "splitForPrint" в свою таблицу, и он аккуратно разделит таблицу на несколько страниц и добавит заголовок таблицы на каждую страницу.


используйте эти свойства CSS:

page-break-after

page-break-before 

например:

<html>
<head>
<style>
@media print
{
table {page-break-after:always}
}
</style>
</head>

<body>
....
</body>
</html>

via


недавно я решил эту проблему с хорошим решением.

Css:

.avoidBreak { 
    border: 2px solid;
    page-break-inside:avoid;
}

Js:

function Print(){
    $(".tableToPrint td, .tableToPrint th").each(function(){ $(this).css("width",  $(this).width() + "px")  });
    $(".tableToPrint tr").wrap("<div class='avoidBreak'></div>");
    window.print();
}

работает как шарм!


Я закончил тем, что следовал подходу @vicenteherrera, с некоторыми настройками (которые, возможно, специфичны для bootstrap 3).

в принципе, мы не можем сломать trили tds, потому что они не блочные элементы. Поэтому мы вставляем divs в каждом, и применить наши page-break-* правила против div. Во-вторых, мы добавляем некоторую прокладку в верхнюю часть каждого из этих дивов, чтобы компенсировать любые артефакты стиля.

<style>
    @media print {
        /* avoid cutting tr's in half */
        th div, td div {
            margin-top:-8px;
            padding-top:8px;
            page-break-inside:avoid;
        }
    }
</style>
<script>
    $(document).ready(function(){
        // Wrap each tr and td's content within a div
        // (todo: add logic so we only do this when printing)
        $("table tbody th, table tbody td").wrapInner("<div></div>");
    })
</script>

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


Я проверил много решений, и никто не работал хорошо.

поэтому я попробовал небольшой трюк, и он работает:

tfoot со стилем:position: fixed; bottom: 0px; помещается внизу последней страницы, но если нижний колонтитул слишком высок, он перекрывается содержимым таблицы.

tfoot только: display: table-footer-group; не перекрывается, но не находится в нижней части последней страницы...

давайте поставим два tfoot:

TFOOT.placer {
  display: table-footer-group;
  height: 130px;
}

TFOOT.contenter {
  display: table-footer-group;
  position: fixed;
  bottom: 0px;	
  height: 130px;
}
<TFOOT  class='placer'> 
  <TR>
    <TD>
      <!--  empty here
-->
    </TD>
  </TR>
</TFOOT>	
<TFOOT  class='contenter'> 
  <TR>
    <TD>
      your long text or high image here
    </TD>
  </TR>
</TFOOT>

зарезервировать место на не последние страницы, Второй помещает в ваш accual нижний колонтитул.


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

<table>
    <thead>  <!-- there should be <thead> tag-->
        <td>Heading</td> <!--//inside <thead> should be <td> it should not be <th>-->
    </thead>
    <tbody><!---<tbody>also must-->
        <tr>
            <td>data</td>
        </tr>
        <!--100 more rows-->
    </tbody>
</table>

выше формат протестирован и работает в кросс-браузерах


принятый ответ не работал для меня во всех браузерах, но следующий css работал для меня:

tr    
{ 
  display: table-row-group;
  page-break-inside:avoid; 
  page-break-after:auto;
}

структура html была:

<table>
  <thead>
    <tr></tr>
  </thead>
  <tbody>
    <tr></tr>
    <tr></tr>
    ...
  </tbody>
</table>

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

из-за проблем с заголовком Я в конечном итоге закончил:

#theTable td *
{
  page-break-inside:avoid;
}

это не предотвратило разрыв строк; только каждая ячейка содержание.