【问题标题】:How to download CSV data using ActionController::Live from MongoDB?如何使用 ActionController::Live 从 MongoDB 下载 CSV 数据?
【发布时间】:2017-01-08 23:31:24
【问题描述】:
我在这样的控制器中创建了一个 CSV 下载器
format.csv do
@records = Model.all
headers['Content-Disposition'] = "attachment; filename=\"products.csv\""
headers['Content-Type'] ||= 'text/csv'
end
现在我想创建server sent events 以从中下载 CSV 以进行优化。我知道我可以在 Rails 中使用ActionController::Live 做到这一点,但我没有这方面的经验。
谁能解释一下我该怎么做
- 批量查询记录
- 将记录添加到
stream
- 从浏览器端处理
sse
- 将记录写入 CSV 文件
如果我的任何假设是错误的,请纠正我。帮助我以更好的方式做到这一点。谢谢。
【问题讨论】:
标签:
ruby-on-rails
export-to-csv
server-sent-events
actioncontroller
【解决方案1】:
Mongoid 自动批量查询您的记录(更多信息请通过here)
要将记录添加到 CSV 文件,您应该执行以下操作:
records = MyModel.all
# By default batch_size is 100, but you can modify it using .batch_size(x)
result = CSV.generate do |csv|
csv << ["attribute1", "attribute2", ...]
records.each do |r|
csv << [r.attribute1, r.attribute2, ...]
end
end
send_data result, filename: 'MyCsv.csv'
记住send_data是一个ActionController方法!
【解决方案2】:
我认为您不需要 SSE 来生成 CSV。只需 include ActionController::Live 进入控制器以使用 response.stream.write 迭代您的集合:
include ActionController::Live
...
def some_action
format.csv do
# Needed for streaming to workaround Rack 2.2 bug
response.headers['Last-Modified'] = Time.now.httpdate
headers['Content-Disposition'] = "attachment; filename=\"products.csv\""
headers['Content-Type'] ||= 'text/csv'
[1,2,3,4].each do |i| # --> change it to iterate your DB records
response.stream.write ['SOME', 'thing', "interesting #{i}", "#{Time.zone.now}"].to_csv
sleep 1 # some fake delay to see chunking
end
ensure
response.stream.close
end
end
尝试使用 curl 或类似方法逐行查看输出:
$ curl -i http://localhost:3000/test.csv