javascript - 在 Rails 4 的邮件中生成 PDF 作为附件

标签 javascript ruby-on-rails pdfkit wicked-pdf shrimp

问题

我想发送附有发票 PDF 的电子邮件。

我已经有了带有样式和 javascript 的发票显示 View ​​。

javascript 正在计算总计字段、格式化货币和日期并在分页符处拆分。

显示 View 显示发票,就像它应该在 pdf 上一样。

尝试

  1. 我试过了wicked_pdfpdfkit .问题是 这样做的时候..

    html = render_to_string(:action => "../invoices/show_pdf.html.erb") 
    mail(:to => @registration.billing_email, :subject => "Faktura") do |format|
      format.pdf do
        attachments['faktura.pdf'] = PDFKit.new(html).to_pdf
      end
    

    ..我没有浏览器来解释 javascript。所以所有 计算和格式消失了。当我在浏览器中打开 pdf 时,它是正确的。

  2. 我也试过shrimp它使用 phantomjs 生成 PDF 的。这个解决方案的问题是我正在使用设计和 phantomjs 浏览器必须以某种方式登录。

我需要一些关于这个问题的优雅解决方案的建议。

要么

在使用 pdfkit 或 wicked_pdf 生成 PDF 之前使用所有 javascript 渲染 View 的一些方法

如何将 session cookie 分配给 phantomjs?

我知道这是两个问题,但因为它解决了一个问题,所以我希望它没问题。

最佳答案

我认为 是您最好的选择。由于您需要执行 javascript,因此运行 PhantomJS 的解决方案可能是您唯一的选择。

Shrimp 提供了一种在请求中添加 session cookie 的简单方法。就像下面这样:

Shrimp::Phantom.new(url, options, {user_session: "a session"})

正如您所理解的 initializer接受一个选项散列,然后是一个包含您的 cookie 及其值的散列。

现在最困难的部分是在您的服务器上始终有一个有效的 session 来执行请求。根据您的 session 管理(例如,您可能有自动过期),这可能有点棘手。


编辑:添加 Andreas 关于如何使用 Devise 基于相关 blog post 在 Rails 应用程序中破解用户 session 的发现。由虾创造者:

lib/devise/sign_in_interceptor.rb

module Devise
  class SignInInterceptor
    def initialize(app, opts)
      @app    = app
      @scope  =opts[:scope]
      @secret = opts[:secret]
      @klass  = opts[:klass]
    end

    def call(env)
      if user = Rack::Request.new(env).cookies[@secret]
        env['warden'].session_serializer.store(@klass.constantize.find(user), @scope)
      end

      @app.call(env)
    end
  end
end

config/application.rb

require File.expand_path('../../lib/devise/sign_in_interceptor', __FILE__)
config.middleware.use Devise::SignInInterceptor, { :scope  => :user, :klass => 'User',
                                                    :secret => "our_very_very_long_secret" }

通过此设置,我们可以将 to_pdf 方法添加到我们的资源中 发票.rb

def to_pdf
  host        = Rails.env.production? ? 'www.adjust.io' : 'localhost:3000'
  url         = Rails.application.routes.url_helpers.reports_url(self, :host => host)
  cookie      = { 'our_very_very_long_secret' => user_id } #user_id is a instance method on the invoice class 
  options     = { :margin => "1cm"}
  res         = Shrimp::Phantom.new(url, options, cookie).to_pdf("#{Rails.root}/invoices/invoice_#{self.id}.pdf")
end

关于javascript - 在 Rails 4 的邮件中生成 PDF 作为附件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21763330/

相关文章:

php - Cakephp 表单必须提交两次才能工作

javascript - 禁用提交,但如果按下后退按钮,请确保其重新启用

javascript - 使 webpack 库输出与 babel 6 兼容

ruby-on-rails - 使用 bundle exec 运行 Rails 控制台

javascript - Rails - 如何在添加项目时强制刷新页面

javascript - PDFKit Node.js 测量单位

javascript - 在 Bootstrap 向导中禁用下一个导航链接

python - 使用pdfkit python在第一页上使用不同的边距

ios - 如何在“打开方式...”菜单中使用我的应用程序将 pdf 文件作为 URL 加载

ruby-on-rails - Rails:NameError:未初始化的常量 Sidekiq::RetrySet