如何从Rails提供文件供下载?

时间:2014-07-31 15:40:10

标签: ruby-on-rails angularjs csv

所以这可能是一个简单的问题,但我以前从未这样做过。

我有一个Rails操作,用于查询数据库并从查询结果中创建一个csv字符串。

我想获取查询字符串,将其放入.csv文件中,当用户发出与此方法关联的http请求时,.csv文件将下载到用户的计算机上。

我该怎么做?

更新

该文件是从rails发送的,但我前端的角度应用程序(请求csv)没有下载它。

这是我用来从rails app

请求文件的角度代码
$scope.csvSubmit = function() {
  var csv = $.post('http://ip_addr:3000/api/csv', { 'input': $scope.query_box });
  csv.done(function(result){
     //empty - after the request is sent I want the csv file to download
  })
}

2 个答案:

答案 0 :(得分:5)

您可以使用send_file方法,将路径作为第一个参数传递给文件,如Rails documentation中所示。

<强>更新

您可以使用临时文件保存CSV,如下所示:

require 'tempfile'

# automatically creates a file in /tmp
file = Tempfile.new('data.csv', 'w')
file.write('my csv')
file.close

send_file(file.path)

# remove the file from /tmp
file.unlink

更新2:AngularJS下载

有两种方法可以实现此目的:您可以添加隐藏的href以在页面中下载文件并单击它,或者将用户重定向到Rails URL,该URL在单击按钮时发送文件。请注意,重定向将使用网址中的参数,因此根据query_box的结构,它将无法正常工作。

使用CSV向页面添加隐藏的href:

$scope.csvSubmit = function() {
  var csv = $.post('http://ip_addr:3000/api/csv', { 'input': $scope.query_box });
  csv.done(function(result){
    var hiddenElement = document.createElement('a');

    hiddenElement.href = 'data:attachment/csv,' + encodeURI(result);
    hiddenElement.target = '_blank';
    hiddenElement.download = 'filename.csv';
    hiddenElement.click();
  })
}

使用重定向:

$scope.csvSubmit = function() {
  var url = 'http://ip_addr:3000/api/csv/?' + 'input=' + encodeURI($scope.query_box);
  window.location = url;
}

答案 1 :(得分:1)

我以前必须这么做很多次。您需要设置响应标头以使浏览器强制下载。

我喜欢使用comma gem来渲染csv。使用gem您需要做的就是在控制器操作中添加以下行。

 respond_to do |format|
   format.csv do 
     response.headers['Content-Type'] = 'text/csv'
     response.headers['Content-Disposition'] = 'attachment; filename=books.csv'
     render :csv => Book.limited(50)  
   end
 end

然后你只需使用csv格式就行了。

如果您不想使用逗号。只需更改渲染线以渲染csv字符串:

render :plain => csv_string_variable