Як боротися з розривами сторінок під час друку великої таблиці HTML


261

У мене є проект, який вимагає друкувати таблицю HTML з багатьма рядками.

Моя проблема полягає в тому, як надрукована таблиця на декількох сторінках. Іноді він скоротить рядок навпіл, зробивши його нечитабельним, оскільки одна половина знаходиться на крайовому краю сторінки, а решта надрукується у верхній частині наступної сторінки.

Єдиним правдоподібним рішенням, про яке я можу придумати, є використання складених DIV-файлів замість таблиці та примусовий розрив сторінки, якщо це потрібно .., але перед тим, як пройти всю зміну, я подумав, що я міг би запитати тут раніше.


28
У дотичній формі, можливо, варто додати <thead>таблицю до таблиці з наступним css thead {display: table-header-group; }, щоб надрукувати заголовок таблиці на всіх наступних сторінках (корисно для таблиць даних loooooong).
Девід каже повернути Моніку

Відповіді:


277
<!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>

18
Це також не в браузерах WebKit (наприклад, Safari та Chrome)
Michael Haren

5
Хоча це стандартний спосіб зробити це, єдиний браузер, який зараз реалізує стандарт, - це Opera. Зауважте, що це є частиною css2, і тому відсутність реалізації може бути проблемою на деякий час, тому що, очевидно, ніхто не переймається.
pkh

16
Специфікація CSS 2.1 вказує, що атрибути стилю розриву сторінки застосовуються лише до елементів рівня блоку. Режим відображення за замовчуванням для рядків таблиці є рядком таблиці. На жаль, жодні елементи таблиці за замовчуванням не є елементами рівня блоку, включаючи саму таблицю.
lsuarez

2
@ SinanÜnür Це не вимога, тому ви не можете покластися на неї, і, на жаль, з мого тестування я бачу, що веб-кайт бачив "може" і ігнорував що-небудь поза ним. Як не дивно, у IE є досить приємна велика підтримка друку настільних таблиць. Ніколи не думав, що я заспіваю його похвали в будь-який момент
lsuarez

6
Я можу підтвердити, що це НЕ працює нормально в Chrome або будь-якому іншому веб-переглядачі Webkit (наприклад, Safari, Opera) - якщо тільки, під "працює нормально" ви маєте на увазі "виключає будь-які функції, які вважаються необов'язковими". Я думаю, що більшість людей хочуть - це заголовки та колонтитули та таблиці, які дозволяють розбивати сторінки лише між рядками, жодна з яких не реалізована в Webkit станом на 2015/11/13.
DoctorDestructo

47

Примітка. При використанні розбиття сторінки: після тегу завжди буде створено розрив сторінки після останнього біта таблиці, створюючи абсолютно порожню сторінку в кінці кожного разу! Щоб виправити це, просто змініть його на перерву на сторінку: 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>

Підходить для мене на Chrome і це приємне звичайне рішення CSS.
Райан

1
Я намагаюся таке ж рішення, але воно не порушує дані таблиці і не зникає зайвих даних, а не відображає їх на наступній сторінці. Будь-які здогадки?
Null Pointer

24

Розширення від рішення 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в деяких браузерах враховується лише елементи блоку, а не комірка, таблиця, рядок, а також рядки-рядки.

Якщо спробувати display:blockв TRтезі, і використовувати там page-break-inside:avoid, він працює, але мур навколо з вашої сервірування столу.


2
Ось простий спосіб динамічно додавати діви за допомогою jquery:$(document).ready(function(){$("table tbody th, table tbody td").wrapInner("<div></div>");});
Chris Bloom

1
Завдяки sinan ürün, vicenteherrera та Chrisbloom7. Я застосував поєднання ваших відповідей, і це зараз працює!
Нурхак Кая

Ви можете спробувати встановити @media CSS на " tr { display: block; }Тільки для друку", а не додавати всі сторонні <div>елементи. (Не перевірений, але варто подивитися)
Stephen R

11

Жодна відповідь тут не працювала для мене в Chrome. AAverin на GitHub створив для цього корисний Javascript, і це працювало для мене:

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


Чи є у вас зразок, як це застосувати? Я намагався призначити свою таблицю className як, splitForPrintале в JS ніде не було посилання на елемент за допомогою className splitForPrint. Тільки та частина, var splitClassName = 'splitForPrint';але це все.
Compaq LE2202x

Даун проголосував через те, що сценарій, з яким ви пов'язуєтесь, не вирішує проблему ОП без значного вибору та переналаштування, і ви не надали жодних прикладів того, як можна зробити це.
Кріс Блум

Працювало як шарм для мене, жодне з інших рішень не спрацювало. +1 Довелося додати трохи css, щоб отримати правильні розриви .page-break {page-break-after: always; }
fhugas

Так, додаючи .page-break {page-break-after: завжди; } це врятувало мені день!
milodky

7

Використовуйте ці властивості CSS:

page-break-after

page-break-before 

Наприклад:

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

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

через


Я не впевнений, вам доведеться перевірити. Якщо ні, розділіть їх на різні масиви та відокремте масиви порожнім
дівом

Вам доведеться застосувати це до рядка таблиці або навіть комірки, але не до таблиці, я думаю. Крім цього, це повинно працювати.
Pekka

2
не працює в хромі. Ігнорується так, ніби 13.6.2012 при
зверненні

5

Нещодавно я вирішив цю проблему хорошим рішенням.

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

Працює як шарм!


2

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

В основному; ми не можемо зламати trs або 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>

Коригування поля та накладки були необхідні для компенсації якогось тремтіння, яке впроваджувалося (на мою здогадку - з завантажувальної програми). Я не впевнений, що я пропоную будь-яке нове рішення з інших відповідей на це питання, але думаю, можливо, це комусь допоможе.


1

Я зіткнувся з однією і тією ж проблемою і всюди шукаю рішення, нарешті, я знаходжу щось, що працює для мене для кожного браузера.

html {
height: 0;
}

використовувати цей css або Замість css ви можете мати цей javascript

$("html").height(0);

Сподіваюсь, що це спрацює і для вас.


0

Я перевірив багато рішень і ніхто не працював добре.

Тому я спробував невеликий трюк, і він працює:

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

tfoot with only: display: table-footer-group; не перекривається, але не знаходиться внизу останньої сторінки ...

Покладемо дві ноги:

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>

Один резервує місце на останніх сторінках, другий розміщує у вашій нижній колонтитулі.


-1

Я спробував усі запропоновані вище пропозиції і знайшов просте і працююче крос-браузерне рішення цієї проблеми. Для цього рішення не потрібні стилі чи розрив сторінки. Для рішення формат таблиці повинен бути таким:

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

Вище перевірений формат і працює в крос-браузерах


-2

Ну, хлопці ... Більшість рішень тут не працювали. Тож ось як на мене спрацювали речі ..

HTML

<table>
  <thead>
   <tr>
     <th style="border:none;height:26px;"></th>
     <th style="border:none;height:26px;"></th>
     .
     .
   </tr>
   <tr>
     <th style="border:1px solid black">ABC</th>
     <th style="border:1px solid black">ABC</th>
     .
     .
   <tr>
  </thead>
<tbody>

    //YOUR CODE

</tbody>
</table>

Перший набір заголовка використовується як манекен, щоб у другому заголовку (тобто оригінальній заголовку) не було відсутньої верхньої межі під час розриву сторінки.


-3

Прийнята відповідь не працювала для мене у всіх браузерах, але наступний 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;
}

Це не заважало рядкам ламатися; лише вміст кожної комірки.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.