Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating multiple csv-files and download all in one zip-archive using rails

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!

like image 420
floriansuchan Avatar asked Sep 13 '14 15:09

floriansuchan


People also ask

How do I read multiple CSV files in a folder?

You can do this by reading each CSV file into DataFrame and appending or concatenating the DataFrames to create a single DataFrame with data from all files. Here, I will use read_csv() to read CSV files and concat() function to concatenate DataFrams together to create one big DataFrame.


2 Answers

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.

like image 191
Jonas Witt Avatar answered Sep 20 '22 16:09

Jonas Witt


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.

like image 22
aquajach Avatar answered Sep 21 '22 16:09

aquajach