Я создаю pdf-отчет с html-страницы с одной таблицей.
Я использую wkhtmltopdf для этой цели.
когда PDF сгенерирован, он разбивается где угодно в теге tr.
Я хочу этого избежать.
Я создаю pdf-отчет с html-страницы с одной таблицей.
Я использую wkhtmltopdf для этой цели.
когда PDF сгенерирован, он разбивается где угодно в теге tr.
Я хочу этого избежать.
Обновление 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;
}
Также рассмотрите следующие проблемы wkhtmltopdf, у них есть интересные комментарии, которые обсуждают, например, проблему разбиения таблицы. Существует решение JS, которое программно разделяет таблицы в 168, которые могут вам помочь (я не использую их, хотя).
  Обновление 08.11.2013
Об этом подробно говорится в статье 168 выше. Кто-то сумел скомпилировать версию wkhtmltopdf, которая поддерживает лучшее разбиение таблиц, но, к сожалению, кажется, что она официально не выпущена и может содержать другие ошибки. Я не знаю, как это получить, и я не знаю, как скомпилировать в Windows, но любой желающий может проверить, например, комментарий  здесь (см. новое обновление ниже).
Обновление 24.02.2014 Вам будет приятно услышать, что в wkhtmltopdf 0,12 эта особенность среди других была значительно улучшена. Однако подождите 0.12.1 и тщательно испытайте, прежде чем начинать использовать какую-либо новую версию, но она все еще немного нестабильна, хотя новые ребята, работающие с antialize, делают отличную работу (камни ashkulz)! Продолжайте обновление wkhtmltopdf.org и github. Сайт google-кода устарел и медленно мигрирует.
Это старый пост, но поскольку я тратил много времени на поиск правильного решения, я его поместил, может быть, кому-то это будет полезно.
Итак, из того, что я читал, проблема с
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>
будет работать как ожидалось.
У меня был более сложный случай с rowspans, поэтому решение сверху разбивало его на грань, что не было желательным эффектом. Я решил его использовать divs для каждого набора строк в строках. Мой 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 разбивает ее на две части и повторяет заголовки столбцов на новой странице, и эти заголовки столбцов отображаются на первый строки.
Я нашел временное решение этой проблемы в разделе вопросов whtmltopdf github: https://github.com/wkhtmltopdf/wkhtmltopdf/issues/2531
Просто добавьте эти строки в свой вид css:
tr {
  page-break-inside: avoid; 
}
		Я обнаружил, что wkhtmltopdf 0.12.2.1 и далее исправил эту проблему.
В моем конкретном случае по какой-то причине ни один из предыдущих ответов не работал у меня. То, что в конечном итоге работало, было на самом деле комбинацией нескольких вещей.
Я установил (в Ubuntu 16.04) оболочку python Wkhtmltopdf, называемую pdfkit, используя pip3, а затем вместо установки Wkhtmltopdf через apt-get Я установил статический двоичный файл (версия 0.12.3), следуя ниже script ниже
#!/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, которая решила мои проблемы. Конечно, они могли быть отчасти из-за того, что не были супер OCD о моем html, но поскольку HTML создается внутри TinyMCE (пользователями), у меня действительно нет большого выбора.
Кроме того, вложенные таблицы для меня не работают.
Я столкнулся с той же проблемой, добавленной после множества пробных ошибок n, которые этот css решил проблему
 tr {
display: inline-table;
}
Как использовать разрывы страниц внутри PDF без перерывов?
Вот решение, которое вы можете использовать в любом файле HTML.....
После запуска вашего tr вы должны взять div внутри tr и передать этот 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
Ответы выше не помогли мне. Мне пришлось специально отключить опцию масштабирования моей конфигурации 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 не будет работать ( по крайней мере, то, что случилось со мной).
Я нашел это смешное решение, но он работал очень хорошо для меня:)
Я просто положил очень длинный столбец rowspan, как этот
<td rowspan="XXX TOTAL ROWS" style="width:0px"></td>
а затем таблица не сломается.
Другой вариант: поместите каждый tr в свой собственный tbody, а затем примените правила css break break для tbody. Таблицы поддерживают несколько tbody s.
Немного дополнительной разметки, но подходит для меня достойно.
 Я копался в этой проблеме в течение нескольких дней и наконец нашел идеальное решение. Вы можете сослаться на этот проект 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;
}
 Если вы китаец, не стесняйтесь проверять этот сайт kh wkhtmltopdf , 你 一定 想 知道 这些 Проверьте суть, если вы хотите суть для 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>
 Мне не нужно было создавать какие-либо div внутри тегов td или th.
Важные вещи, которые я заметил при попытке решить проблему:
Надеюсь, это поможет.
 Я много боролся с этой проблемой, используя последнюю версию h4cc/wkhtmltopdf-amd64 0.12.4, и, наконец, заставил ее работать, понизив версию пакета до 0.12.3 !
Чтобы избежать разрыва страницы, мы можем использовать опцию разрыва страницы, чтобы избежать css.
tr { page-break-inside: avoid; }
 Разбейте любой контент (изображение/текст) и сделайте так, чтобы он появился на следующей странице
.sample-image { page-break-before: always; }