WKHTMLTOPDF с pdfkit на Rails игнорируя разрывы страниц таблиц
Я знаю, что есть много проблем с wkhtmltopdf и разрывами страниц, которые датируются годами, но я еще не нашел решения. Я использую гем PDFKit для генерации моих html-страниц в pdf, но я не хочу, чтобы страницы ломались в середине строки таблицы.
Я использую wkhtmltopdf-binary (0.9.9.3), который выглядит как самая обновленная версия
Мой CSS:
@media print {
#scores table tr td, #scores table tr th {
page-break-inside: avoid !important;
}
table, tr, td, th, tbody, thead, tfoot {
page-break-inside: avoid !important;
}
}
Мой стол:
<div class="score_table">
<table id="scores" class="print-friendly">
<tbody>
<% @chapters.each do |chapter| %>
<tr>
<th colspan="3" ><%= chapter.name %></th>
</tr>
<% chapter.rules.each do |rule| %>
<tr>
<th colspan="2" >Rule: <%= rule.name %></th>
<th></th>
</tr>
<!-- Triggers -->
<% rule.triggers.each do |trigger| %>
<tr>
<td>T</td>
<td><%= markdown(trigger.body) %></td>
<td><%= markdown(trigger.explanation) %></td>
</tr>
<% if trigger.image? || trigger.image2? %>
<tr>
<td></td>
<% if trigger.image? %>
<td><%= image_tag trigger.image.url(:thumb) %></td>
<% else %>
<td></td>
<% end %>
<% if trigger.image2? %>
<td><%= image_tag trigger.image2.url(:thumb) %></td>
<% else %>
<td></td>
<% end %>
</tr>
<% end %>
<% end %>
<!-- Questions -->
<% rule.questions.each do |question| %>
<tr>
<td>Q</td>
<td><%= markdown(question.body) %></td>
<td><%= markdown(question.answer) %></td>
</tr>
<% if question.image? || question.image2? %>
<tr>
<td></td>
<% if question.image? %>
<td><%= image_tag question.image.url(:thumb) %></td>
<% else %>
<td></td>
<% end %>
<% if question.image2? %>
<td><%= image_tag question.image2.url(:thumb) %></td>
<% else %>
<td></td>
<% end %>
</tr>
<% end %>
<% end %>
<!-- Hints -->
<% rule.hints.each do |hint| %>
<tr>
<td>H</td>
<td><%= markdown(hint.body) %></td>
<td><%= markdown(hint.explanation) %></td>
</tr>
<% if hint.image? || hint.image2? %>
<tr>
<td></td>
<% if hint.image? %>
<td><%= image_tag hint.image.url(:thumb) %></td>
<% else %>
<td></td>
<% end %>
<% if hint.image2? %>
<td><%= image_tag hint.image2.url(:thumb) %></td>
<% else %>
<td></td>
<% end %>
</tr>
<% end %>
<% end %>
<% end %>
<% end %>
</tbody>
</table>
</div>
Есть ли работа вокруг, или я что-то не так делаю? Это результат:
Я мог бы также опубликовать код PDFKit, но это звучит как вопрос wkhtmltopdf
*** Обновление - мой CSS @print не влияет на страницу при добавлении.pdf к URL. У меня есть своя таблица стилей с медиа: "все"
<%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %>
Вот мой инициализатор pdfkit.rb:
ActionController::Base.asset_host = Proc.new { |source, request|
if request.env["REQUEST_PATH"].include? ".pdf"
"file://#{Rails.root.join('public')}"
else
"#{request.protocol}#{request.host_with_port}"
end
}
Если я смогу исправить CSS, то я, вероятно, решу проблему разрыва страницы!
4 ответа
Я добавил это в CSS это работает для меня
@media print {
#scores {
page-break-before: always;
}
}
Я использую версию wkhtmltopdf 0.12.0
Для меня разрывы страниц работают ТОЛЬКО с --print-media-type. Без этого работает защита разрыва страницы для изображений, но не разрыва страницы или до.
Я должен был сделать специальный файл CSS для печатных СМИ, чтобы заставить его работать.
Установка формата бумаги на "А3" или использование "переполнения: видимый" не имеет никакого значения.
Я закончил со следующим:
в конфиге / инициализаторах:
PDFKit.configure do |config|
config.wkhtmltopdf = '/usr/bin/wkhtmltopdf'
config.default_options = {
:encoding=>"UTF-8",
:page_size => 'A3',
:zoom => 0.9,
:javascript_delay => 2000,
:print_media_type => true,
:footer_right => 'report, page [page] of [toPage]',
:no_background => true,
}
end
Я не уверен на 100%, нужен ли no_background.
Затем в контроллере:
def report_as_pdf
require 'nokogiri'
root_url = Rails.env.development? ? 'http://localhost:3000' : 'https://my.example.com'
html = render_to_string(layout: true, template: "reports/report_as_pdf").gsub('/assets', root_url + '/assets') # since wkhtmltopdf can not find the css files, we add the root_url to all assets
html_doc = Nokogiri::HTML(html)
html_doc.css('div.contain-to-grid').remove
html_doc.css('nav#rapportage_bar').remove
# Had to remove certain elements on the page. Not relevant for this particular problem, but it may help.
html = html_doc.to_html
filename = 'report_' + Time.now.to_s(:db)[0..9]
if Rails.env.development?
File.write("/tmp/#{filename}.html", html)
render :text => "wrote /tmp/#{filename}.html"
fork do
system("wkhtmltopdf --footer-right 'report, page [page] of [toPage]' --page-size 'A3' --zoom 0.9 --javascript-delay 2000 --no-background --print-media-type file:////tmp/#{filename}.html /tmp/#{filename}.pdf")
end
# forking was the only way I could get it to work in development mode, using thin as webserver instead of webrick (but it might work with webrick, I didn't try).
else
kit = PDFKit.new(html)
send_data(kit.to_pdf, :filename => filename + '.pdf', :type => 'application/pdf')
# all is simpeler in production mode.
end
end
Обратите внимание, что в макете по умолчанию (обычно app/views/layouts/application.html.erb) я добавил одну строку, чтобы ввести специальный файл css для печати:
stylesheet_link_tag "application_print", media: "print"
Этот файл фактически импортирует некоторые таблицы из ZURB Foundation, что круто.
@import "foundation/components/tables";
h1 {
font-variant: small-caps;
font-weight: bolder;
font-size: 320%;
border-bottom: 12px solid black;
margin-bottom: 20px;
margin-top: 80px;
}
h2 { (etc etc etc)
Чтобы сделать разрывы страниц в представлении, я просто вставляю это в нужных местах:
Надеюсь, это кому-нибудь пригодится.
Можете ли вы загрузить код контроллера, где вы назвали PDFkit.new?
Ваша таблица стилей может быть не включена. Попробуйте добавить таблицу стилей в код вашего контроллера следующим образом:
def export
kit = PDFKit.new(render_to_string(layout: false, handlers: [:haml], formats: :html, template: 'score_tables/export'))
kit.stylesheets << "#{Rails.root}/vendor/assets/stylesheets/bootstrap.css"
kit.stylesheets << "#{Rails.root}/app/assets/stylesheets/score_tables.css"
kit
end
Вот как я исправил свою проблему.
- Обновлен PDFKIT до (22.01.2014)
- Мне пришлось переместить свой стол из <div>
поскольку вложенная таблица все испортила.
Пример:
нет div
тег обтекания стола.
От
<div class="score_table">
<table id="scores" class="print-friendly">
...rest of the HTML
к
<table id="scores" class="print-friendly">
...rest of the HTML
Надеюсь это поможет.