我从一个表格的html页面生成pdf报告。
我正在使用wkhtmltopdf。
当生成pdf时,它会破坏tr标签中的任何位置。
我想避免它。
更新17.09.2015:检查您使用的版本:wkhtmltopdf 0.12.2.4 is said to fix the problem (I have not checked)。
这是wkhtmltopdf中的已知问题。 webkit使用的分页算法(WK在WKhtmltopdf中)对于大型表格并不适用。我建议将表格拆分为较小的块,这些块更容易拆分为页面并使用css:
table, tr, td, th, tbody, thead, tfoot {
page-break-inside: avoid !important;
}
另外看看下面的wkhtmltopdf问题,他们有一些有趣的评论,例如讨论表分裂问题。有一个JS解决方案,以编程方式在168中拆分可能对您有帮助的表(尽管我不使用它)。
更新08.11.2013在上面链接的问题168中有很多关于此的讨论。有人设法编译了一个支持更好的表格破坏的wkhtmltopdf版本,但不幸的是它似乎没有正式发布,可能包含其他错误。我不知道如何获得它,我不知道如何在Windows上编译,但任何感兴趣的人都可以检查例如评论 here (见下面的新更新)。
更新24.02.2014您将很高兴听到在wkhtmltopdf 0.12中这个功能已经大大改进。然而,在开始使用任何新版本之前等待0.12.1并进行彻底测试,虽然使用antialize的新人做得很好(ashkulz rock),但它仍然有点不稳定!请继续关注wkhtmltopdf.org和github。谷歌代码网站已过时,正在慢慢迁移。
上面的答案对我不起作用。我不得不专门禁用我的pdfkit配置的缩放选项。
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
对于仍然有这个问题的人来说,有一件事要记住,桌子必须是身体的直接孩子,否则css将无法工作(至少那是我发生的事情)。
我找到了这个荒谬的解决方案,但它对我来说效果很好:)
我只是放了一个非常长的rowpan列
<td rowspan="XXX TOTAL ROWS" style="width:0px"></td>
然后桌子不会破裂。
另一个选择:将每个tr
放在自己的tbody
中,然后将peage break css规则应用于tbody
。表支持多个tbody
s。
一点额外的标记,但对我来说效果不错。
我遇到了同样的问题,经过大量的试验n错误后,这个css解决了这个问题
tr {
display: inline-table;
}
我已经挖掘了这些问题好几天了,终于找到了完美的解决方案。你可以参考这个项目phpwkhtmltopdf。查看目录article
,您将找到3个问题的解决方案。简而言之,最终的解决方案是添加css样式
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;
}
如果您是中国人,请随时查看此网站关于wkhtmltopdf,你一定想知道这些如果您希望gist for wkhtmltopdf查看要点
我使用一些建议的解决方案组合解决了这个问题。
我将我的表包装在div中并定义了以下CSS。
.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;
}
完成后的表结构定义如下:
<div class="wrapping-div">
<table>
<tbody>
<tr>
<th>
header
</th>
<td>
content
</td>
</tr>
</tbody>
</table>
</div>
我不需要在td或th标签内创建任何div。
在尝试解决问题时我注意到的重要事项:
我希望这有帮助。
我在这个问题上遇到了很多困难,使用最新的h4cc/wkhtmltopdf-amd64 version 0.12.4,最后通过将软件包的版本降级到0.12.3
来实现它!
这是老帖子,但由于我浪费了很多时间试图找到合适的解决方案,我会把它放在这里,也许它会对某人有用。
所以从我读到的,问题
page-break-inside: avoid
是它不起作用。但实际上,如果你在具有display:block
的元素上设置它,它会按预期工作(如SO中某处所述)。所以对于表css的简单结构
td div, th div{
page-break-inside: avoid;
}
和表结构
<table>
....
<tr>
<td><div>some text</div></td>
<td><div>more text</div></td>
</tr>
....
</table>
将按预期工作。
我有一个更复杂的案例与rowpans,所以上面的解决方案是打破和平,这是不希望的效果。我使用div为每个行显示的行集解决了它。我的jquery js完成所有工作:
$(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;
}
我不知道是否需要一切,我不认为它是完美的,但它确实起到了作用。仅在镀铬上测试过
从0.12开始,这个问题已经解决了,但有时候,当一个表太长而无法放入页面时,wkhtmltopdf将它分成两部分并重复新页面上的列标题,这些列标题显示为叠加到第一行。
我在wkhtmltopdf github问题部分找到了这个问题的时间解决方案:https://github.com/wkhtmltopdf/wkhtmltopdf/issues/2531
只需将此行添加到您的视图css:
tr {
page-break-inside: avoid;
}
我发现wkhtmltopdf 0.12.2.1以后修复了这个问题。
在我的特殊情况下由于某些原因,以前的答案都没有对我有用。最终工作的实际上是几件事的组合。
#!/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/
tr, td div, th div{
page-break-inside: avoid;
}
<thead>
和<tbody>
标签,如此处所示(没有这些表格仍会以丑陋的方式破坏):
<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>
通过这些修改,我现在可以成功使用Mako templates生成HTML,然后将其提供给Wkhtmltopdf并获得精美的分页PDF :)
我尝试了各种各样的操作到我的表,但我尝试的任何东西都不能阻止页面中断被放入中间行。无奈之下,我尝试了不同的版本,并发现了以下内容:
Wkhtmltopdf 0.12.2.1:不好
Wkhtmltopdf 0.12.3:不好
Wkhtmltopdf 0.12.1:好
我的解决方案是降级到版本0.12.1,这解决了我的问题。当然,他们可能部分原因在于我的html并不是超级强迫症,但由于HTML是在TinyMCE内部生成的(用户),我真的没有多少选择。
此外,嵌套表对我来说不适用于任何版本。
如何在不破坏tr的情况下在pdf中使用分页符?
这是你可以在任何html文件中使用的解决方案.....
在启动你的tr后你必须在tr中取一个div并将这个css给div:
<tr>
<div style="page-break-inside:avoid !important; page-break-after:auto !important; overflow: hidden; display:block !important; width:100% ">
</tr>
你有桌头吗?还有一个桌子?
<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>
这是表格的正确格式,而大多数浏览器可能不在乎,像你提到的转换器可以,如果你缺少<tbody>
或<th>
标签,我建议你先尝试添加。
除了Nanotelep所说的,这里是手动表格分页算法的工作实现。 https://github.com/AAverin/JSUtils/tree/master/wkhtmltopdfTableSplitHack