我正在从html页面生成一个表格的pdf报告。
我为此目的使用wkhtmltopdf。
生成pdf时,它会在tr标签的任何位置中断。
我想避免。
我正在从html页面生成一个表格的pdf报告。
我为此目的使用wkhtmltopdf。
生成pdf时,它会在tr标签的任何位置中断。
我想避免。
Answers:
2015年9月17日更新:检查您使用的版本:据说可以解决wkhtmltopdf 0.12.2.4的问题(我尚未检查)。
这是wkhtmltopdf中的一个已知问题。webkit(WKhtmltopdf中的WK)使用的分页算法在大型表中效果不佳。我建议将表分解为较小的块,这些块更容易拆分为页面并大量使用css:
table, tr, td, th, tbody, thead, tfoot {
page-break-inside: avoid !important;
}
还可以看看以下wkhtmltopdf问题,它们有有趣的评论,例如,讨论了表拆分问题。有一个JS解决方案可以以编程方式在168中拆分表,这可能会对您有所帮助(不过我不使用它)。
2013年11月8日更新
上面链接的第168期对此进行了很多讨论。有人设法编译了一个支持更好的表中断的wkhtmltopdf版本,但不幸的是,它似乎尚未正式发布,并且可能包含其他错误。我不知道如何获得它,也不知道如何在Windows上进行编译,但是任何有兴趣的人都可以在这里查看例如注释(请参见下面的新更新)。
更新2014年2月24日 您将很高兴听到在wkhtmltopdf 0.12中,此功能以及其他功能已得到很大改进。但是,在开始使用任何新版本之前,请等待0.12.1并进行彻底测试,尽管使用antialize的新手做的很棒(ashkulz摇滚),但它仍然有些不稳定!保持更新在wkhtmltopdf.org和github上。Google代码网站已过时,并且正在缓慢迁移。
display: inline-block
。将其更改为,block
然后进行更改,所有这些都开始起作用!
这是旧文章,但是由于我浪费大量时间试图找到适当的解决方案,所以我将其放在此处,也许对某人有用。
所以从我读到的问题来看
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>
将按预期工作。
我对行距的情况比较复杂,因此从上面的解决方案是将其破坏成和平,这不是期望的效果。我使用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;
}
经过数天的研究,我终于找到了完美的解决方案。您可以参考phpwkhtmltopdf这个项目。查看目录article
,您将找到针对3个问题的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,你一定想知道这些 退房的要点,如果你想为wkhtmltopdf要点
在我的特殊情况下,由于某种原因,以前的答案都对我无效。最终起作用的实际上是几件事的组合。
我安装(在Ubuntu 16.04)的Wkhtmltopdf Python包装称为pdfkit使用PIP 3,然后,而不是通过安装Wkhtmltopdf易于得到我通过下面的脚本安装了静态二进制(版本0.12.3),从这里取
#!/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/
添加了此CSS(如此处答案之一所示):
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模板生成HTML,然后将其提供给Wkhtmltopdf并获得漂亮的分页PDF。
我尝试了对表的所有方式的操作,但是尝试执行的任何操作都无法阻止将分页符置于行的中间。无奈之下,我尝试了不同的版本,并发现了以下内容:
Wkhtmltopdf 0.12.2.1:错误
Wkhtmltopdf 0.12.3:错误
Wkhtmltopdf 0.12.1:好
我的解决方案是将版本降级到0.12.1,从而解决了我的问题。当然,它们的出现可能部分是由于我的html并不是超级OCD,但是由于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>
除了Nanotelep所说的以外,这是手动表格分页算法的有效实现。 https://github.com/AAverin/JSUtils/tree/master/wkhtmltopdfTableSplitHack
以上答案对我没有用。我必须专门禁用pdfkit配置中的zoom选项。
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
对于仍然对此有疑问的任何人,要记住的一件事是桌子必须是body的直接子对象,否则css将无法正常工作(至少这就是我所发生的事情)。
display: table-cell;
应用的div内。使这些样式@media only screen
固定的分页符。如果无法使分页符正常工作,请尝试通过分阶段删除一半CSS并查看其是否起作用来进行分而治之。
另一种选择:将每个tr
在其自己的tbody
,然后应用Peage酒店休息CSS规则tbody
。表支持多个tbody
。
有点额外的标记,但对我来说不错。
我结合了一些建议的解决方案解决了这个问题。
我将表包装在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版本0.12.4,并通过将软件包的版本降级为0.12.3
!