Як боротися з розривами сторінок під час друку великої таблиці 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.