将 Prawn 与 rails 应用程序一起使用:将生成的 pdf 文件发送到用户的下载文件夹而不是应用程序目录

Using Prawn with rails app: Send generated pdf file to user's downloads folder instead of app directory

在控制器中,我在其中一个操作中有以下行:

def some_action
  @blog = Blog.find(11)
  PdfSingleBlog.new(@blog).print
end

PDfSingleBlog 只是一个充当服务的 PORO class。该服务的工作显然是生成此博客的 pdf,并且应该将该 pdf 发送到用户的下载文件夹。该代码位于此处:

#app/services/pdf_single_blog.rb
class PdfSingleBlog

  def initialize(blog)
    @blog = blog
  end

  def print
    pdf = Prawn::Document.new
    pdf.text "Blog Name: #{@blog.name}"
    pdf.text "Description: #{@blog.description}"
    pdf.render_file "blog_info.pdf"
  end
end

pdf 已成功生成,但未将其发送到用户的下载文件夹。相反,它会将其保存到服务器上应用程序的目录中。

如何将生成的 pdf 实际发送到用户的下载文件夹?

PDF of prawn manual found here


更新了以下答案:


def some_action
  @blog = Blog.find(11)
  blog_pdf = PdfSingleBlog.new(@blog).prepare_for_print
  send_data blog_pdf.render, filename: "blog.pdf", type: "application/pdf"
end

#app/services/pdf_single_blog.rb
class PdfSingleBlog

  attr_reader :blog
  def initialize(blog)
    @blog = blog
  end

  def prepare_for_print
    pdf = Prawn::Document.new
    pdf.text "Blog Name: #{@blog.name}"
    pdf.text "Description: #{@blog.description}"
    return pdf
  end
end

虽然您现在正在生成文件,但实际上并没有将其发送到浏览器。虽然您可以使用 send_file 将本地生成的文件发送到浏览器,但这需要您生成文件并将其保存在本地。

由于这个文件是动态生成的,我建议使用 send_data 来避免保存文件的需要。

您可以通过进行以下修改来做到这一点

在您的控制器中:

def some_action
  @blog = Blog.find(11)
  send_data PdfSingleBlog.new(@blog).print_data, filename:'blog.pdf', type: "application/pdf", disposition: :attachment
end

在您的模型中:

class PdfSingleBlog

  def print_data
    pdf = Prawn::Document.new
    pdf.text "Blog Name: #{@blog.name}"
    pdf.text "Description: #{@blog.description}"
    pdf.render
  end
end

这会将 pdf 作为附件流式传输到浏览器,提示最终用户打开或下载文件。