Ich generiere einen PDF-Bericht von einer HTML-Seite mit einer Tabelle .
Ich benutze wkhtmltopdf für diesen Zweck.
Wenn PDF generiert wird, wird es an einer beliebigen Stelle im tr-Tag unterbrochen .
Ich möchte es vermeiden.
Ich generiere einen PDF-Bericht von einer HTML-Seite mit einer Tabelle .
Ich benutze wkhtmltopdf für diesen Zweck.
Wenn PDF generiert wird, wird es an einer beliebigen Stelle im tr-Tag unterbrochen .
Ich möchte es vermeiden.
Antworten:
Update 17.09.2015: Überprüfen Sie die Version, die Sie verwenden: wkhtmltopdf 0.12.2.4 soll das Problem beheben (ich habe nicht überprüft) .
Dies ist ein bekanntes Problem in wkhtmltopdf. Der vom Webkit verwendete Seitenumbruchalgorithmus (der WK in WKhtmltopdf) funktioniert für große Tabellen nicht wirklich gut. Ich schlage vor, die Tabelle in kleinere Teile aufzuteilen, die sich leichter in Seiten aufteilen lassen und das CSS häufig verwenden:
table, tr, td, th, tbody, thead, tfoot {
page-break-inside: avoid !important;
}
Schauen Sie sich auch die folgenden wkhtmltopdf-Probleme an. Sie enthalten interessante Kommentare, in denen beispielsweise das Problem der Tabellenaufteilung erläutert wird. Es gibt eine JS-Lösung, die Tabellen in 168 programmgesteuert aufteilt, was Ihnen helfen könnte (ich verwende sie jedoch nicht).
Update 08.11.2013 In der
oben verlinkten Ausgabe 168 wird viel darüber diskutiert. Jemand hat es geschafft, eine Version von wkhtmltopdf zu kompilieren, die ein besseres Tabellenbrechen unterstützt, aber leider scheint es, dass es nicht offiziell veröffentlicht wurde und möglicherweise andere Fehler enthält. Ich weiß nicht, wie ich es bekommen soll und ich weiß nicht, wie ich es unter Windows kompilieren soll, aber jeder Interessierte kann zum Beispiel den Kommentar hier überprüfen (siehe neues Update unten).
Update 24.02.2014 Sie werden erfreut sein zu hören, dass in wkhtmltopdf 0.12 diese Funktion unter anderem stark verbessert wurde. Warten Sie jedoch auf 0.12.1 und testen Sie es gründlich, bevor Sie eine neue Version verwenden. Es ist immer noch ein wenig instabil, obwohl die neuen Leute, die mit Antialize arbeiten, einen großartigen Job machen (Ashkulz Rocks)! Halten Sie sich unter wkhtmltopdf.org und github auf dem Laufenden . Die Google Code-Site ist veraltet und wird langsam migriert.
display: inline-block
. Geändert zu block
und mit den Änderungen darüber fing alles an zu funktionieren!
Es ist ein alter Beitrag, aber da ich viel Zeit damit verschwendet habe, eine richtige Lösung zu finden, werde ich ihn hier einfügen, vielleicht ist er für jemanden nützlich.
Also von dem, was ich gelesen habe, das Problem mit
page-break-inside: avoid
ist, dass es nicht funktioniert. Aber tatsächlich, wenn Sie es auf ein Element setzen, das display:block
es hat , funktioniert es wie erwartet (wie irgendwo in SO angegeben). also für einfache strukturierung der tabelle css mit
td div, th div{
page-break-inside: avoid;
}
und Tabellenstruktur
<table>
....
<tr>
<td><div>some text</div></td>
<td><div>more text</div></td>
</tr>
....
</table>
wird wie erwartet funktionieren.
Ich hatte einen etwas komplizierteren Fall mit Reihenspannen, daher brach die Lösung von oben in Stücke, was nicht erwünscht war. Ich habe es mit divs für jeden zeilenübergreifenden Satz von Zeilen gelöst. Meine jquery macht den ganzen Job:
$(window).load(function () {
var sizes = {};
$('#the_table tr:first th').each(function (a, td) {
var w = $(td).width();
if (sizes.hasOwnProperty('' + a)) {
if (sizes['' + a] < w)
sizes['' + a] = w;
}
else {
sizes['' + a] = w;
}
});
var tableClone = $('#the_table').clone();
$('#the_table').replaceWith('<div class="container"></div>');
var curentDivTable;
var cDiv = $('.container');
tableClone.find('tr').each(function (i, ln) {
var line = $(ln);
if (line.hasClass('main_row')) {
var div = $('<div class="new-section"><table><tbody>')
currentDivTable = div.find('tbody');
cDiv.append(div);
}
currentDivTable.append(line);
});
//optional - maybe in % its better than px
var sum = 0;
$.each(sizes, function (a, b) {
sum += b;
});
var widths = {};
$.each(sizes, function (a, b) {
var p = Math.ceil(b * 100 / sum);
widths['' + a] = p + '%';
});
//setup
$('.container table').each(function (a, tbl) {
$(tbl).find('tr:first td, tr:first th').each(function (b, td) {
$(td).width(widths['' + b]);
});
$(tbl).addClass('fixed');
});
});
CSS:
div.new-section {
page-break-inside: avoid;
}
.container, .new-section, .new-section table.fixed{
width: 100%;
}
.new-section table.fixed{
table-layout:fixed;
}
Ich weiß nicht, ob alles gebraucht wird und ich denke nicht, dass es perfekt ist, aber es macht den Job. Nur auf Chrom getestet
Seit 0.12 wurde dieses Problem behoben, aber manchmal, wenn eine Tabelle zu lang ist, um in die Seite zu passen, zerlegt wkhtmltopdf sie in zwei Teile und wiederholt die Spaltenüberschriften auf der neuen Seite, und diese Spaltenüberschriften werden der ersten Zeile überlagert.
Ich fand eine zeitliche Lösung für dieses Problem im Abschnitt wkhtmltopdf Github-Probleme: https://github.com/wkhtmltopdf/wkhtmltopdf/issues/2531
Fügen Sie einfach diese Zeilen zu Ihrer Ansicht CSS hinzu:
tr {
page-break-inside: avoid;
}
Ich habe mich tagelang mit diesen Problemen befasst und endlich die perfekte Lösung gefunden. Sie können auf dieses Projekt phpwkhtmltopdf verweisen . Schauen Sie in das Verzeichnis article
und Sie werden 3 Lösungen für 3 Probleme finden. Kurz gesagt, die ultimative Lösung ist das Hinzufügen des CSS-Stils
thead {
display: table-row-group;
}
tr {
page-break-before: always;
page-break-after: always;
page-break-inside: avoid;
}
table {
word-wrap: break-word;
}
table td {
word-break: break-all;
}
Wenn Sie Chinese sind, können Sie diese Seite gerne besuchen. Schauen Sie sich das Wesentliche an, wenn Sie das Wesentliche für wkhtmltopdf wünschen
Ich habe festgestellt, dass ab wkhtmltopdf 0.12.2.1 dieses Problem behoben wurde.
In meinem speziellen Fall hat aus irgendeinem Grund keine der vorherigen Antworten für mich funktioniert. Was letztendlich funktionierte, war eine Kombination aus mehreren Dingen.
Ich installierte (in Ubuntu 16.04) der wkhtmltopdf Python - Wrapper namens PDFKit PIP3 verwenden, und dann anstelle wkhtmltopdf über installieren apt-get ich die statische binäre (Version 0.12.3) installiert anhand der folgenden Skript, von hier genommen
#!/bin/sh
sudo apt-get install -y openssl build-essential xorg libssl-dev
wget http://download.gna.org/wkhtmltopdf/0.12/0.12.3/wkhtmltox-0.12.3_linux-generic-amd64.tar.xz
tar -xJf wkhtmltox-0.12.3_linux-generic-amd64.tar.xz
cd wkhtmltox
sudo chown root:root bin/wkhtmltopdf
sudo cp -r * /usr/
Dieses CSS wurde hinzugefügt (wie in einer der Antworten hier vorgeschlagen):
tr, td div, th div{
page-break-inside: avoid;
}
Und dann auch noch hinzufügen <thead>
und <tbody>
markieren, wie hier vorgeschlagen (ohne diese würde die Tabelle immer noch auf hässliche Weise brechen):
<table>
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>Value 1</td>
<td>Value 2</td>
</tr>
</tbody>
</table>
Mit diesen Änderungen kann ich nun erfolgreich Mako-Vorlagen verwenden , um den HTML-Code zu generieren und diesen dann an Wkhtmltopdf weiterzuleiten und ein wunderschön paginiertes PDF zu erhalten.
Ich habe alle Arten von Manipulationen an meinen Tabellen versucht, aber nichts, was ich versucht habe, konnte verhindern, dass die Seitenumbrüche in die Mitte einer Zeile gestellt werden. In meiner Verzweiflung habe ich verschiedene Versionen ausprobiert und Folgendes gefunden:
Wkhtmltopdf 0.12.2.1: Schlecht
Wkhtmltopdf 0.12.3: Schlecht
Wkhtmltopdf 0.12.1: Gut
Meine Lösung bestand darin, ein Downgrade auf Version 0.12.1 durchzuführen, wodurch meine Probleme gelöst wurden. Zugegeben, sie könnten teilweise darauf zurückzuführen sein, dass mein HTML-Code keine Super-OCD ist, aber da der HTML-Code in TinyMCE (von Benutzern) generiert wird, habe ich nicht wirklich eine große Auswahl.
Außerdem funktionieren verschachtelte Tabellen in keiner Version für mich.
Ich hatte das gleiche Problem. Fügen Sie nach vielen Versuchen und Fehlern hinzu, dass dieses CSS das Problem gelöst hat
tr {
display: inline-table;
}
Wie verwende ich Seitenumbrüche in PDF, ohne ein tr zu brechen?
Hier ist eine Lösung, die Sie in jeder HTML-Datei verwenden können .....
Nachdem Sie Ihr tr gestartet haben, müssen Sie ein div innerhalb des tr nehmen und dieses CS dem div geben:
<tr>
<div style="page-break-inside:avoid !important; page-break-after:auto !important; overflow: hidden; display:block !important; width:100% ">
</tr>
Mit der Ergänzung zu dem, was Nanotelep sagt, ist hier die funktionierende Implementierung des manuellen Algorithmus zum Brechen von Tabellenseiten. https://github.com/AAverin/JSUtils/tree/master/wkhtmltopdfTableSplitHack
Die obigen Antworten haben bei mir nicht funktioniert. Ich musste die Zoomoption meiner pdfkit-Konfiguration speziell deaktivieren.
PDFKit.configure do |config|
config.default_options = {
print_media_type: false,
page_size: "A4",
encoding: "UTF-8",
## Make sure the zoom option is not enabled!
## zoom: '1.3',
disable_smart_shrinking: false,
footer_right: "Page [page] of [toPage]"
}
end
Für alle, die immer noch Probleme damit haben, ist es wichtig, sich daran zu erinnern, dass der Tisch ein direktes Kind des Körpers sein muss , sonst funktioniert das CSS nicht (zumindest ist das bei mir passiert).
display: table-cell;
angewendet. Wenn Sie diese Stile @media only screen
korrigieren, werden die Seitenumbrüche behoben. Wenn Sie keine Seitenumbrüche erzielen können, versuchen Sie zu teilen und zu erobern, indem Sie die Hälfte des CSS schrittweise entfernen und prüfen, ob es funktioniert.
Eine weitere Option: Platzieren Sie jede tr
für sich tbody
und wenden Sie dann die CSS-Regeln für die Pausenunterbrechung auf die an tbody
. Tabellen unterstützen mehrere tbody
s.
Ein bisschen extra Markup, funktioniert aber anständig für mich.
Ich habe das Problem mit einer Kombination einiger Lösungsvorschläge gelöst.
Ich habe meine Tabelle in ein div eingewickelt und das folgende CSS definiert.
.wrapping-div {
display: block;
page-break-inside: avoid !important;
}
.wrapping-div table, .wrapping-div tbody, .wrapping-div tr, .wrapping-div td, .wrapping-div th {
page-break-inside: avoid !important;
}
Die Tabellenstruktur wurde nach Abschluss wie folgt definiert:
<div class="wrapping-div">
<table>
<tbody>
<tr>
<th>
header
</th>
<td>
content
</td>
</tr>
</tbody>
</table>
</div>
Ich musste kein Div innerhalb der td- oder th-Tags erstellen.
Wichtige Dinge, die mir beim Versuch, das Problem zu lösen, aufgefallen sind:
Ich hoffe das hilft.
Ich habe viel mit dem Problem zu kämpfen gehabt , indem ich die neueste h4cc / wkhtmltopdf-amd64-Version 0.12.4 verwendet habe und es schließlich zum Laufen gebracht habe , indem ich die Version des Pakets auf 0.12.3
! Herabgestuft habe !
Um Seitenumbrüche zu vermeiden, können wir die Option "Seitenumbrüche vermeiden" verwenden.
tr { page-break-inside: avoid; }
Brechen Sie alle Inhalte (Bild / Text) und lassen Sie sie auf der nächsten Seite erscheinen
.sample-image { page-break-before: always; }
Hast du einen Tischkopf? und ein Tischkörper?
<table>
<tbody>
<tr><th>Name</th><th>Value</th></tr>
<tr><td>url</td><td>stackoverflow.com</td></tr>
<tr><td>ip</td><td>123.123.123.123</td></tr>
</tbody>
</table>
Das ist die richtige Formatierung einer Tabelle, während es die meisten Browser nicht weniger interessieren könnten, Konverter wie der von Ihnen erwähnte können, wenn Ihre fehlenden <tbody>
oder <th>
Tags, ich schlage vor, Sie versuchen, diese zuerst hinzuzufügen.