如何避免wkhtmltopdf表格行内的分页符

Moh*_*ikh 73 pdfkit wkhtmltopdf

我从一个表格的 html页面生成pdf报告.

我正在使用wkhtmltopdf.

当生成pdf时,它会破坏tr标签中的任何位置.

我想避免它.

Nen*_*lep 132

更新17.09.2015:检查您使用的版本:wkhtmltopdf 0.12.2.4据说可以解决问题(我没有检查过).


这是wkhtmltopdf中的已知问题.webkit使用的分页算法(WK在WKhtmltopdf中)对于大型表格并不适用.我建议将表格拆分为较小的块,这些块更容易拆分为页面并使用css:

table, tr, td, th, tbody, thead, tfoot {
    page-break-inside: avoid !important;
}
Run Code Online (Sandbox Code Playgroud)

另外看看下面的wkhtmltopdf问题,他们有一些有趣的评论,例如讨论表分裂问题.有一个JS解决方案,以编程方式在168中拆分可能对您有帮助的表(尽管我不使用它).

更新08.11.2013 在上面链接的问题168中有很多关于此的讨论.有人设法编译了一个支持更好的表格破坏的wkhtmltopdf版本,但不幸的是它似乎没有正式发布,可能包含其他错误.我不知道如何获得它,我不知道如何在Windows上编译,但任何感兴趣的人都可以查看这里的评论(见下面的新更新).

更新24.02.2014 您将很高兴听到在wkhtmltopdf 0.12中这个功能已经大大改进.然而,在开始使用任何新版本之前等待0.12.1并进行彻底测试,虽然使用antialize的新人做得很好(ashkulz rock),但它仍然有点不稳定!请在wkhtmltopdf.orggithub上更新.谷歌代码网站已过时,正在慢慢迁移.

  • 我挣扎了几天.原来我的桌子是一个div的样式`display:inline-block`.将其更改为`block`,并且上面的更改全部开始工作! (3认同)
  • @Nenotlep谢谢你的回答.是的,我已经发布了一个关于这个问题的新问题:http://stackoverflow.com/q/36334330/3391783 - 这很有趣,这一切似乎都在0.12.1-ish或0.12.2-ish版本中运行并且被破坏了再次以0.12.3-ish版本. (2认同)
  • @DjDacSaunders WKHTMLTOPDF是一个黑客,而不是一个纯粹的HTML - > pdf工具.其重点是将非常长的文档呈现为分页格式.我们对此有任何控制权的事实很棒.如果你想要这个改进绝对最好的联系地点是wkhtml的上游,它可以是QT项目,也可能是WebKit项目.我预见这件事永远不会改变,因为WebKit在将网页渲染为PDF文件时不应该做的事情:/为了完全控制,也许尝试使用PrinceXML.(x)HTML不是一种印刷格式,而对于该概率的"解决方案"总是很糟糕. (2认同)

小智 17

这是老帖子,但由于我浪费了很多时间试图找到合适的解决方案,我会把它放在这里,也许它会对某人有用.

所以从我读到的,问题

page-break-inside: avoid
Run Code Online (Sandbox Code Playgroud)

是它不起作用.但实际上,如果你将它设置在元素上,display:block它可以按预期工作(如SO中某处所述).所以对于表css的简单结构

td div, th div{
    page-break-inside: avoid;
}
Run Code Online (Sandbox Code Playgroud)

和表结构

<table>
....
<tr>
    <td><div>some text</div></td>
    <td><div>more text</div></td>
</tr>
....
</table>
Run Code Online (Sandbox Code Playgroud)

将按预期工作.

我有一个更复杂的案例与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');
    });
});
Run Code Online (Sandbox Code Playgroud)

CSS:

div.new-section {
    page-break-inside: avoid;
}
.container, .new-section, .new-section table.fixed{
    width: 100%;
}

.new-section table.fixed{
    table-layout:fixed;
}
Run Code Online (Sandbox Code Playgroud)

我不知道是否需要一切,我不认为它是完美的,但它确实起到了作用.仅在镀铬上测试过


小智 13

从0.12开始,这个问题已经解决了,但有时,当一个表太长而无法放入页面时,wkhtmltopdf将它分成两部分并重复新页面上的列标题,这些列标题显示为叠加到第一行.

我在wkhtmltopdf github问题部分找到了这个问题的暂时解决方案:https: //github.com/wkhtmltopdf/wkhtmltopdf/issues/2531

只需将此行添加到您的视图css:

tr {
  page-break-inside: avoid; 
}
Run Code Online (Sandbox Code Playgroud)


Uni*_*ain 7

我已经研究这个问题好几天了,终于找到了完美的解决方案。你可以参考这个项目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;
}
Run Code Online (Sandbox Code Playgroud)

如果您是中国人,请随时查看此站点??wkhtmltopdf????????? 如果您希望wkhtmltopdf 的要点,请查看要点

  • 这对我有用。我正在使用 *wkhtmltopdf 0.12.4*。谢谢! (2认同)

Yor*_*Mak 5

我发现wkhtmltopdf 0.12.2.1以后修复了这个问题.

  • 这不是真的.我们仍然有这个问题. (4认同)

Aca*_*lco 5

在我的特殊情况下由于某些原因,以前的答案都没有对我有用.最终工作的实际上是几件事的组合.

  1. 我使用pip3 安装了(在Ubuntu 16.04中)Wkhtmltopdf python包装器,名为pdfkit,然后通过apt-get安装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/
    
    Run Code Online (Sandbox Code Playgroud)
  2. 添加了这个CSS(如其中一个答案所示):

    tr, td div, th div{
        page-break-inside: avoid;
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 然后按照这里的建议添加<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>
    
    Run Code Online (Sandbox Code Playgroud)

通过这些修改,我现在可以成功使用Mako模板生成HTML,然后将其提供给Wkhtmltopdf并获得精美的分页PDF :)