Come gestire le interruzioni di pagina durante la stampa di una tabella HTML di grandi dimensioni


261

Ho un progetto che richiede la stampa di una tabella HTML con molte righe.

Il mio problema è il modo in cui la tabella viene stampata su più pagine. Talvolta taglierà una riga a metà, rendendola illeggibile perché una metà si trova sul bordo inferiore di una pagina e il resto viene stampato nella parte superiore della pagina successiva.

L'unica soluzione plausibile a cui riesco a pensare è usare DIV in pila invece di una tabella e forzare le interruzioni di pagina, se necessario ... ma prima di affrontare l'intero cambiamento, pensavo di poter chiedere qui prima.


28
Su una tangente, potrebbe valere la pena aggiungere un <thead>alla tua tabella con i seguenti CSS in thead {display: table-header-group; }modo da stampare l'intestazione della tabella su tutte le pagine successive (utile per le tabelle di dati loooooong).
David dice di reintegrare Monica il

Risposte:


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
Ciò fallisce anche nei browser WebKit (ad es. Safari e Chrome)
Michael Haren,

5
Mentre questo è il modo conforme agli standard per farlo, l'unico browser che attualmente implementa lo standard è Opera. Nota che questo fa parte di css2, e quindi la mancanza di implementazione potrebbe essere un problema per qualche tempo, perché apparentemente a nessuno importa.
pkh

16
La specifica CSS 2.1 indica che gli attributi dello stile di interruzione di pagina vengono applicati solo agli elementi a livello di blocco. La modalità di visualizzazione predefinita per le righe della tabella è table-row. Sfortunatamente, nessun elemento della tabella è predefinito a livello di blocco, inclusa la tabella stessa.
lsuarez,

2
@ SinanÜnür Non è un requisito, quindi non puoi fare affidamento su di esso, e sfortunatamente dai miei test posso vedere che il webkit ha visto "può" e ha ignorato qualsiasi cosa al di là di esso. Stranamente, IE ha un supporto di stampa per tavoli piuttosto bello. Non avrei mai pensato di cantare le sue lodi su un dato punto.
lsuarez,

6
Posso confermare che questo NON funziona bene in Chrome o in qualsiasi altro browser Webkit (ad esempio Safari, Opera) - a meno che, con "funziona bene", intendi "esclude qualsiasi funzionalità considerata facoltativa". Penso che ciò che la maggior parte delle persone desidera sia eseguire intestazioni e piè di pagina e tabelle che consentano solo interruzioni di pagina tra le righe, nessuna delle quali è implementata in Webkit a partire dal 2015/11/13.
DoctorDestructo,

47

Nota: quando si utilizza l'interruzione di pagina: sempre per il tag creerà un'interruzione di pagina dopo l'ultimo bit della tabella, creando ogni volta una pagina completamente vuota alla fine! Per risolvere questo problema basta cambiarlo in page-break-after: auto. Si romperà correttamente e non creerà una pagina vuota aggiuntiva.

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

Funziona per me su Chrome ed è una bella soluzione CSS semplice.
Ryan,

1
Sto provando la stessa soluzione, ma non rompe i dati della tabella e scompare i dati extra invece di visualizzarli nella pagina successiva. Qualche supposizione?
Puntatore nullo

24

Espansione dalla soluzione 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>

Sembra che page-break-inside:avoidin alcuni browser sia preso in considerazione solo per gli elementi di blocco, non per cella, tabella, riga né blocco in linea.

Se provi display:blockil TRtag e lo usi lì page-break-inside:avoid, funziona, ma si scherza con il layout della tabella.


2
Ecco un modo semplice per aggiungere i div in modo dinamico con jquery:$(document).ready(function(){$("table tbody th, table tbody td").wrapInner("<div></div>");});
Chris Bloom,

1
Grazie a Sinan ürün, Vicenteherrera e Chrisbloom7. Ho applicato la combinazione delle tue risposte e ora funziona!
Nurhak Kaya,

Potresti provare a impostare il CSS @media tr { display: block; }su Solo stampa, anziché aggiungere tutti gli <div>elementi estranei . (Non ho provato ma vale la pena guardarlo)
Stephen R

11

Nessuna delle risposte qui ha funzionato per me in Chrome. AAverin su GitHub ha creato alcuni Javascript utili per questo scopo e questo ha funzionato per me:

Basta aggiungere js al tuo codice e aggiungere la classe 'splitForPrint' alla tua tabella e dividerà ordinatamente la tabella in più pagine e aggiungerà l'intestazione della tabella a ciascuna pagina.


Hai un esempio su come applicare questo? Ho cercato di assegnare la mia classe className come splitForPrintma in JS non c'è nessun posto dove ha preso il riferimento dell'elemento usando className splitForPrint. Solo la parte in cui var splitClassName = 'splitForPrint';ma questo è tutto.
Compaq LE2202x

Down ha votato perché lo script a cui ti sei collegato non risolve il problema del PO senza una considerevole selezione e riconfigurazione della ciliegia, e non hai fornito alcun esempio di come si potrebbe fare per farlo.
Chris Bloom,

Ha funzionato come un fascino per me, nessuna delle altre soluzioni ha funzionato. +1 Ho dovuto aggiungere un po 'di CSS per ottenere le pause corrette .page-break {page-break-after: sempre; }
fhugas,

Sì, aggiungendo .page-break {page-break-after: sempre; } mi ha salvato la giornata!
milodky,

7

Usa queste proprietà CSS:

page-break-after

page-break-before 

Per esempio:

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

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

attraverso


Non sono sicuro, dovrai controllare. In caso contrario, dividere in matrici diverse e separare le matrici da un div vuoto
marcgg

Dovrai applicarlo alla riga della tabella o anche alla cella, ma non alla tabella, credo. A parte questo, dovrebbe funzionare.
Pekka,

2
non funziona in Chrome. Viene ignorato come se fosse il 13/06/2012 quando applicato a TR
ladieu il

5

Di recente ho risolto questo problema con una buona soluzione.

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

Funziona come un fascino!


2

Ho finito per seguire l'approccio di @ vicenteherrera, con alcune modifiche (che sono probabilmente bootstrap 3 specifiche).

Fondamentalmente; non possiamo rompere trs, o tds perché non sono elementi a livello di blocco. Quindi incorporiamo divs in ognuno di essi e applichiamo le nostre page-break-*regole contro div. in secondo luogo; aggiungiamo un po 'di imbottitura nella parte superiore di ciascuno di questi div, per compensare eventuali artefatti di stile.

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

Le regolazioni del margine e del padding erano necessarie per compensare una sorta di jitter che veniva introdotto (a mio avviso - dal bootstrap). Non sono sicuro di presentare una nuova soluzione dalle altre risposte a questa domanda, ma immagino che questo possa aiutare qualcuno.


1

Ho dovuto affrontare lo stesso problema e cercare ovunque una soluzione, alla fine trovo qualcosa che funzioni per me su tutti i browser.

html {
height: 0;
}

usa questo css o Invece di css puoi avere questo javascript

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

Spero che questo funzioni anche per te.


0

Ho controllato molte soluzioni e nessuno stava lavorando bene.

Quindi ho provato un piccolo trucco e funziona:

piede con stile: position: fixed; bottom: 0px; è posizionato nella parte inferiore dell'ultima pagina, ma se il piè di pagina è troppo alto viene sovrapposto al contenuto della tabella.

tfoot with only: display: table-footer-group; non è sovrapposto, ma non è in fondo all'ultima pagina ...

Mettiamo due piedi:

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>

Uno si posiziona su pagine non ultime, il secondo inserisce il piè di pagina accuale.


-1

Ho provato tutti i suggerimenti sopra riportati e ho trovato una soluzione cross browser semplice e funzionante per questo problema. Non ci sono stili o interruzioni di pagina necessari per questa soluzione. Per la soluzione, il formato della tabella dovrebbe essere simile a:

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

Il formato sopra è stato testato e funziona su più browser


-2

Bene ragazzi ... La maggior parte delle soluzioni qui non ha funzionato. Quindi è così che le cose hanno funzionato per me ..

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>

Il primo set di testine viene utilizzato come fittizio in modo che non ci sia un bordo superiore mancante nella seconda testina (ovvero testina originale) durante l'interruzione di pagina.


-3

La risposta accettata non ha funzionato per me in tutti i browser, ma i seguenti css hanno funzionato per me:

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

La struttura html era:

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

Nel mio caso, ci sono stati alcuni problemi aggiuntivi con thead tr, ma questo ha risolto il problema originale di impedire la rottura delle righe della tabella.

A causa dei problemi di intestazione, alla fine ho finito con:

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

Ciò non ha impedito la rottura delle file; solo il contenuto di ogni cella.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.