unikaj łamania strony w wierszu tabeli

97

Chcę uniknąć podziału strony w wierszu tabeli w html, kiedy konwertuję HTML na PDF za pomocą wkhtmltopdf. Używam łamania strony wewnątrz: unikaj z tabelą - to działa, ale mam tak wiele wierszy, więc nie działa. Jeśli ustawisz wyświetlanie tr jako blok lub coś innego, zmieni to formatowanie tabeli i wstawia podwójne obramowanie. Lub możliwe jest wstawienie nagłówka tabeli na każdej stronie, na której tabela została podzielona.

Ankit Mittal
źródło
1
Przepraszam, jaki jest problem podczas używania page-break-inside: avoid;?
Christian,
2
@ChristianVarga, kiedy używam łamania strony wewnątrz: unikaj z tr, to nie działa
Ankit Mittal
1
Strona łamiąca tabele jest dość błędna. Spójrz na to obejście JavaScript code.google.com/p/wkhtmltopdf/issues/detail?id=168#c4
Jona,
2
właściwie próbowałem page-break-inside:avoidze wszystkimi elementami tabeli, takimi jak tr td, ale nie zadziałało.
Ankit Mittal
3
Yay Google dla WebGL, oślepiający szybki javascript, przenośny klient natywny, ale nadal nie możemy drukować tabel danych. Kto musiałby to zrobić ??? Tylko o każdej firmie na świecie. Nawiasem mówiąc, właśnie próbowałem wydrukować arkusz kalkulacyjny w Dokumentach Google i konsekwentnie powoduje to awarię mojego Chrome. Wydaje mi się, że dokumenty Google są drukowane w formacie PDF. : /
Sam Watkins

Odpowiedzi:

74

Możesz spróbować tego z CSS:

<table class="print-friendly">
 <!-- The rest of your table here -->
</table>

<style>
    table.print-friendly tr td, table.print-friendly tr th {
        page-break-inside: avoid;
    }
</style>

Większość reguł CSS nie ma <tr>bezpośredniego zastosowania do tagów, z powodu dokładnie tego, co wskazałeś powyżej - mają unikalny displaystyl, który nie pozwala na te reguły CSS. Jednak <td>i <th>tagi w nich zwykle zrobić umożliwiają tego rodzaju specyfikacji - i można łatwo zastosować takie reguły do wszystkich idealny dla całych <tr>„S <td>” s za pomocą CSS, jak pokazano powyżej.

Troy Alford
źródło
18
Niestety to (jeszcze) nie działa z przeglądarkami opartymi na webkitach.
Attila Fulop
2
Tak - jest kilka dziwactw. Zobacz odpowiedź @ Petera na to pytanie: stackoverflow.com/questions/7706504/ ... po więcej informacji.
Troy Alford
3
Działa tylko wtedy, gdy weźmiesz całą tabelę, a nie tylko tr / td: stackoverflow.com/a/13525758/729324
marcovtwout
1
Mam z tym problemy w IE8, być może w innych, gdzie powoduje to, że cała tabela próbuje zmieścić się na jednej stronie i odcina wszelkie przepełnienia. Wydawało się również, że ignoruje opcję „dopasuj skalę” dla tych tabel.
Tom Pietrosanti
6
@AttilaFulop Still? Twój post ma 3 lata i nadal nie mogę go uruchomić. Dzięki
powtórz
32

Najlepszym sposobem, w jaki znalazłem rozwiązanie tego problemu w przeglądarkach webkit, jest umieszczenie elementu div wewnątrz każdego elementu td i zastosowanie podziału strony wewnątrz: unikaj stylu w elemencie div, na przykład:

...
<td>
  <div class="avoid">
    Cell content.
  </div>
</td>
...
<style type="text/css">
  .avoid {
    page-break-inside: avoid !important;
    margin: 4px 0 4px 0;  /* to keep the page break from cutting too close to the text in the div */
  }
</style>

Mimo że Chrome podobno nie rozpoznaje polecenia „page-break-inside: unikaj”; wydaje się, że zapobiega to dzieleniu zawartości wiersza na pół przez podział strony podczas używania wktohtml do generowania plików PDF. Element tr może nieco wisieć nad stroną zepsutą, ale element div i wszystko w jego wnętrzu nie.

Aaron Hill
źródło
margin: 4px 0 4px 0;Wystarczyły mi, traciłem rekord od czasu do czasu. Dzięki
Wartodust
Problem z tym podejściem polega na tym, że czasami tylko kilka komórek wiersza jest dzielonych na następną stronę, chociaż każda komórka osobno nie zostanie zerwana.
WorldSEnder
@WorldSEnder Yes. Czy znalazłeś na to jakieś rozwiązanie?
ranjansaga
4
Nie działa. Nic nie działa. Wypróbowałem każde „rozwiązanie” w internecie i nie ma rozwiązania. Musimy tylko zaakceptować bzdury, które nie potrafią nawet wyrenderować tabeli.
Niklas R.
18

Użyłem sztuczki 4px autorstwa @AaronHill powyżej ( link ) i zadziałała naprawdę dobrze! Użyłem jednak prostszej reguły css bez konieczności dodawania klasy do każdej z nich <td>w tabeli.

@media print {
    table tbody tr td:before,
    table tbody tr td:after {
        content : "" ;
        height : 4px ;
        display : block ;
    }
}
fidias
źródło
10

Znalazłem nowy sposób rozwiązania tego problemu, przynajmniej dla mnie (wersja Chrome 63.0.3239.84 (oficjalna kompilacja) (64-bitowa) na MacOS Sierra)

Dodaj regułę CSS do tabeli nadrzędnej:

table{
    border-collapse:collapse;
}

a dla td:

tr td{
    page-break-inside: avoid;
    white-space: nowrap;
}

Właściwie znalazłem to rozwiązanie w Stack Overflow, ale nie pojawiło się w początkowych wyszukiwaniach Google: CSS, aby zatrzymać podział strony w wierszu tabeli

Uznanie dla @ Ibrennan208 za rozwiązanie problemu!

Jason Silver
źródło
rozwiązany problem rzędu stołu do cięcia przełamuje inny projekt
aviboy2006
9

Używanie CSS do dzielenia strony nie zadziała (jest to problem z przeglądarką Webkit).

Istnieje hack wkhtmltopdf JavaScript do dzielenia tabel, który automatycznie dzieli długą tabelę na mniejsze tabele w zależności od określonego rozmiaru strony (zamiast dzielenia strony po statycznej wartości x wierszy): https://gist.github.com/3683510

Richard Pursehouse
źródło
Ten hack js zadziała, jeśli chcę wydrukować stronę internetową bez wkhtmltopdf?
120196
To jedyny, który działał dla mnie. Działa również z biblioteką HTML-PDF.
gilbert-v
8

Napisałem następujący JavaScript na podstawie odpowiedzi Aarona Hilla:

//Add a div to each table cell so these don't break across pages when printed
//See http://stackoverflow.com/a/17982110/201648
$(document).ready(function () {
    var ctlTd = $('.dontSplit td');
    if (ctlTd.length > 0)
    {
        //console.log('Found ctlTd');
        ctlTd.wrapInner('<div class="avoidBreak" />');
    }
});

Gdzie dontSplit to klasa tabeli, w której nie chcesz, aby td dzieliło się na strony. Użyj tego z następującym CSS (ponownie przypisanym Aaronowi Hillowi):

 .avoidBreak {
    page-break-inside: avoid !important;
    margin: 4px 0 4px 0;  /* to keep the page break from cutting too close to the text in the div */
  }

Wygląda na to, że działa dobrze w najnowszej wersji Chrome.

Aaron Newton
źródło
1
Renderuję duże tabele do formatu PDF za pomocą wkhtmltopdf i jest to jedyne rozwiązanie, które przyniosło akceptowalne wyniki. Mogłoby być lepiej (Webkit nie powtarza granic komórek po podziale strony), ale przynajmniej zawartość jest dostępna. Dzięki!
Jonathon Hill
7

Jedynym sposobem, w jaki udało mi się zadziałać, było umieszczenie każdego elementu TR wewnątrz jego własnego elementu TBODY i zastosowanie reguł podziału strony do elementu TBODY za pośrednictwem css

Troy Morehouse
źródło
1
Działa to lepiej niż reszta dla mnie na Chromium w wersji 40.0.2214.111 (64-bit) na Arch Linux. Jest brzydki i wydaje się hacky - ale najwyraźniej wiele tbodyelementów jest prawidłowych w table stackoverflow.com/questions/3076708/ ...
ElDog,
To nie działa dla mnie (Chrome 56.0.2924.87 (64-bit), Mac OS 10.12.2).
Nhat Dinh
4

Spróbuj z

white-space: nowrap; 

style do td, aby uniknąć zrywania nowych linii.

vinayakshukre
źródło
1
Dużo prostsze niż inne rozwiązania. Czy to nowa rzecz?
bendecko
3

Znalazłem to page-break-inside: avoid to nie zadziała, jeśli którykolwiek z elementów nadrzędnych tabeli to display: inline-blocklub flex. Upewnij się, że wszystkie elementy nadrzędne sądisplay: block .

Weź również pod uwagę nadrzędne table, tr, td„s displaystyle CSS griddla układu wydruku, jeśli trzymać problemy z tabeli.

Stephen Saucier
źródło
3

Rozwiązanie 2020

Jedyną rzeczą, którą mogłem konsekwentnie pracować we wszystkich przeglądarkach, jest umieszczenie każdego wiersza we własnym elemencie tabeli . Działa to również z węzłem HTML-PDF. Następnie ustaw wszystko na page-break-inside: avoid.

table,
tr,
td,
div {
    page-break-inside: avoid;
}

Jedyną wadą jest to, że musisz ręcznie ustawić szerokość kolumn, w przeciwnym razie wygląda to dość dziwnie. Poniższe działały dobrze dla mnie z dwiema kolumnami.

td:first-child { width: 30% }
td:last-child { width: 70% }


Przykład

<table>
  <tr>
    <td>Forename</td>
    <td>John</td>
  </tr>
</table>
<table>
  <tr>
    <td>Surname</td>
    <td>Piper</td>
  </tr>
</table>
<table>
  <tr>
    <td>Website</td>
    <td>desiringgod.org</td>
  </tr>
</table>
gilbert-v
źródło
Czy możesz podać przykładowy kod HTML tabeli? Dzięki.
PavanBhushan
Dziękuję @ gilbert-v za edycję z przykładem. Spróbuję tego.
PavanBhushan
0

To jest stare pytanie, ale ostatnio wpadłem w ten sam błąd. Problem w moim przypadku był związany z table-responsiveklasą Bootstrap , która została przypadkowo użyta na <table>elemencie.

Jeśli więc masz ten sam problem, spróbuj usunąć table-responsivez <table>zajęć podczas wywoływania wkhtmltopdf.

Laerte
źródło