Posiadanie nagłówków tabeli powtórzeń Google Chrome na drukowanych stronach

Chciałbym, aby nagłówki tabeli były powtarzane dla każdej wydrukowanej strony, ale wygląda na to, że Google Chrome nie obsługuje tagu <thead> well...is jest jakiś sposób na obejście tego? Używam Google Chrome v13. 0. 782. 215.

Kod tabeli jest bardzo prosty...nic ciekawego:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <style type="text/css" media="all">
           @page {
              size: landscape;
              margin-top: 0;
              margin-bottom: 1cm;
              margin-left: 0;
              margin-right: 0;
           }
           table {
               border: .02em solid #666; border-collapse:collapse; 
               width:100%; 
           }
           td, th {
               border: .02em solid #666; font-size:12px; line-height: 12px; 
               vertical-align:middle; padding:5px; font-family:"Arial";
           }
           th { text-align:left; font-size:12px; font-weight:bold; }
           h2 { margin-bottom: 0; }
       </style>
   </head>
   <body>
   <h2>Page Title</h2>
   <table>
       <thead>
           <tr class="row1">
               <th><strong>Heading 1</strong></th>
               <th><strong>Heading 2</strong></th>
               <th><strong>Heading 3</strong></th>
               <th><strong>Heading 4</strong></th>
               <th><strong>Heading 5</strong></th>
           </tr>
       </thead>
       <tbody>
           <tr class="row2">
              <td width="30">...</td>
              <td width="30">...</td>
              <td width="90">....</td>
              <td width="190">...</td>
              <td width="420">...</td>
           </tr>
           <tr class="row1">
              <td width="30">...</td>
              <td width="30">...</td>
              <td width="90">....</td>
              <td width="190">...</td>
              <td width="420">...</td>
           </tr>
           ....
       </tbody>
   </table>
   </body>
</html>
Każdy wgląd w to jest mile widziany.
Author: Sᴀᴍ Onᴇᴌᴀ, 2011-08-26

7 answers

Wydaje mi się, że to błąd w Chrome.

 39
Author: Arif Uddin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-18 04:49:08

Aktualizacja 2017-03-22: powtarzające się nagłówki tabeli zostały w końcu zaimplementowane w Chrome! (właściwie, myślę, że zostały wdrożone jakiś czas temu.) Oznacza to, że prawdopodobnie nie potrzebujesz już tego rozwiązania; po prostu umieść nagłówki kolumn w znaczniku <thead> i powinieneś być ustawiony. Użyj poniższego roztworu tylko wtedy, gdy:

    [[26]}w implementacji Chrome napotkasz błędy zatrzymujące pokazy,
  • potrzebujesz "funkcji bonusowych", lub
  • musisz wspierać jakiegoś dziwaka przeglądarka, która nadal nie obsługuje powtarzających się nagłówków.

Rozwiązanie (przestarzałe)

Poniższy kod pokazuje najlepszą metodę, jaką znalazłem dla wielostronicowego drukowania tabel. Posiada następujące cechy:

  • nagłówki kolumn powtarzają się na każdej stronie
  • Nie musisz się martwić o rozmiar papieru ani liczbę wierszy-przeglądarka obsługuje wszystko automatycznie]}
  • podziały stron występują tylko między wierszami
  • granice komórek są zawsze w pełni zamknięte
  • Jeśli w górnej części tabeli pojawi się przerwa na stronie, nie zostanie osierocony podpis lub nagłówki kolumn bez dołączonych danych (problem, który nie ogranicza się tylko do Chrome) [27]}
  • Działa w Chrome! (i inne przeglądarki oparte na Webkit, takie jak Safari i Opera)

... i następujące znane ograniczenia:

  • obsługuje tylko 1 <thead> (co najwyraźniej jest najbardziej wolno mieć w każdym razie)
  • nie obsługuje [10]} (chociaż chromowane stopki do biegania są technicznie możliwe )
  • obsługuje tylko wyrównane do góry <caption>
  • tabela nie może mieć górnej lub dolnej margin; aby dodać białą spację powyżej lub poniżej tabeli, Wstaw pusty div I ustaw na niej dolny margines
  • wszelkie wartości rozmiaru CSS, które wpływają na wysokość (w tym border-width i line-height) muszą być w px
  • Szerokości kolumn nie można ustawić, stosując wartości szerokości do poszczególnych komórek tabeli; należy albo pozwolić zawartość komórki automatycznie określa szerokość kolumny lub użyj <col>s, aby ustawić określone szerokości w razie potrzeby

  • Tabela nie może (łatwo) być zmieniana dynamicznie po uruchomieniu JS

KOD

<!DOCTYPE html>
<html>
  <body>
    <table class="print t1"> <!-- Delete "t1" class to remove row numbers. -->
      <caption>Print-Friendly Table</caption>
      <thead>
        <tr>
          <th></th>
          <th>Column Header</th>
          <th>Column Header</th>
          <th>Multi-Line<br/>Column<br/>Header</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td></td>
          <td>data</td>
          <td>Multiple<br/>lines of<br/>data</td>
          <td>data</td>
        </tr>
      </tbody>
    </table>
  </body>
</html>

<style>
  /* THE FOLLOWING CSS IS REQUIRED AND SHOULD NOT BE MODIFIED. */
    div.fauxRow {
      display: inline-block;
      vertical-align: top;
      width: 100%;
      page-break-inside: avoid;
    }
    table.fauxRow {border-spacing: 0;}
    table.fauxRow > tbody > tr > td {
      padding: 0;
      overflow: hidden;
    }
    table.fauxRow > tbody > tr > td > table.print {
      display: inline-table;
      vertical-align: top;
    }
    table.fauxRow > tbody > tr > td > table.print > caption {caption-side: top;}
    .noBreak {
      float: right;
      width: 100%;
      visibility: hidden;
    }
    .noBreak:before, .noBreak:after {
      display: block;
      content: "";
    }
    .noBreak:after {margin-top: -594mm;}
    .noBreak > div {
      display: inline-block;
      vertical-align: top;
      width:100%;
      page-break-inside: avoid;
    }
    table.print > tbody > tr {page-break-inside: avoid;}
    table.print > tbody > .metricsRow > td {border-top: none !important;}

  /* THE FOLLOWING CSS IS REQUIRED, but the values may be adjusted. */
    /* NOTE: All size values that can affect an element's height should use the px unit! */
    table.fauxRow, table.print {
      font-size: 16px;
      line-height: 20px;
    }

  /* THE FOLLOWING CSS IS OPTIONAL. */
    body {counter-reset: t1;} /* Delete to remove row numbers. */
    .noBreak .t1 > tbody > tr > :first-child:before {counter-increment: none;} /* Delete to remove row numbers. */
    .t1 > tbody > tr > :first-child:before { /* Delete to remove row numbers. */
      display: block;
      text-align: right;
      counter-increment: t1 1;
      content: counter(t1);
    }
    table.fauxRow, table.print {
      font-family: Tahoma, Verdana, Georgia; /* Try to use fonts that don't get bigger when printed. */
      margin: 0 auto 0 auto; /* Delete if you don't want table to be centered. */
    }
    table.print {border-spacing: 0;}
    table.print > * > tr > * {
      border-right: 2px solid black;
      border-bottom: 2px solid black;
      padding: 0 5px 0 5px;
    }
    table.print > * > :first-child > * {border-top: 2px solid black;}
    table.print > thead ~ * > :first-child > *, table.print > tbody ~ * > :first-child > * {border-top: none;}
    table.print > * > tr > :first-child {border-left: 2px solid black;}
    table.print > thead {vertical-align: bottom;}
    table.print > thead > .borderRow > th {border-bottom: none;}
    table.print > tbody {vertical-align: top;}
    table.print > caption {font-weight: bold;}
</style>

<script>
  (function() { // THIS FUNCTION IS NOT REQUIRED. It just adds table rows for testing purposes.
    var rowCount = 100
      , tbod = document.querySelector("table.print > tbody")
      , row = tbod.rows[0];
    for(; --rowCount; tbod.appendChild(row.cloneNode(true)));
  })();

  (function() { // THIS FUNCTION IS REQUIRED.
    if(/Firefox|MSIE |Trident/i.test(navigator.userAgent))
      var formatForPrint = function(table) {
        var noBreak = document.createElement("div")
          , noBreakTable = noBreak.appendChild(document.createElement("div")).appendChild(table.cloneNode())
          , tableParent = table.parentNode
          , tableParts = table.children
          , partCount = tableParts.length
          , partNum = 0
          , cell = table.querySelector("tbody > tr > td");
        noBreak.className = "noBreak";
        for(; partNum < partCount; partNum++) {
          if(!/tbody/i.test(tableParts[partNum].tagName))
            noBreakTable.appendChild(tableParts[partNum].cloneNode(true));
        }
        if(cell) {
          noBreakTable.appendChild(cell.parentNode.parentNode.cloneNode()).appendChild(cell.parentNode.cloneNode(true));
          if(!table.tHead) {
            var borderRow = document.createElement("tr");
            borderRow.appendChild(document.createElement("th")).colSpan="1000";
            borderRow.className = "borderRow";
            table.insertBefore(document.createElement("thead"), table.tBodies[0]).appendChild(borderRow);
          }
        }
        tableParent.insertBefore(document.createElement("div"), table).style.paddingTop = ".009px";
        tableParent.insertBefore(noBreak, table);
      };
    else
      var formatForPrint = function(table) {
        var tableParent = table.parentNode
          , cell = table.querySelector("tbody > tr > td");
        if(cell) {
          var topFauxRow = document.createElement("table")
            , fauxRowTable = topFauxRow.insertRow(0).insertCell(0).appendChild(table.cloneNode())
            , colgroup = fauxRowTable.appendChild(document.createElement("colgroup"))
            , headerHider = document.createElement("div")
            , metricsRow = document.createElement("tr")
            , cells = cell.parentNode.cells
            , cellNum = cells.length
            , colCount = 0
            , tbods = table.tBodies
            , tbodCount = tbods.length
            , tbodNum = 0
            , tbod = tbods[0];
          for(; cellNum--; colCount += cells[cellNum].colSpan);
          for(cellNum = colCount; cellNum--; metricsRow.appendChild(document.createElement("td")).style.padding = 0);
          cells = metricsRow.cells;
          tbod.insertBefore(metricsRow, tbod.firstChild);
          for(; ++cellNum < colCount; colgroup.appendChild(document.createElement("col")).style.width = cells[cellNum].offsetWidth + "px");
          var borderWidth = metricsRow.offsetHeight;
          metricsRow.className = "metricsRow";
          borderWidth -= metricsRow.offsetHeight;
          tbod.removeChild(metricsRow);
          tableParent.insertBefore(topFauxRow, table).className = "fauxRow";
          if(table.tHead)
            fauxRowTable.appendChild(table.tHead);
          var fauxRow = topFauxRow.cloneNode(true)
            , fauxRowCell = fauxRow.rows[0].cells[0];
          fauxRowCell.insertBefore(headerHider, fauxRowCell.firstChild).style.marginBottom = -fauxRowTable.offsetHeight - borderWidth + "px";
          if(table.caption)
            fauxRowTable.insertBefore(table.caption, fauxRowTable.firstChild);
          if(tbod.rows[0])
            fauxRowTable.appendChild(tbod.cloneNode()).appendChild(tbod.rows[0]);
          for(; tbodNum < tbodCount; tbodNum++) {
            tbod = tbods[tbodNum];
            rows = tbod.rows;
            for(; rows[0]; tableParent.insertBefore(fauxRow.cloneNode(true), table).rows[0].cells[0].children[1].appendChild(tbod.cloneNode()).appendChild(rows[0]));
          }
          tableParent.removeChild(table);
        }
        else
          tableParent.insertBefore(document.createElement("div"), table).appendChild(table).parentNode.className="fauxRow";
      };
    var tables = document.body.querySelectorAll("table.print")
      , tableNum = tables.length;
    for(; tableNum--; formatForPrint(tables[tableNum]));
  })();
</script>

Jak to działa (Jeśli cię to nie obchodzi, Czytaj dalej; wszystko, czego potrzebujesz, jest powyżej.)

Na prośbę @ Kingsolmn, poniżej znajduje się wyjaśnienie, jak to rozwiązanie działa. Nie obejmuje JavaScript, który nie jest ściśle wymagane (choć to czyni tę technikę znacznie łatwiejszą w użyciu). Zamiast tego skupia się na generowanych strukturach HTML i powiązanych CSS, gdzie dzieje się prawdziwa magia.

Oto tabela, z którą będziemy pracować:

<table>
  <tr><th>ColumnA</th><th>ColumnB</th></tr>
  <tr><td>row1</td><td>row1</td></tr>
  <tr><td>row2</td><td>row2</td></tr>
  <tr><td>row3</td><td>row3</td></tr>
</table>

(aby zaoszczędzić miejsce, dałem mu tylko 3 wiersze danych; oczywiście tabela wielostronicowa Zwykle miałaby więcej)

Pierwszą rzeczą, którą musimy zrobić, to podzielić stół na serię mniejszych tabel, z których każda ma własną kopię nagłówków kolumn. Nazywam te mniejsze tabele sztucznymi wierszami .

<table> <!-- fauxRow -->
  <tr><th>ColumnA</th><th>ColumnB</th></tr>
  <tr><td>row1</td><td>row1</td></tr>
</table>

<table> <!-- fauxRow -->
  <tr><th>ColumnA</th><th>ColumnB</th></tr>
  <tr><td>row2</td><td>row2</td></tr>
</table>

<table> <!-- fauxRow -->
  <tr><th>ColumnA</th><th>ColumnB</th></tr>
  <tr><td>row3</td><td>row3</td></tr>
</table>

FauxRows są zasadniczo klonami oryginalnej tabeli, ale z tylko jednym wierszem danych na sztukę. (Jeśli jednak twój stół ma podpis, tylko górny fauxRow powinien go zawierać.)

Następnie musimy sprawić, by sztućce były niezniszczalne . Co to znaczy? (Zwróć uwagę - jest to prawdopodobnie najważniejsza koncepcja w obsłudze łamania stron.) "Unbreakable" to określenie I użyj do opisania bloku treści, którego nie można podzielić na dwie strony*. Gdy w przestrzeni zajmowanej przez taki blok dochodzi do podziału strony, cały blok przechodzi do następnej strony. (Zauważ, że używam tu nieformalnie słowa "blok"; jestem , a nie odnoszącym się konkretnie do elementów poziomu bloku.) To zachowanie ma interesujący efekt uboczny, który wykorzystamy później: może ujawniać zawartość, która początkowo była ukryta z powodu warstw lub przepełnienia.

Możemy aby sztuczki były niełamliwe, zastosuj jedną z następujących deklaracji CSS:

  • page-break-inside: avoid;
  • display: inline-table;

Zwykle używam obu, ponieważ pierwsza jest stworzona do tego celu, a druga działa w starszych/niezgodnych przeglądarkach. W tym przypadku jednak, dla uproszczenia, będę trzymać się właściwości podziału strony. Zauważ, że po dodaniu tej właściwości nie zobaczysz żadnych zmian w wyglądzie tabeli.

<table style="page-break-inside: avoid;"> <!-- fauxRow -->
      <tr><th>ColumnA</th><th>ColumnB</th></tr>
      <tr><td>row1</td><td>row1</td></tr>
    </table>
    
    <table style="page-break-inside: avoid;"> <!-- fauxRow -->
      <tr><th>ColumnA</th><th>ColumnB</th></tr>
      <tr><td>row2</td><td>row2</td></tr>
    </table>
    
    <table style="page-break-inside: avoid;"> <!-- fauxRow -->
      <tr><th>ColumnA</th><th>ColumnB</th></tr>
      <tr><td>row3</td><td>row3</td></tr>
    </table>

Teraz, gdy fauxRows są niełamliwe, jeśli podział strony nastąpi w wierszu danych, przejdzie do następnej strony wraz z dołączonym wierszem nagłówka. Więc Następna strona zawsze będzie miała nagłówki kolumn na górze, co jest naszym celem. Ale tabela wygląda teraz bardzo dziwnie ze wszystkimi dodatkowymi wierszami nagłówka. Aby znów wyglądać jak normalna tabela, musimy ukryć dodatkowe nagłówki w taki sposób, aby pojawiały się tylko wtedy, gdy są potrzebne.

Co zrobimy, to umieścimy każdą sztuczkę w elemencie pojemnika z overflow: hidden; a następnie przesuń go w górę, aby nagłówki zostały przycięte przez górną część kontenera. Spowoduje to również przeniesienie wierszy danych z powrotem do siebie, tak aby wyglądały sąsiadujące.

Twoim pierwszym instynktem może być użycie div dla kontenerów, ale zamiast tego użyjemy komórek tabeli nadrzędnej. Wyjaśnię później, ale na razie dodajmy kod. (Po raz kolejny nie wpłynie to na wygląd stołu.)

table {
  border-spacing: 0;
  line-height: 20px;
}
th, td {
  padding-top: 0;
  padding-bottom: 0;
}
<table> <!-- parent table -->
  <tr>
    <td style="overflow: hidden;">

      <table style="page-break-inside: avoid;"> <!-- fauxRow -->
        <tr><th>ColumnA</th><th>ColumnB</th></tr>
        <tr><td>row1</td><td>row1</td></tr>
      </table>

    </td>
  </tr>
  <tr>
    <td style="overflow: hidden;">

      <table style="page-break-inside: avoid;"> <!-- fauxRow -->
        <tr><th>ColumnA</th><th>ColumnB</th></tr>
        <tr><td>row2</td><td>row2</td></tr>
      </table>

    </td>
  </tr>
  <tr>
    <td style="overflow: hidden;">

      <table style="page-break-inside: avoid;"> <!-- fauxRow -->
        <tr><th>ColumnA</th><th>ColumnB</th></tr>
        <tr><td>row3</td><td>row3</td></tr>
      </table>

    </td>
  </tr>
</table>

Zwróć uwagę na CSS powyżej znaczniki tabeli. Dodałem go z dwóch powodów: po pierwsze, uniemożliwia tabeli nadrzędnej dodawanie białych spacji między fauxRows; po drugie, sprawia, że wysokość nagłówka jest przewidywalna, co jest konieczne, ponieważ nie używamy JavaScript, aby obliczyć ją dynamicznie.

Teraz musimy przesunąć sztuczki w górę, co zrobimy z ujemnymi marżami. Ale to nie jest takie proste, jak mogłoby się wydawać. Jeśli dodamy ujemny margines bezpośrednio do fauxRow, pozostanie on w mocy, gdy fauxRow dostanie do następnej strony, powodując przycinanie nagłówków u góry strony. Potrzebujemy sposobu na pozostawienie negatywnego marginesu.

Aby to osiągnąć, umieścimy pusty div nad każdym fauxrowem po pierwszym i dodamy do niego ujemny margines. (Pierwszy fauxRow jest pomijany, ponieważ jego nagłówki powinny być zawsze widoczne.) Ponieważ margines znajduje się na oddzielnym elemencie, nie będzie podążał za fauxrowem do następnej strony, a nagłówki nie zostaną przycięte. Nazywam te puste divy headerHiders .

table {
  border-spacing: 0;
  line-height: 20px;
}
th, td {
  padding-top: 0;
  padding-bottom: 0;
}
<table> <!-- parent table -->
  <tr>
    <td style="overflow: hidden;">

      <table style="page-break-inside: avoid;"> <!-- fauxRow -->
        <tr><th>ColumnA</th><th>ColumnB</th></tr>
        <tr><td>row1</td><td>row1</td></tr>
      </table>

    </td>
  </tr>
  <tr>
    <td style="overflow: hidden;">

      <div style="margin-bottom: -20px;"></div> <!-- headerHider -->

      <table style="page-break-inside: avoid;"> <!-- fauxRow -->
        <tr><th>ColumnA</th><th>ColumnB</th></tr>
        <tr><td>row2</td><td>row2</td></tr>
      </table>

    </td>
  </tr>
  <tr>
    <td style="overflow: hidden;">

      <div style="margin-bottom: -20px;"></div> <!-- headerHider -->

      <table style="page-break-inside: avoid;"> <!-- fauxRow -->
        <tr><th>ColumnA</th><th>ColumnB</th></tr>
        <tr><td>row3</td><td>row3</td></tr>
      </table>

    </td>
  </tr>
</table>
Koniec z nami! Na ekranie tabela powinna teraz wyglądać normalnie, z tylko jednym zestawem nagłówków kolumn na górze. W druku powinien teraz mieć uruchomione nagłówki.

Jeśli zastanawiałeś się, dlaczego użyliśmy tabeli nadrzędnej zamiast kilku kontenerów div, to dlatego, że Chrome / webkit ma błąd, który powoduje, że zamknięty w div nierozerwalny blok przenosi swój kontener do następnej strony. Ponieważ headerHider jest również w pojemniku nie zostanie pozostawiony tak, jak powinien, co prowadzi do przyciętych nagłówków. Ten błąd występuje tylko wtedy, gdy nierozerwalny blok jest najwyższym elementem w div o niezerowej wysokości.

Odkryłem obejście podczas pisania tego samouczka: musisz tylko jawnie ustawić height: 0; na headerhiderze i dać mu pusty dziecięcy div o niezerowej wysokości. Następnie możesz użyć kontenera div. Nadal jednak wolę używać tabeli nadrzędnej, ponieważ była ona bardziej dokładnie przetestowany, a to ratuje semantykę do pewnego stopnia, wiążąc sztuczki z powrotem razem w jednym stole.

EDIT: właśnie zdałem sobie sprawę, że znaczniki generowane przez JavaScript są nieco inne, ponieważ umieszcza każdy fauxRow w osobnej tabeli kontenerów i przypisuje mu nazwę klasy "fauxRow" (kontener). Byłoby to wymagane dla obsługi stopki, którą zamierzałem kiedyś dodać, ale nigdy tego nie zrobiłem. Gdybym miał zaktualizować JS, mógłbym rozważyć przejście na div kontenery, ponieważ moje semantyczne uzasadnienie użycia tabeli nie ma zastosowania.

* jest jedna sytuacja, w której niezniszczalny blok może być podzielony między dwie strony: gdy przekroczy wysokość drukowanego obszaru. Powinieneś unikać tego scenariusza; zasadniczo prosisz przeglądarkę, aby zrobiła to, co niemożliwe, i może to mieć bardzo dziwne skutki na wyjściu.

 51
Author: DoctorDestructo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-08 22:40:39

Teraz możliwe jest drukowanie w chrome przy użyciu jQuery.... proszę wypróbuj ten kod (przepraszam zapomnij kto jest twórcą tego kodu zanim zmodyfikowałem - a mój język angielski nie jest dobry :d hehehe)

            <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
            <html>
            <head>
                <title>DOCUMENT TITLE</title>
                <link rel="stylesheet" type="text/css" href="assets/css/bootstrap.css"/>
                <style type="text/css">
                    @media print{
                        table { page-break-after:auto;}
                        tr    { page-break-inside:avoid;}
                        td    { page-break-inside:auto;}
                        thead { display:table-header-group }

                        .row-fluid [class*="span"] {
                          min-height: 20px;
                        }
                    }

                    @page { 
                        margin-top: 1cm;
                        margin-right: 1cm;
                        margin-bottom:2cm;
                        margin-left: 2cm;';
                        size:portrait;
                        /*
                        size:landscape;
                        -webkit-transform: rotate(-90deg); -moz-transform:rotate(-90deg);
                        filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);
                        */

                    };
                </style>
            </head>
            <body>
                <div id="print-header-wrapper">
                    <div class="row-fluid">HEADER TITLE 1</div>
                    <div class="row-fluid">HEADER TITLE 2</div>
                </div>
                <div class="row-fluid" id="print-body-wrapper">
                    <table class="table" id="table_data">
                        <thead>
                            <tr><th>TH 1</th><th>TH 2</th></tr>
                        </thead>
                        <tbody>
                            <tr><td>TD 1</td><td>TD 2</td></tr>
                            <tr><td>TD 1</td><td>TD 2</td></tr>
                            <tr><td>TD 1</td><td>TD 2</td></tr>
                            <tr><td>TD 1</td><td>TD 2</td></tr>
                            <tr><td>TD 1</td><td>TD 2</td></tr>
                            <tr><td>TD 1</td><td>TD 2</td></tr>
                            <tr><td>TD 1</td><td>TD 2</td></tr>
                            <tr><td>TD 1</td><td>TD 2</td></tr>
                            <tr><td>TD 1</td><td>TD 2</td></tr>
                            <tr><td>TD 1</td><td>TD 2</td></tr>
                            <tr><td>TD 1</td><td>TD 2</td></tr>
                            <tr><td>TD 1</td><td>TD 2</td></tr>
                            <tr><td>TD 1</td><td>TD 2</td></tr>
                            <tr><td>TD 1</td><td>TD 2</td></tr>
                            <tr><td>TD 1</td><td>TD 2</td></tr>
                            <tr><td>TD 1</td><td>TD 2</td></tr>
                        </tbody>
                    </table>
                    <div id="lastDataTable"></div>
                </div>
                <script type="text/javascript">
                    jQuery(document).ready(function()
                    {
                        var printHeader = $('#print-header-wrapper').html();
                        var div_pageBreaker = '<div style="page-break-before:always;"></div>';
                        var per_page = 25;
                        $('#table_data').each(function(index, element)
                        {
                            //how many pages of rows have we got?
                            var pages = Math.ceil($('tbody tr').length / per_page);

                            //if we only have one page no more
                            if (pages == 1) {
                                return;
                            }
                            //get the table we're splutting
                            var table_to_split = $(element);

                            var current_page   = 1;
                            //loop through each of our pages
                            for (current_page = 1; current_page <= pages; current_page++) 
                            {
                                //make a new copy of the table
                                var cloned_table = table_to_split.clone();
                                //remove rows on later pages
                                $('tbody tr', table_to_split).each(function(loop, row_element) {
                                    //if we've reached our max
                                    if (loop >= per_page) {
                                        //get rid of the row
                                        $(row_element).remove();
                                    }
                                });

                                //loop through the other copy
                                $('tbody tr', cloned_table).each(function(loop, row_element) {
                                    //if we are before our current page
                                    if (loop < per_page) {
                                        //remove that one
                                        $(row_element).remove();
                                    }
                                });

                                //insert the other table afdter the copy
                                if (current_page < pages) {
                                    $(div_pageBreaker).appendTo('#lastDataTable');
                                    $(printHeader).appendTo('#lastDataTable');
                                    $(cloned_table).appendTo('#lastDataTable');
                                }

                                //make a break
                                table_to_split = cloned_table;
                            }
                        });
                    });
                </script>
              </body>
            </html>
 4
Author: thefredzx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-28 08:20:59

Jest to ulepszenie nadal niedostępne w Webkit, Blink i Vivliostyle, a nie w innych "formaterach zorientowanych na drukowanie" (Firefox, IE).

Możesz sprawdzić problem dla Google Chrome od wersji 4 tutaj (6 lat i 45 wersji temu!) , gdzie możemy docenić, że ma właściciela ostatnio (luty 2016), który nawet wydaje się nad nim pracować.

Niektóre rozmowy odbyły się również w W3 gdzie możemy docenić troskę o to, użyteczność:

Od powtarzania nagłówków tabeli i stopek na Przerwa na fragmentację jest ogólnie przydatna, proponuję zrobić wymóg normatywny i powiedzieć, że UAs musi powtarzać wiersze nagłówka / stopki kiedy stół ma przerwę.

Tymczasem kody JS i Jquery z @ DoctorDestructo i @thefredzx były naprawdę przydatne dla moich użytkowników nie korzystających z Firefoksa ani IE (większość z nich).

Pierwszy, który wie o nowej wersji, która zawiera ten cecha, powinien zauważyć to tutaj, wielu z nas by to docenić.

 2
Author: DavidTaubmann,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-30 01:48:36

Z mojego ustawienia testowania w chrome display: table-row-group; do thead zatrzymuje problem.

Np jeśli spróbujesz wydrukować poniżej bez stylu zobaczysz numer na górze każdej strony, ale jeśli dodasz styl, pojawia się tylko oncontextmenu.

<style>
  thead {
      display: table-row-group;
  }
</style>
<table>
  <thead>
    <tr>
      <th>number</th>
    </tr>
  </thead>
  <tbody id="myTbody">
  </tbody>
</table>
<script>
  for (i = 1; i <= 100; i++) {
    document.getElementById("myTbody").innerHTML += "<tr><td>" + i + "</td></tr>";
  }
</script>
 1
Author: ak85,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-07 01:42:51

Uwaga Z 2019 roku: Miałem problemy przez wiele godzin, miałem obraz w nagłówku

<table>
 <thead>
    <tr>
      <td>
        <img ...>
      </td>

Który był wyświetlany tylko na pierwszej stronie.

Przyczyna: Chrome dodaje styl @media print { img { page-break-inside: avoid !important; } }

To powodowało, że obraz nie wyświetlał się na stronie 2 i dalej!

Rozwiązanie: Więc po prostu wstaw regułę

@media print { thead img { page-break-inside: auto !important; } }

Aby wyłączyć tę regułę specyficzną dla przeglądarki.

 0
Author: olidem,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-10-19 11:22:00

W przypadku firmowych systemów opartych na przeglądarkach radzę użytkownikom używać Firefoksa lub IE; w przypadku stron internetowych przeznaczonych dla ogółu, myślę, że nie możemy nic z tym zrobić, jeśli użytkownicy korzystają z chrome lub przeglądarek o podobnych ograniczeniach (również opera)

 -3
Author: Manny,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-18 10:32:29