所以这可能是一个简单的问题,但我以前从未这样做过。
我有一个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
})
}
答案 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