How to generate an application/excel type download?

For my data aquisition application, I want to implement a download
function, that generates a file in excel 2003 (xml) - Format.

Is it possible to add a new format the show function to produce such a
file and send it to the client?

On 24 Jun 2010, at 13:57, Fritz T. wrote:

For my data aquisition application, I want to implement a download
function, that generates a file in excel 2003 (xml) - Format.

Is it possible to add a new format the show function to produce such a
file and send it to the client?

Add the following to initializers/mimetypes.rb:

Mime::Type.register “application/vnd.ms-excel”, :xls
Then in your show method:

def show
respond_to do |format|
format.html { # render normal show here }
format.xls { # render excel file here }
end
end

Best regards

Peter De Berdt

Thanks for your quick reply.

For a quick test, I entered http://localhost:3000/data/5.xls into the
browser.

The response is: “Template is missing”

The code fragment in show is:

respond_to do |format|
  format.html # show.html.erb
  format.xls  { render :to_excel_2003 => @data }
end

and to_excel_2003 only contains a debugger call, which is never reached.

Two more questions:
How to overcome the “Template is missing” - an .erb-file doesn’t make
sense here.
How to build the link_to to generate a link to the .xls-file?

On 24 Jun 2010, at 15:12, Fritz T. wrote:

 format.html # show.html.erb
 format.xls  { render :to_excel_2003 => @data }

end

and to_excel_2003 only contains a debugger call, which is never
reached.

Two more questions:
How to overcome the “Template is missing” - an .erb-file doesn’t make
sense here.

Use a valid render command. And to send the file:

http://api.rubyonrails.org/classes/ActionController/Streaming.html

How to build the link_to to generate a link to the .xls-file?

Just like you would generate a normal link, but with :format => xls as
an extra parameter.

Best regards

Peter De Berdt

On 24 Jun 2010, at 15:19, Fritz T. wrote:

OK, that’s nonsense. should be:

 format.xls  { render :xls => @data.to_excel_2003 }

This is just as wrong, you just need to serve up data using what’s
available in Rails. Anyway, send_data is the thing you want.

Best regards

Peter De Berdt

Fritz T. wrote:

The code fragment in show is:

respond_to do |format|
  format.html # show.html.erb
  format.xls  { render :to_excel_2003 => @data }
end

OK, that’s nonsense. should be:

  format.xls  { render :xls => @data.to_excel_2003 }

Peter De Berdt wrote:

This is just as wrong, you just need to serve up data using what’s
available in Rails. Anyway, send_data is the thing you want.

There is an example in responde_to:

def index
@people = Person.find(:all)

respond_to do |format|
  format.html
  format.xml { render :xml => @people.to_xml }
end

end

For me, to_xml looks like method of the class of @people. Right?

My data is in @data, which needs to be rendered into the excel xml
format using a template consisting of xml fragments and variables, that
will be expanded using the content of @data.

send_data will be the very last step.

The point is, that the excel file doesn’t exist and should be created on
the fly.

Peter De Berdt wrote:

On 24 Jun 2010, at 16:10, Fritz T. wrote:

 format.html
 format.xml { render :xml => @people.to_xml }

end
end

For me, to_xml looks like method of the class of @people. Right?

Well, it’s actually a method from Enumerable or Array which renders it
to an XML format according to Rails specifications. That doesn’t mean
Excel will be able to read it (and it won’t, I can tell you right now).

It’s really a member function of

class data < ActiveRecord::Base
def to_excel_2003
debugger
end
end

and gets called from format.xls { render :xls => @data.to_excel_2003 }

My problem now is to find a trick to redirect back to show after
downloading the file.

As a result, the client should ge a download dialog to store the file.

You have three options:

  • Make a template in excel with some variables (I would recommend
    using something like liquid instead of erb) and run them through the
    template parser of your choice
  • Generate an excel file using one of the gems you find when googling
    “ruby excel”, your mileage may vary on those

This is too much efford. I developed the xml-solution for javascript and
it works very well.

To design and format such a sheet, simply use excel or OpenOffice and
export it as excel 2003 format, then take a xml editor like XML Copy
Editor, pretty print it and extract varable blocks to xml fragments and
set variables instead.

This is something like a template and my to_excel_2003 should act as a
template parser. Any idea, how to do this?

  • Generate an excel file using your own code based on the public spec
    available from Mickeysoft

This is even more efford…

On 24 Jun 2010, at 17:19, Fritz T. wrote:

My problem now is to find a trick to redirect back to show after
downloading the file.

As a result, the client should ge a download dialog to store the file.

Instead of render :xls, use send_data with the correct options to
serve the file with disposition attachment (see the docs), this will
bring up the dialog box right away and you never have to redirect to
show, since a file download doesn’t do a page refresh.

You’ll need to implement the to_excel_2003 method to return a string
at the end that will constitute the contents of the file. It’s up to
you to figure out which method of actually generating the string fits
your project best and implement it.

Best regards

Peter De Berdt

Similar to what Peter is pointing out, I use a similar construct to
generate and send a pdf to the user off a link on the ‘show’ form…

def pdf
if @project = Project.find(params[:id])
filename =
@project.name+"-"+Time.now.strftime("%Y-%m-%d-%H%M")+".pdf"
filename = filename.gsub(" “,”_")
send_data @project.as_pdf(params[:detail_level]), :filename =>
filename, :type => “application/pdf”
end
end

Where I use @project.as_pdf, you might have @data.to_excel_2003 to
create your file, and you’ll need a different :type on your send_data
call.

On 24 Jun 2010, at 16:10, Fritz T. wrote:

 format.html
 format.xml { render :xml => @people.to_xml }

end
end

For me, to_xml looks like method of the class of @people. Right?

Well, it’s actually a method from Enumerable or Array which renders it
to an XML format according to Rails specifications. That doesn’t mean
Excel will be able to read it (and it won’t, I can tell you right now).

My data is in @data, which needs to be rendered into the excel xml
format using a template consisting of xml fragments and variables,
that
will be expanded using the content of @data.

send_data will be the very last step.

The point is, that the excel file doesn’t exist and should be
created on
the fly.

Uhu, and your point is?

You have three options:

  • Make a template in excel with some variables (I would recommend
    using something like liquid instead of erb) and run them through the
    template parser of your choice
  • Generate an excel file using one of the gems you find when googling
    “ruby excel”, your mileage may vary on those
  • Generate an excel file using your own code based on the public spec
    available from Mickeysoft

Best regards

Peter De Berdt

i have installed
ruby 1.8.6 window version,
rails 2.0.2

everything runs fine except SCAFFOLD
when i run
ruby script/generate scaffold modelname controllername actions
e,g. C:depot>ruby script/generate scaffold Album albums
it gives following error
“WRONG NUMBER OF ARGUMENTS (1 FOR 2)”
i tried with many dummyprojects and tutorial,
BUT if i run
ruby script/generate scaffold modelname
e.g ruby script/generate scaffold Album
IT’S RUN FINE
SEE THE FOLLOWING

C:\InstantRails-2.0-win_2\rails_apps\music_library_development>ruby
script/generate scaffold Album albums
exists app/models/
exists app/controllers/
exists app/helpers/
create app/views/products
exists app/views/layouts/
exists test/functional/
exists test/unit/
create app/views/products/index.html.erb
wrong number of arguments (1 for 2)

C:\InstantRails-2.0-win_2\rails_apps\music_library_development>ruby
script/generate scaffold Album
exists app/models/
exists app/controllers/
exists app/helpers/
exists app/views/albums
exists app/views/layouts/
exists test/functional/
exists test/unit/
create app/views/products/index.html.erb
create app/views/products/show.html.erb
create app/views/products/new.html.erb
create app/views/products/edit.html.erb
create app/views/layouts/albums.html.erb
create public/stylesheets/scaffold.css
dependency model
exists app/models/
exists test/unit/
exists test/fixtures/
create app/models/album.rb
create test/unit/album_test.rb
create test/fixtures/albums.yml
create db/migrate
create db/migrate/20080628070012_create_albums.rb
create app/controllers/albums_controller.rb
create test/functional/albums_controller_test.rb
create app/helpers/albums_helper.rb
route map.resources :albums

C:\InstantRails-2.0-win_2\rails_apps\music_library_development>

BUT RESULTS ARE A BIT DIFFERENT ,
i am looking for Modelname “album”, Controllername " albums "
and Actions “show.rhtml, new.rhml, edit.rhtml,_form.rhtml”

BUT RESULTS ARE
Modelname " album" , Controllername " albums",and Actions
“show.html.erb,new.html.erb,edit.html.erb,index.html.erb”

PLZ HELP ME WHAT’S GOING WRONG
Thanks

Pravin M.
[email protected]

Ar Chron wrote:

Similar to what Peter is pointing out, I use a similar construct to
generate and send a pdf to the user off a link on the ‘show’ form…

def pdf
if @project = Project.find(params[:id])
filename =
@project.name+"-"+Time.now.strftime("%Y-%m-%d-%H%M")+".pdf"
filename = filename.gsub(" “,”_")
send_data @project.as_pdf(params[:detail_level]), :filename =>
filename, :type => “application/pdf”
end
end

Where I use @project.as_pdf, you might have @data.to_excel_2003 to
create your file, and you’ll need a different :type on your send_data
call.

Thanks for your reply. I’m about to solve it. Downloading a file works,
now I have to render the xml string.