I'm writing an application that exports certain data into a specifically formatted Excel document. I'm building an XML spreadsheet file using this document (http://msdn.microsoft.com/en-us/library/aa140066(v=office.10).aspx#odc_xmlss_x:pagesetup)
and so far have it all working. BUT to get it working I had to use ".html_safe" in several fields which is dangerous in this instance as some of the fields being exported contain user entered data.
Basically to get a new line inside an excel cell you use " "
instead of the usual \n
I'm currently using this in my erb:
(edited 8/8/2014 for clarity)
<% @tickets.each do |t| %>
<Row>
<Cell ss:StyleID="borders"><Data ss:Type='String'>
<%=t.business_impact.gsub("\n"," ").html_safe %>
</Data></Cell>
</Row>
<% end %>
but is there a better way to do this that wont "html_safe" the entire string?
I strongly recommend you use ERB to generate XML formated Excel document.
First you should create an excel template. You can create an excel document with only 1 row 3 columns, and save it using xml format, then change the file name to xxx.erb.
Change the erb file with your model instance variables. I can give you my sample here:
<Worksheet ss:Name="sheet1">
<Table>
<Column ss:Width="30" />
<Column ss:Width="200" />
<Column ss:Width="300" />
<Column ss:Width="400" />
<Row>
<Cell><Data ss:Type="String">C1</Data></Cell>
<Cell><Data ss:Type="String">C2</Data></Cell>
<Cell><Data ss:Type="String">C3</Data></Cell>
</Row>
<% @yourmodels.each do |ds| %>
<Row>
<Cell><Data ss:Type="String"><![CDATA[<%safe_concat ds.c1 %>]]></Data></Cell>
<Cell><Data ss:Type="String"><![CDATA[<%safe_concat ds.c2 %>]]></Data></Cell>
<Cell><Data ss:Type="String"><![CDATA[<%safe_concat ds.c3 %>]]></Data></Cell>
</Row>
<% end %>
</Table>
</Worksheet>
UPDATE:
Reference to another question of excel-xml-line-breaks-within-cell-from-php-dom,
and article safebuffers and rails 3.0.
Update code <Cell><Data ss:Type="String"><%= ds.c1 %></Data></Cell>
to <Cell><Data ss:Type="String"><![CDATA[<%safe_concat ds.c1 %>]]></Data></Cell>
.
These codes are just part of my sample, just like other html templates. Don't worry about new line in data, don't need html_save, it works well.
And in your controller, you should add responed to xls or xml format.
respond_to do |format|
format.html # index.html.erb
format.xls # index.xls.erb
format.xml # index.xml.erb
end
Additionally if you want to create a file locally instead of return a file from browser. You can use ERB class method like below:
@yourmodels = ...
f = File.new( 'youmodels_out.xml', "w")
f_template = File.open( 'template_file_name.erb' )
erb = ERB.new( f_template.read )
f.print erb.result( binding )
f_template.close
f.close