代码之家  ›  专栏  ›  技术社区  ›  darko

生成带有大量页眉/页脚页面的pdf时出现wkhtmltopdf错误

  •  7
  • darko  · 技术社区  · 10 年前

    我正在使用pdfkit(它在引擎盖下使用wkhtmltopdf)在我的rails应用程序中生成PDF。遵循指南 here 我已经把它主要用于PDF的基本情况。我现在遇到了一个问题,当我试图生成一个包含大量页面的PDF时,这些页面也有页眉/页脚。尝试生成PDF时,我在控制台中的wkhtmltopdf中看到的错误是:

    QEventDispatcherUNIXPrivate(): Unable to create thread pipe: Too many open files
    QEventDispatcherUNIXPrivate(): Can not continue without a thread pipe
    

    可用于重新创建错误的html的最小示例:

    <!-- content of pdf_header_url is the character "h" -->
    <meta content="<%= pdf_header_url %>" name="pdfkit-header-html"/>
    <!-- content of pdf_footer_url is the character "f" -->
    <meta content="<%= pdf_footer_url %>" name="pdfkit-footer_html"/>
    <% [*1..3].each do |j|%>
      <h1><%= j %></h1>
      <ul>
        <% [*1..1000].each do |i|%>
          <li><%= i %></li>
        <% end %>
      </ul>
    <% end %>
    

    请注意,删除页眉/页脚标记可以使pdf呈现得更好。

    生成PDF的实际ruby代码是:

    def view_report
      html = render_to_string(:template => 'pdf/pdf_body.html', :layout => false)
      kit = PDFKit.new(html)
      pdf = kit.to_pdf
      send_data pdf, :type => 'application/pdf', :disposition => 'inline', :filename => 'foo.pdf'
    end
    

    访问此控制器路线将生成PDF。最后,我还有一个用于页眉/页脚的控制器,因为这些“部分”需要通过url获取:

    class PdfController < ApplicationController
    
      def header
        render :layout => false
      end
    
      def footer
        render :layout => false
      end
    
    end
    

    pdf_header_url和pdf_footer_url的值实际上只是“h”和“f”,这是一个最小的可重复示例。

    熟悉wkhtmltopdf的人是否对解决此问题的进一步调试步骤有任何建议?

    3 回复  |  直到 9 年前
        1
  •  8
  •   Tom Hirschfeld    10 年前

    我今天收到了同样的错误消息,我用一个非常简单的解决方案解决了这个问题。问题是我的页眉和页脚需要是带有html、head和body标记的完整html文档。此外,看看是否可以获取生成的页眉和页脚的html输出并验证它们。

        2
  •  7
  •   Joshua Pinter    6 年前

    打开文件限制。

    我确保页眉和页脚文件是完整的HTML文档 Tom Hirschfeld 建议,但我仍然收到打开文件太多的错误。

    在浏览互联网后,我发现你需要提高一个进程允许打开的文件数量的限制。在我的例子中,我正在生成数百到数千页的PDF。它在没有页眉和页脚的情况下工作得很好,但在合并页眉和页脚时,它似乎达到了打开文件的上限。

    根据您正在运行的系统,有不同的方法来调整此设置,但以下是我在Ubuntu服务器上使用的方法:

    在末尾添加以下内容 /etc/security/limits.conf :

    # Sets the open file maximum here.
    # Generating large PDFs hits the default ceiling (1024) quickly. 
    *    hard nofile 65535
    *    soft nofile 65535
    root hard nofile 65535 # Need these two lines because the wildcards
    root soft nofile 65535 # (the * above) are not applied to the root user.
    

    一个很好的参考 ulimit 可以找到命令 here .

    我希望这能让一些人走上正轨。

        3
  •  3
  •   ashkulz    10 年前

    wkhtmltopdf 每页使用2个文件描述符(页眉和页脚各一个),这是生成每页自定义变量所需的。你必须编辑 /etc/security/limits.conf 设置 nofile (即最大打开文件数)设置为适当的高值——可能需要一些实验来找到适合您的值。