WKHTMLTOPDF与Rails上的pdfkit忽略表分页符

时间:2014-11-28 17:25:26

标签: ruby-on-rails-4 wkhtmltopdf pdfkit

我知道wkhtmltopdf和分页符存在很多问题可以追溯到几年前,但我还没有找到解决方案。我正在使用PDFKit gem将我的html页面生成为pdfs,但我不希望页面在表格行的中间打破。

我正在使用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>

是否有工作,或者有什么我做错了?这是结果:

enter image description here

我也可以发布PDFKit代码,但听起来像wkhtmltopdf问题

***更新 - 当.pdf添加到网址时,我的CSS @print不会影响页面。我的媒体样式表链接:“all”

<%= 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 个答案:

答案 0 :(得分:2)

我在css中为我添加了这个

@media print {
#scores {
      page-break-before: always;
    }
}

答案 1 :(得分:1)

我使用的是版本wkhtmltopdf 0.12.0

对我来说,分页符只适用于--print-media-type。 没有它,图像的分页保护可以正常工作,但不能在分页后或之前使用。

我必须为打印介质制作一个特殊的css文件才能使其正常工作。

将纸张尺寸设置为“A3”或使用“溢出:可见”没有任何区别。

我最终得到了以下内容:

在config / initializers中:

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

如果需要no_background,我不能100%确定。

然后,在控制器中:

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)

要在视图中创建分页符,我只需将其插入正确的位置:

我希望有一天这对某人有用。

答案 2 :(得分:0)

您可以将控制器代码上传到您调用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

答案 3 :(得分:0)

以下是我解决问题的方法。 - 更新PDFKIT至(2014年1月22日) - 我不得不将我的桌子移出<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

希望这会有所帮助。