In my rails app, I can download data as csv file.
This is my current code
response_to do |format|
format.csv {send_data #MY_DATA#}
end
Instead of this code, I want to save the csv file on server.
How can I generate csv file and save the file on the server
Thanks
You can use this to generate a CSV on server.
CSV.open("#{Rails.root}/public/file.csv", "wb") do |csv|
csv << ["row", "of", "CSV", "data"]
csv << ["another", "row"]
# ...
end
Related
How can we csv file compress in .gz format and save in rails.root public folder?
def compress_file(file_name)
zipped = "#{file_name}.gz"
Zlib::GzipWriter.open(zipped) do |gz|
gz.write IO.binread(file_name)
end
end
I'm currently working on a Rails 5.2 application using the combine pdf gem. I'm trying to merge two PDF files but somehow I'm unable to load files from the public directory.
In the controller I have the following method:
def pdf_download
pdf = CombinePDF.new
pdf << CombinePDF.load("#{Rails.root}/public/pdfs/1.pdf")
pdf << CombinePDF.load("#{Rails.root}/public/pdfs/1.pdf")
pdf.save "combined.pdf"
send_data combined_file.to_pdf, filename: "combined.pdf", type: "application/pdf"
end
I have tried many posts on StackOverflow without success such as using Rails.root. But I still get the same error:
Errno::ENOENT (No such file or directory # rb_sysopen - app/public/pdfs/1.pdf):
Is there any additional configuration I have to do to load files from public? and if these PDF shouldn't be in public where should I store them?
This fixed it for me:
def pdf_download
pdf = CombinePDF.new
pdf << CombinePDF.load(Rails.root.join("public", "pdfs/1.pdf").to_s)
pdf << CombinePDF.load(Rails.root.join("public", "pdfs/2.pdf").to_s)
# pdf.save "combined.pdf"
send_data pdf.to_pdf, filename: "combined.pdf", type: "application/pdf"
end
This fixed it for me:
pdf << CombinePDF.load("./public/pdfs/1.pdf")
I have a rake task that looks like this
require 'open-uri'
require 'csv'
namespace :Table do
task reload: :environment do
ActiveRecord::Base.connection.execute("TRUNCATE Table RESTART IDENTITY")
csv_text = open('URL')
csv = CSV.parse(csv_text, :headers=>true)
csv.each do |row|
Table.create(table columns)
end
end
end
Now i can either have the file come back as gzip or zip. It has to be compressed however the csv is the only file inside the zip file.
Any ideas how i can make this open the csv inside the zip file?
Thanks for the help
Sam
Ruby core includes Zlib support. If you've got a URL pointing to a gzipped file, you can use Zlib::GzipReader to inflate the Tempfile returned by open.
gzipped = open('URL')
csv_text = Zlib::GzipReader.new(gzipped).read
csv = CSV.parse(csv_text, :headers=>true)
I would use the rubyzip gem, read the file down to a temp file unzip it, pull the file you want and open it normally as a local file for the CSV.
require 'open-uri'
require 'csv'
require 'zip'
namespace :Table do
task reload: :environment do
ActiveRecord::Base.connection.execute("TRUNCATE Table RESTART IDENTITY")
t=Tempfile.new("foo.zip")
url = open("url")
t.binmode
t.write stringIo.read
t.close
zip_file = Zip::File.open(t.path)
entry = zip_file.glob('*.csv').first
csv_text = entry.get_input_stream.read
csv = CSV.parse(csv_text, :headers=>true)
csv.each do |row|
Table.create(table columns)
end
end
end
Rake aborted!
cannot open entry for reading while its open for writing - ddh8484000adshdjas.csv
I am getting above error, when I am running my task. I try closing the csv file with close(), but nothing working for me. Any help on this.
Below is my code
CSV.open("#{rootDir}/#{filename}.csv", "w") do |csv|
data.each do | array |
csv << array
end
csv.close()
end
zip_file_path = "filename.zip"
Zip::ZipFile.open(zip_file_path, Zip::ZipFile::CREATE) { |zipfile|
Dir.glob("#{rootDir}/*.csv").each do |file|
zipfile.get_output_stream(file.split("/")[8]);
file.close()
end
}
I've been knocking my head around with Heroku, while trying to download a zip file with all my receipt files data.
The files are stored on amazon s3 and it all works fine on my development machine..
I thought it had to do with Tempfile, and abandoned that previous solution, since heroku has some strict policies with their filesystem, so i used the tmp folder, but the problem doesn't seem to be there. I already tried to load directly from s3 (using openUri) to the zip file, but it doesn't seem to work either on Heroku.
What might be wrong with my code for Heroku not loading the files to the zip?
Here is my model method :
def zip_receipts(search_hash=nil)
require 'zip/zip'
require 'zip/zipfilesystem'
t=File.open("#{Rails.root}/tmp/#{Digest::MD5.hexdigest(rand(12).to_s)}_#{Process.pid}",'w')
# t = Tempfile.new(Digest::MD5.hexdigest(rand(12).to_s))
# Give the path of the temp file to the zip outputstream, it won't try to open it as an archive.
Zip::ZipOutputStream.open(t.path) do |zos|
logger.debug("search hash Zip: #{search_hash.inspect}")
self.feed(search_hash).each do |receipt|
begin
require 'open-uri'
require 'tempfile'
#configures filename
filen = File.basename(receipt.receipt_file_file_name)
ext= File.extname(filen)
filen_noext = File.basename(receipt.receipt_file_file_name, '.*')
filen=filen_noext+SecureRandom.hex(10)+ext
logger.info("Info Zip - Filename: #{filen}")
# Create a new entry on the zip file
zos.put_next_entry(filen)
# logger.info("Info Zip - Added entry: #{zos.inspect}")
# Add the contents of the file, reading directly from amazon
tfilepath= "#{Rails.root}/tmp/#{File.basename(filen,ext)}_#{Process.pid}"
open(tfilepath,"wb") do |file|
file << open(receipt.authenticated_url(:original),:ssl_verify_mode => OpenSSL::SSL::VERIFY_NONE).read
end
zos.print IO.binread tfilepath
# logger.info("Info Zip - Extracted from amazon: #{zos.inspect}")
rescue Exception => e
logger.info("exception #{e}")
end # closes the exception begin
end #closes receipts cycle
end #closes zip file stream cycle
# The temp file will be deleted some time...
t.close
#returns the path for send file controller to act
t.path
end
My controller:
def download_all
#user = User.find_by_id(params[:user_id])
filepath = #user.zip_receipts
# Send it using the right mime type, with a download window and some nice file name.
send_file(filepath,type: 'application/zip', disposition: 'attachment',filename:"MyReceipts.zip")
end
And I write also my view and routes, so that it might serve anyone else trying to implement a download all feature
routes.rb
resources :users do
post 'download_all'
end
my view
<%= link_to "Download receipts", user_download_all_path(user_id:user.id), method: :post %>
The problem seemed to be with the search hash, and the sql query, and not the code itself. For some reason, the receipts get listed, but aren't downloaded. So it is an all different issue
In the end i have this code for the model
def zip_receipts(search_hash=nil)
require 'zip/zip'
require 'zip/zipfilesystem'
t=File.open("#{Rails.root}/tmp/MyReceipts.zip_#{Process.pid}","w")
# t = Tempfile.new(Digest::MD5.hexdigest(rand(12).to_s))
#"#{Rails.root}/tmp/RecibosOnline#{SecureRandom.hex(10)}.zip"
puts "Zip- Receipts About to enter"
# Give the path of the temp file to the zip outputstream, it won't try to open it as an archive.
Zip::ZipOutputStream.open(t.path) do |zos|
self.feed(search_hash).each do |receipt|
begin
require 'open-uri'
require 'tempfile'
filen = File.basename(receipt.receipt_file_file_name)
ext= File.extname(filen)
filen_noext = File.basename(receipt.receipt_file_file_name, '.*')
filen=filen_noext+SecureRandom.hex(10)+ext
# puts "Info Zip - Filename: #{filen}"
# Create a new entry on the zip file
zos.put_next_entry(filen)
zos.print open(receipt.authenticated_url(:original),:ssl_verify_mode => OpenSSL::SSL::VERIFY_NONE).read
rescue Exception => e
puts "exception #{e}"
end # closes the exception begin
end #closes receipts cycle
end #closes zip file stream cycle
# The temp file will be deleted some time...
t.close
#returns the path for send file controller to act
t.path
end