Reputation: 25
I have the following table:
<tr>
<th colspan = "18"> student info</th>
<th colspan="10">class info</th>
</tr>
<tr>
<th colspan="1">First Name</th>
<th colspan="1">Middle Name</th>
<th colspan="1">Last Name</th>
....
</tr>
<tr>
<td colspan="1"><%= link_to student.first_name,:controller => 'acme_modificationss' , :action=>'profile', :id => student.id %></td>
<td colspan="1"><%= student.middle_name %></td>
<td colspan="1"><%= student.last_name %></td>
<td colspan="1"><%= student.first_name %></td>
<td colspan="1"><%=m_first_name%></td>
.....
I need to export the same table to .xls file. So I added a new action to the controller:
def document_xls
....
respond_to do |format|
format.xls
end
end
Then I added document_xls view:
<?xml version="1.0"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40">
<Worksheet ss:Name="Sheet1">
<Table>
<Row>
<Cell><Data ss:Type="String">Student Info</Data></Cell>
<Cell><Data ss:Type="String">Class info</Data></Cell>
....
</Row>
<Row>
<Cell><Data ss:Type="String">First Name</Data></Cell>
<Cell><Data ss:Type="String">Middle Name</Data></Cell>
<Cell><Data ss:Type="String">Last Name</Data></Cell>
...
This generates a file with type file. But I want to generate this file as .xls, so I tried to add this to my controller action:
format.xls{ send_data @students, :type => 'application/vnd.ms-excel', :filename => 'students.xls' }
But I got this error:
NoMethodError (undefined method `bytesize' for #)
Also, I need the excel table headers to be merged in more than one cell, is there a way to do this?
Upvotes: 1
Views: 3391
Reputation: 1310
One easier way to fix this is send content as HTML to excel. Excel is able to parse it and convert by his own, you just need to send the right headers. first, have your table in a partial view, then, in your controller create a method like this:
def export
headers['Content-Type'] = "application/vnd.ms-excel"
headers['Content-Disposition'] = 'attachment; filename="report.xls"'
headers['Cache-Control'] = ''
@data = self.send params[:type]
render layout: false
end
3 first lines export the excel file, so, the next line send the data receiving like type method the name of the method that retrieve your data to html and excel view, and render: false show you an empty layout jus loading your data.
in your routes something like
get 'excel/stats/:type', to: 'stats#export', as: 'excel_stat'
In this example we have the stats controller with many different types of stats, and in a view 'export' in your controller, you can render the partial view like this
export.html.haml :
= render params[:type]
Upvotes: 4