【问题标题】:How to generate a CSV file in a background task?如何在后台任务中生成 CSV 文件?
【发布时间】:2012-01-09 12:17:07
【问题描述】:

我们允许用户以 CSV 格式下载他们的所有数据,但我们发现对于很多用户(拥有大量数据)我们确实需要在后台生成 CSV 文件然后提供给他们稍后提供下载链接。

我知道如何在视图中动态生成 CSV 文件,但我并不完全清楚在后台任务中生成它的最佳方式。

我目前正在使用csv_builder 在视图中生成 CSV 文件...所以能够仍然使用它并以某种方式将其直接输出到我可以上传到的 CSV 文件中会很棒S3 使用回形针......但这可能太牵强了。

【问题讨论】:

  • backgroundrb 应该可以帮到你。他们已经描述了如何在后台执行某些任务的步骤。您可以根据需要自动运行它(在您在视图中使用它之前,您可以生成它)使用 cron。
  • 我知道如何运行后台任务。我在问如何使用后台任务生成 CSV 文件,以及是否可以继续使用 csv_builder

标签: ruby-on-rails ruby-on-rails-3 csv background-process


【解决方案1】:

我遇到了类似的问题,但使用了内置的 rails CSV 库而不是 csv_builder(我对此一无所知)。

在我的模型中,我有一种方法可以生成 csv 并在 s3 上另存为 paerclip 附件:

def csv_export
  @entries = self.entries    
  @filename = "naming my file"    
  CSV.open("#{Rails.root.to_s}/tmp/#{@filename}", "wb") do |csv| #creates a tempfile csv
    csv << ["Date & Time", "Name", "Email"] #creates the header
    @entries.each do |e|            
      csv << [e.created_at, e.name, e.email] #create new line for each item in collection
    end
end

self.update_attribute(:csv_report, File.open("#{Rails.root.to_s}/tmp/#{@filename}"))
  #saves tempfile as paperclip attachment
end

我在 rake 任务中调用此方法,该任务会卸载到延迟的作业工作者。

所以在 rake 任务中:Object.delay.csv_export

【讨论】:

    【解决方案2】:

    您可以创建一个数据库表,您可以在后台创建文件后将其保存在其中。我可以向您展示 Rails 迁移。

      create_table "csv_table", force: :cascade do |t|
        t.binary "csv_file"
        t.string "file_name"
      end
    

    创建此文件后,您可以在此处保存 csv 文件。您可以使用

    将文件保存为二进制文件
    csv_converted_file = Base64.encode64(csv)
    

    这里 csv 是数据。

    现在,如果您想在后台下载 csv。您可以使用这个咖啡脚本下载它。您将发出 ajax 请求以获取您刚刚保存在 csv 表中的 csv 数据。

       $.ajax
        type: 'GET'
        dataType: "text"
        url: url
        success: (data) ->
          blob = new Blob([data], { type: "text/csv" })
          file_name_url = new URL(window.location.href)
          file_name = file_name_url.searchParams.get("file_name");
          url = window.URL.createObjectURL(blob)
          a = document.createElement('a')
          a.setAttribute('hidden', '')
          a.setAttribute('href', url)
          a.setAttribute('download', file_name)
          document.body.appendChild(a)
          a.click()
          document.body.removeChild(a)
      return
    

    这样,您的 csv 将在所需的页面加载时下载。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-21
      • 2017-03-22
      • 1970-01-01
      • 2018-05-13
      相关资源
      最近更新 更多