Home » excel » Rails 4, replacing "\n" with " " for use in XML spreadsheets in excel

Rails 4, replacing "\n" with " " for use in XML spreadsheets in excel

Posted by: admin April 23, 2020 Leave a comment


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| %>
    <Cell ss:StyleID="borders"><Data ss:Type='String'>
").html_safe %>
<% end %> 

but is there a better way to do this that wont “html_safe” the entire string?

How to&Answers:

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">
   <Column ss:Width="30" />
   <Column ss:Width="200" />
   <Column ss:Width="300" />
   <Column ss:Width="400" />
        <Cell><Data ss:Type="String">C1</Data></Cell>
        <Cell><Data ss:Type="String">C2</Data></Cell>
        <Cell><Data ss:Type="String">C3</Data></Cell>
   <% @yourmodels.each do |ds| %>
    <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>
   <% end %>

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

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 )