-->

Creating multiple csv-files and download all in on

2019-03-29 07:31发布

问题:

I am looking for a way to create multiple csv files and download them as one zip archive within one request in my rails application.

To build the archive I use rubyzip gem - to download it just the rails built-in function send_data. The problem I have is that rubyzip's add-function requires a pathname to load files from. But there is no path as my csv files are created within the same request.

Some Code:

# controller action to download zip
def download_zip
  zip = @company.download_all
  send_data zip, filename: "abc.zip", type: 'application/zip'
end

# method to create zip
def download_all
  Zip::File.open('def.zip', Zip::File::CREATE) do |zipfile|
    self.users.each do |user|
      #some magic to combine zipfile.add() and user.to_csv
    end
  end
end

# method to create csv
def to_csv
  CSV.generate do |csv|
    #build awesome csv
  end
end

Is there a way to save my csv files temporarely at some directory, that I can pass a pathname to zipfile.add()?

Nice weekend everybody and happy coding!

回答1:

You could either write your CSV output into a temporary file and call zipfile.add() on that, but there is a cleaner solution:

zipfile.get_output_stream("#{user.name}.csv") { |f| f.puts(user.to_csv) }

See http://rdoc.info/github/rubyzip/rubyzip/master/Zip/File#get_output_stream-instance_method for more details on get_output_stream - you can also pass additional parameters to specify attributes for the file to be created.



回答2:

get_output_stream doesn't work for me. However, the updated method Zip::OutputStream.write_buffer helps

https://gist.github.com/aquajach/7fde54aa9bc1ac03740feb154e53eb7d

The example adds password protection to the file as well.