Rails中的文件下载链接

67

我想为访问者提供下载一些PDF文件的选项。 我已经尝试过:

<%= link_to "abc", "/data/abc.pdf"%>

<%= link_to "abc", "/data/abc.pdf", :format => 'pdf' %>

我尝试了一些变化,但它们似乎都不起作用。我一直收到 No route matches [GET] "/data/abc.pdf" 的错误提示。

我把pdf文件放在一个名为data的文件夹中,该文件夹位于assets文件夹中。任何帮助将不胜感激。

6个回答

89

Rails 4:

在路由文件中:

get "home/download_pdf"

在控制器中(已经有PDF文件):

def download_pdf
  send_file(
    "#{Rails.root}/public/your_file.pdf",
    filename: "your_custom_file_name.pdf",
    type: "application/pdf"
  )
end

在控制器中(需要生成PDF):

require "prawn"
class ClientsController < ApplicationController

  def download_pdf
    client = Client.find(params[:id])
    send_data generate_pdf(client),
              filename: "#{client.name}.pdf",
              type: "application/pdf"
  end

  private

  def generate_pdf(client)
    Prawn::Document.new do
      text client.name, align: :center
      text "Address: #{client.address}"
      text "Email: #{client.email}"
    end.render
  end
end

就该问题而言:

<%= link_to 'Download PDF', home_download_pdf_url %>

Rails 3

实现方法:

def download
  send_data pdf,
    :filename => "abc.pdf",
    :type => "application/pdf"
end

你应该去这个替代方案

Rails < 3

将文件放在public文件夹中

这可能是你的答案:如何从Rails应用程序下载文件

你应该把文件放在public文件夹中,这是诀窍。

如果正确放置文件,则应该可以正常工作。

如果你不能将文件移动到public文件夹中,请告诉我。

通过控制器下载

创建一个控制器,其中包含一个downlaod操作,然后使用link_to链接它

  def download
    send_file '/assets/data/abc.pdf', :type=>"application/pdf", :x_sendfile=>true
  end

那是一个旧版本的Rails。自从Rails 3(我想)开始,公共文件夹变成了资产文件夹。 - Ionut Hulub
好的,我尝试了一下,它起作用了。我相当确定自 Rails 3 以来所有资源都应该放在 assets 文件夹中,但既然它能工作,现在就这样吧。谢谢。 - Ionut Hulub
抱歉,没有指明您使用的是哪个版本的Rails。 - felipeclopes
检查我刚刚为Rails 3所做的新编辑。希望它能对你有所帮助! - felipeclopes
如果这些PDF文件对所有人都可用,就不需要采用这种方法。在Rails 3.1中,js、css和图像被移动到资产文件夹中(因为预编译),但公共文件夹仍然有其目的,就像这个文件夹一样 :) - BurmajaM

78

Rails 4:

在路由中:

get "home/download_pdf"

在控制器中(已经有PDF文件):

def download_pdf
  send_file(
    "#{Rails.root}/public/your_file.pdf",
    filename: "your_custom_file_name.pdf",
    type: "application/pdf"
  )
end

在控制器中(需要生成PDF):

require "prawn"
class ClientsController < ApplicationController

  def download_pdf
    client = Client.find(params[:id])
    send_data generate_pdf(client),
              filename: "#{client.name}.pdf",
              type: "application/pdf"
  end

  private

  def generate_pdf(client)
    Prawn::Document.new do
      text client.name, align: :center
      text "Address: #{client.address}"
      text "Email: #{client.email}"
    end.render
  end
end

在视图中:

<%= link_to 'Download PDF', home_download_pdf_url %>

2
只需使用 <%= link_to "下载PDF", "files/pdf.pdf", :class => "themed_text" %> 即可下载PDF文件。 - Navin
使用路由URL的优点是,如果文件作为临时文件内联生成,则不需要依赖于特定的文件名/路径。 - user483040
进一步澄清,我知道这不是楼主的问题,但这是一个更普遍的答案。 - user483040
@Navi 我尝试了你的方法,但是我一直收到“没有匹配路由”的错误。我的目录是/assets/templates/,当我在控制台中使用Rails.application.config.assets.paths时,它被列出来了,但是在我的public文件夹中却没有列出来。你能看出问题在哪里吗? - Marklar
你如何调整这个程序以适应多个文件?例如,一个包含需要在列表中生成链接的文件的文件夹。 - Btuman
Rails 5也是一样的吗? - stevec

25

如果文件是静态的(指它们不会改变),请将它们放在公共文件夹中。

然后您可以像这样下载

<a href="file.pdf" download>PDF</a>

或使用 ERB

<%= link_to 'PDF', 'file.pdf', download: '' %>

如果要为下载文件指定另一个名称,只需将该名称传递给下载选项即可。

<%= link_to 'PDF', 'file.pdf', download: 'data' %>

这将把文件下载为data.pdf而不是file.pdf


4
您可以像这样简单地调用您的控制器操作:
<%= link_to "Download", download_file_path, class: "btn btn-sm btn-default", target: "_blank" %>

在你的控制器中

def download_file
 redirect_to paperclip_attachment.file.url
end

这是一个Rails项目,因此您需要使用link_to助手。 - daslicious
这个建议是要求对回答进行负面评价还是只是告诉发布者更新他/她的回答?我认为这种态度对于像我这样的新手 SO 用户来说不太合适。 - Muhammad Nasir Shamshad
只是想帮助新手,态度很重要。问题中使用了helper,这也是在回答中使用它的更好理由。 - daslicious

1

我为了找到一个简单的方法来自动下载公共目录中的某些文件而苦恼了很久。 最后,我想出了这个解决方案。 例如: 我在公共目录的SVG文件夹中有一个文件。

Public/svg/Test1.xlsx

现在当我尝试访问它并使用纸夹路径时,它会出现问题。 即使我尝试完整路径也会出现问题,所以我们可以使它成为动态路径。 首先获取主机路径,以便可以轻松重定向。 <% url = request.original_url.chomp(request.fullpath) %>
现在我们可以像下面这样访问公共文件夹中的任何文件,并传递id和下载选项。 下载选项可以将任何要下载的文件重命名。
<%= link_to 'Database File', "#{url}/svgs/Test1.xlsx", download: 'Data.xlsx',id: "Link_to_Downlaod" %>

现在可点击的链接已经准备好,我们可以点击上面的链接来下载文件。使用以下脚本可以自动下载文件。
  <script type="text/javascript">
    window.onload = document.getElementById('Link_to_Downlaod').click();
  </script>
</div>

对于PDF或任何其他文件类型,只需要更改文件扩展名即可。

1

对于我来说,链接到PDF文件的最佳解决方案是通过以下简单步骤:

1- 将您的PDF文件添加到public文件夹中

2- <%= link_to "/nameofthefile.pdf",target: "_blank" do %>pdf file<% end %>

这里有一个视频为您详细展示 https://www.youtube.com/watch?v=bNZ6FJrZ_lo&t=64s`


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接