Я створюю звіт у форматі 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 і ретельно протестуйте, перш ніж почати використовувати будь-яку нову версію, вона все ще трохи нестабільна, хоча нові хлопці, які працюють з антиалізацією, роблять чудову роботу (скелі Ашкульца)! Будьте в курсі 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 розбиває її на дві частини та повторює заголовки стовпців на новій сторінці, і ці заголовки стовпців з’являються накладеними на перший рядок.
Часове рішення цієї проблеми я знайшов у розділі проблем із github wkhtmltopdf: 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
Я виявив, що wkhtmltopdf 0.12.2.1 і далі вирішив цю проблему.
У моєму конкретному випадку чомусь жодна з попередніх відповідей не спрацювала для мене. Що в підсумку вдалося, насправді було поєднанням кількох речей.
Я встановив (в Ubuntu 16.04) обгортку піктону Wkhtmltopdf з назвою pdfkit за допомогою pip3, а потім замість установки Wkhtmltopdf через apt-get встановив статичний двійковий файл (версія 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 і отримувати красиво розбитий на сторінки сторінки.
Я спробував усілякі маніпуляції зі своїми таблицями, але нічого, що я спробував, не могло зупинити розміщення розривів сторінок у середині рядка. У відчаї я спробував різні версії і виявив наступне:
Wkhtmltopdf 0.12.2.1: Погано
Wkhtmltopdf 0.12.3: Погано
Wkhtmltopdf 0.12.1: Добре
Моїм рішенням було перейти на версію 0.12.1, яка вирішила мої проблеми. Звичайно, вони могли бути частково пов’язані з тим, що вони не були супер OCD щодо мого html, але оскільки HTML формується всередині TinyMCE (користувачами), у мене насправді немає великого вибору.
Крім того, вкладені таблиці не працюють для мене в жодній версії.
Як використовувати розриви сторінок всередині pdf без break a tr?
Ось рішення, яке можна використовувати в будь-якому файлі 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>
Я стикався з тією ж проблемою, додавши після багатьох пробних помилок n, ця css вирішила проблему
tr {
display: inline-table;
}
Окрім того, що говорить 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 не буде працювати (принаймні, це сталося зі мною).
display: table-cell;
застосованим. Вирішення цих стилів @media only screen
виправило розриви сторінок. Якщо вам не вдається змусити працювати розриви сторінок, спробуйте розділити і завоювати, видаляючи поетапно половину CSS і перевіряючи, чи це працює.
Інший варіант: розмістіть кожен tr
у своєму, tbody
а потім застосуйте правила css peage break css до tbody
. Таблиці підтримують кількаtbody
s.
Трохи додаткової розмітки, але для мене працює гідно.
Я вирішив проблему, використовуючи комбінацію деяких запропонованих рішень.
Я загорнув свою таблицю в 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; }
У вас є голова столу? а тіло столу?
<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>
теги я пропоную спробувати додати їх першими.