Rails 4, replacing “\\n” with “ ” for use in X

2019-07-03 04:20发布

问题:

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","&#10;").html_safe %>
    </Data></Cell>
  </Row>
<% end %> 

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

回答1:

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