Rails - Error when encoding CSV in production - ruby-on-rails

Im using Active Admin with Rails and I'm exporting all my data in a csv file. It works really well in development, but in production i get this error :
Encoding::UndefinedConversionError (U+00E7 to WINDOWS-1251 in conversion from UTF-8 to WINDOWS-1251)
When I send_data :
date = DateTime.now
csv_title = "O535#{date.year}#{date.strftime('%m')}#{date.strftime('%d')}#{date.strftime('%H')}#{date.strftime('%M')}#{date.strftime('%S')}"
send_data csv.force_encoding('UTF-8'),
:type => 'text/csv; charset=iso-8859-1; header=present',
:disposition => "attachment; filename=#{csv_title}.csv"
Has anyone ever met that error ? I tried using csv.encore / csv.force_encoding and many other solutions but it's still working well in development but always crash in production
Thanks a lot

Related

rails send_data can't handle large file (2G+)

My env:
Mac: 10.12.4
Memory: 16G
ruby: 2.1.4
rails: 3.2.22.5
web server: thin 1.7.0
When the file size is under 2G, everything goes well.
class ItemListsController < ApplicationController
...
send_data IO.read(zip_path), :type => 'application/zip',
:disposition => 'attachment',
:filename => file_name
However, when file size is larger than 2G, exception raised:
Errno::EINVAL: Invalid argument # io_fread
I tried to use rubyzip to output stream instead:
compressed_filestream = Zip::OutputStream.write_buffer do |zos|
files.each do |file|
zos.put_next_entry file[1]
zos.write File.open(file[0], 'r').read
end
end
compressed_filestream.rewind
send_data compressed_filestream.read, :type => 'application/zip',
:disposition => 'attachment',
:filename => file_name
Exception raised with further detail:
Unexpected error while processing request: integer 2206004964 too big to convert to `int'
/Users/karl/.rvm/gems/ruby-2.1.4#hcsvlab/gems/eventmachine-1.0.3/lib/em/connection.rb:328:in `send_data'
Seems send_data would read the whole file into memory then send data back.
My original plan is to find some way to provide "buffer" so send_data would read from buffer instead reading the whole file, but can't find such options in API
https://apidock.com/rails/ActionController/DataStreaming/send_data
Any idea would be greatly appreciated.
Thanks.
You might want to use send_file instead. According to the documentation:
Sends the file, by default streaming it 4096 bytes at a time. This way
the whole file doesn’t need to be read into memory at once. This makes
it feasible to send even large files. You can optionally turn off
streaming and send the whole file at once.

Unable to change file encoding to utf-8 using send_data

First of all, allow me to wish you all happy reading this question, happy and productive new year.
Here comes the issue: I am unable to change file charset via Rails 3 send_data
I have some content generated via
xml_data = ''
x = Builder::XmlMarkup.new(:target => xml_data, :indent => 1)
which i fill then with all sort of data.
When I attempt to send this file for download using this command
send_data xml_data.encode('cp1251'),
:type => 'text/xml; charset=utf-8; header=present',
:filename => "data.xml"
it downloads just fine, but for some reason, when in Linux I request file encoding using
> file -bi data.xml
text/plain; charset=iso-8859-1
I need charset of this file to be utf-8. How can I automatically set it through Rails send_data?
Any help regarding this issue will be highly appreciated.
Thank you.
It appears that for the third party system the XML is used, all UTF-8 encoding is just fine.
In result i ended up with
send_data xml_data.encode('utf-8'),
:type => 'text/xml; charset=utf-8; header=present',
:filename => "data.xml"

How to handle csv download prompt through a post request in Rails

I have a servlet (java) returning a csv file. So in my controller I send a post request,
def handleCsvRequest
response = RestClient.post theUrlPathTotheServlet queryParams
end
Now how do I handle the response so that it prompts the user to download this csv file. I know you can do this via a form and hidden Iframe but i'd like to do it through rails. I am looking through fastercsv but i am not finding great examples. Many thanks.
I have tried the following:
i have tried the following
csv_string = RestClient.post url, json, :content_type => :json
csv_file = CSV.generate do |csv|
csv << [csv_string]
end
send_data csv_file, :type => 'text/csv; charset=iso-8859-1; header=present', :disposition => "attachment; filename=report.csv"
but i don't get prompt for a file download? any ideas?
Do have a look at
1> http://fastercsv.rubyforge.org/ - For Documenation
2> http://supriya-surve.blogspot.com/2010/02/using-fastercsv-to-import-data.html - As an e.g.
Use send_file or send_data to send the csv data back to the browser.
A typical example of send_data is something along the lines:
csv_data = CSV.generate do
# block to generate CSV text
end
send_data csv_data, :filename => 'your_data.csv'
A typical example of send_file is
#csv_filename ="#{RAILS_ROOT}/tmp/your_data.csv"
send_file #csv_filename, :filename => "your_data.csv"
This should work in development. If this does not work in production, and you are using an Apache server,
you have to comment out the following line in config/environments/production.rb
config.action_dispatch.x_sendfile_header = "X-Sendfile"
Hope this helps.

rails send_file and send_data sends out zero byte files

I'm trying to send a pdf back to the user but I'm having serious problem getting send_file and send_data to work. I created the pdf file as follows:
tmp = Tempfile.new('filled')
new_tmp_path = PDFPrint.fill_form_using_pdftk(template_path, tmp.path)
send_file (new_tmp_path, :filename => 'filled.pdf')
The browser prompts for a download, but the downloaded filled.pdf file has zero byte.
I have verified that new_tmp_path does contain a valid pdf (good, filled content)
I have tried this:
File.open(new_tmp_path, 'r') do |f|
send_data(f.read, :filename => "filled.pdf")
end
But this also gives me the same download->zero-byte problem, while the file on server (new_tmp_path) has perfect content.
Regards,
Try sending a simple file to see if it works
send_file '/path/to.jpeg', :type => 'image/jpeg', :disposition => 'inline'
Read this thread, I think it has everything you need.

Rails send_data throws "invalid byte sequence in UTF-8"... but why?

I'm using Rails to generate a PDF with the executable wkhtmltopdf and then using send_data to send the result back to the user as a PDF file.
view = ActionView::Base.new(ActionController::Base.view_paths, {})
html = "<h1>A heading</h1>"
pdfdata = `echo '#{html}' | #{RAILS_ROOT}/lib/pdf/wkhtmltopdf-i386 - -`
send_data pdfdata, :filename => 'readthis.pdf', :disposition => 'attachment', :type => "application/pdf"
The PDF is generated properly, but Rails complains ArgumentError (invalid byte sequence in UTF-8) from the send_data method. Changing it to send "foobar" as :type => text/html makes it work, so it's definitely got a problem with pdfdata.
I don't understand. Isn't send_data supposed to send binary data? Of course it's not valid UTF-8. Or am I missing something?
Thanks
Rails assumes UTF-8. Telling it explicitly that it is binary data solves the problem. Thanks for your help.
pdfdata.force_encoding('BINARY')
Did you inspect the variable pdfdata and check whether it is proper or not?

Resources