7

Estoy usando Rails 3.1.0.rc8 y Chromium 15.0.874.102.en rieles, no se puede sobrescribir el nombre de archivo de disposición de contenido

Quiero establecer el nombre de archivo de una descarga CSV. Estoy siguiendo este SO solution, pero no puedo modificar el filename del encabezado Content-Disposition.

Aquí está mi código:

module ActionController 
    module CSVHelper 

    def render_csv options={} 
     if request.env['HTTP_USER_AGENT'] =~ /msie/i 
     headers['Pragma'] = "public" 
     headers['Content-Type'] = "text/plain" 
     headers['Cache-Control'] = "no-cache, must-revalidate, post-check=0, pre-check=0" 
     headers['Expires'] = "0" 
     else 
     headers['Content-Type'] = "text/csv" 
     end 

     filename = generate_filename options.delete(:basename) 
     headers['Content-Disposition'] = "attachment; filename=#{filename}" 
    end 

    def generate_filename basename=nil, suffix="csv" 
     filename = basename || params[:action] 
     filename << ".#{suffix}" 
     filename 
    end 

    end 
end  

Y en mi controlador:

respond_to do |format| 
    format.html 
    format.csv do 
    render_csv(:basename => "my_filename") 
    Rails.logger.debug "HEADERS: #{headers.to_s}" 
    end 
end 

En mi registro:

[2011-11-28 12:25:49.611] DEBUG - HEADERS: {"Content-Type"=>"text/csv", "Content-Disposition"=>"attachment; filename=my_filename.csv"} 

En cromo herramienta inspector de la red, veo lo siguiente en mis encabezados de respuesta:

Content-Type: text/plain 
Content-Disposition: attachment; filename=index.csv 

Si cambio el Content-Type a algo así como foo/bar, veo el cambio en mi herramienta de inspector de red. No importa a qué establezca el filename, sigue siendo index.csv.

Gracias, Max

+0

¿Tiene la vista correctamente configurada? – baol

+0

la vista se visualiza como se espera, si eso es lo que quiere decir; el contenido del archivo descargado parece que quiero – maxenglander

Respuesta

11

De acuerdo con la Content-Disposition section of the appendices to the HTTP/1.1 specification el nombre del archivo debe ser una cadena citado:

filename-parm = "filename" "=" quoted-string 
    ... 

Un ejemplo es

Content-Disposition: attachment; filename="fname.ext" 

Así que es probable que tenga que hacer el siguiente cambio (nota las comillas):

headers['Content-Disposition'] = "attachment; filename=\"#{filename}\"" 
+0

Tenga en cuenta que si el nombre del archivo en sí puede contener comillas, tendrá que escapar de ellas - 'filename.gsub (/" /, '\\ "')' – gmcnaughton

2

descubrí que mi equipo está usando la gema csv_builder, lo que le permite ajustar el nombre del archivo descargado mediante el establecimiento de @filename en el controlador. Aún otorgaré la respuesta correcta a cualquiera que pueda explicar por qué recibí el comportamiento descrito en OP.

1

No veo dónde está realmente enviando/renderizando la salida ... ¿Está eso en un archivo .csv.erb o algo así? ¿O usando csv_builder como otra respuesta? Ese podría ser el truco.

Se me ocurrió lo mismo con una salida .xlsx. Una vez que tenía el archivo en el disco, que podría hacer esto:

def example 
    respond_to do |format| 
    format.xlsx do 
     path = some_method_generating_xlsx_file 
     headers['Content-Disposition'] = "attachment; filename=test.xlsx" 
     render :text => File.binread(path), :content_type => XLSX_MIME_TYPE 
    end 
    end 
end 

en mi controlador, y ha funcionado muy bien. Tal vez los encabezados estaban siendo golpeados por la representación de la plantilla.

0

Yo personalmente no uso render para este tipo de contenido - Prefiero usar send_data. Aquí hay un ejemplo:

send_data data, :type => 'text/csv', :disposition => 'attachment; filename=my_file_name.csv' 
Cuestiones relacionadas