【问题标题】:How to include css stylesheet into wicked pdf?如何将 css 样式表包含到 wicked pdf 中?
【发布时间】:2020-02-17 18:42:13
【问题描述】:

我被宝石 wicked_pdf 困住了。

  • 我正在生成一个 pdf 报告,我想包含样式表。
  • 样式表是通过 webpack 和 tailwindcss 生成的。

在 wicked_pdf 文档中,据说我可以使用 wicked_pdf_stylesheet_pack_tagwicked_pdf_javascript_pack_tag 从 webpack 中包含我的样式表和 javascript,但没有任何效果。

这是来自控制器的代码:

      format.pdf do
        render template: "pdf_reports/show", 
        layout: "wicked_layout",
        pdf: "report"
      end

这是布局中的代码:

<!DOCTYPE html>
    <html>
        <head>
           <%= csrf_meta_tags %>
           <%= wicked_pdf_javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
           <%= wicked_pdf_stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
           <%= wicked_pdf_stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
      </head>
      <body>
        <%= yield %>
      </body>
</html>

这是来自 pdf.erb 视图的代码:

<h1 class="text-red-base">Test pdf</h1>
<h2 class="test-wicked">mldgmdjgfd</h2>

它适用于 wicked_pdf_stylesheet_link_tag(从 sprockets 应用 test-wicked:文本为蓝色)但不适用于 wicked_pdf_stylesheet_pack_tag(h1 应该是红色但不是)。

知道发生了什么吗?

谢谢!

【问题讨论】:

标签: ruby-on-rails webpack wicked-pdf


【解决方案1】:

分析

webpack 助手做了几个假设,这些假设可能并不适用于每个项目。

根据running_in_develpment? 返回的内容,它们会产生两种不同的结果。对于 webpacker 3.0.0 或更高版本,此方法委托给 Webpacker.dev_server.running?

如果没有运行开发服务器,帮助程序将假定资产已预编译,并将尝试将资产的内容粘贴到 &lt;style&gt;&lt;script&gt; 标记中。如果资产在生产环境中预编译并且在应用程序运行的环境的文件系统中可用,这应该可以工作。这通常是正确的。

随着开发服务器的运行,webpack 助手将返回一个标签,其中包含指向包资产的资产路径(最终使用标准的 asset_path 助手)。实际路径取决于 rails 配置。在某些情况下,路径将与 wkhtmltopdffile://... 呈现的 html 不兼容:

  • 如果config.action_controller.asset_host 未设置,asset_path 将产生相对路径。这些在 wkhtmltopdf 从文件渲染中不起作用。

  • 如果设置了config.action_controller.asset_host,则将在整个应用程序中使用绝对 URL(这是控制asset_path 返回内容的常规设置)。现在wkhtmltopdf 可能能够获取资产,如果它在可以解析和访问资产主机的环境中运行。这在容器化应用程序中可能不是真的。

其他限制

在我们的例子中,我们有一些额外的限制:

  • 我们的 PDF 发射动作支持一个参数,使它们将 show_as_html: true 传递给 render。这使得wicked_pdf 跳过 PDF 生成并返回中间 HTML。我们使用它来调试浏览器中的 HTML 视图。此 html 将由开发人员的浏览器在与运行 wkhtmltopdf 的环境不同的环境中呈现。

  • 我们的开发设置是单线程的,因为我们使用better_errors 调试器,它依赖于由同一应用程序实例处理的所有请求。另一方面,我们在请求中呈现 PDF。这意味着wkhtmltopdf 将无法从应用程序请求资产(例如通过将host: "localhost:3000" 传递给asset_path),因为它已经占用了唯一可用的线程。

示例解决方案

我们的解决方案是实施我们自己的助手,这些助手更了解我们的设置。

  1. 在生产中,默认行为与我们的设置兼容,因此我们委托给原始版本,它将在文件系统中查找资产并将它们包含在生成的 HTML 中。

  2. 在开发中,当生成 PDF 时,我们将 webpack 开发服务器的主机名/端口传递给 webpacker 标签助手(这会将它们传递给asset_path)。开发服务器在单独的进程中运行,因此即使应用程序在请求处理程序中也会响应。

  3. 1234563应用程序,它将在浏览器中运行。
module PdfHelper
  def pdf_stylesheet_pack_tag(source)
    if running_in_development?
      options = { media: "all" }
      wds = Webpacker.dev_server
      options[:host] = "#{wds.host}:#{wds.port}" unless show_as_html?
      stylesheet_pack_tag(source, options)
    else
      wicked_pdf_stylesheet_pack_tag(source)
    end
  end

  def pdf_javascript_pack_tag(source)
    if running_in_development?
      options = {}
      wds = Webpacker.dev_server
      options[:host] = "#{wds.host}:#{wds.port}" unless show_as_html?
      javascript_pack_tag(source, options)
    else
      wicked_pdf_javascript_pack_tag(source)
    end
  end
end

在 pdf 布局中 (slim)

html
  head
    ...
    = pdf_stylesheet_pack_tag "pdf"
    = pdf_javascript_pack_tag "pdf"
    ...

【讨论】:

  • 您的解决方案对我来说效果很好,除了“show_as_html?”函数需要在助手的上下文中定义。我目前的解决方法是在“def show_as_html?; params[:debug].present?; end”中正确定义它。我的渲染调用中的 show_as_html 选项也基于 params[:debug]。
  • 效果很好,只是我需要在 stylesheet/javascript_pack_tag 调用中使用扩展运算符 **options 插入 options
猜你喜欢
  • 2015-11-12
  • 1970-01-01
  • 2013-11-17
  • 2017-08-28
  • 2014-11-17
  • 1970-01-01
  • 1970-01-01
  • 2015-12-19
  • 2015-12-25
相关资源
最近更新 更多