File Download from browser with given filename

phoenix
troubleshooting

#1

Hi, all.

I’m creating some APIs, and one of that is to download a excel file which is created by Phoenix with the elixlsx library. I’ve succeeded to create the Excel File.

However, after that, when I response that file to front-end via Browser,
I can not get the file with a specified file name which is given by my code.
I can get the file with like “clients-1552475772585.xls”, because the controller name is ClientsController ( filename is clients_controller.ex).

How can I get ( download ) the file with a filename I expected ?

When I respond, I tried send_resp, send_file and send_download, but I always get the file with filename is “clients-1552475772585.xls”.

My Code is following.

Thanks.

filename I expect.

  excel_file_name = "sample.xlsx"

create excel data on memory

  binary_data = client_excel_report_generator(clients, param)
  |> Elixlsx.write_to_memory(excel_file_name)

try to send to front-end.

  conn
  |> put_resp_content_type("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
  |> put_resp_header("content-disposition", "attachment; filename=\"#{fname}\"")
  |> send_resp(200, excel_file_name)

#2

You are setting Content-Disposition header file name to fname. That’s the file name that browser will use.
Also quoting https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition below. You need to make sure that fname doesn’t contain any invalid characters. Like path separators and it should be encoded. More info here https://stackoverflow.com/questions/93551/how-to-encode-the-filename-parameter-of-content-disposition-header-in-http

filename

Is followed by a string containing the original name of the file transmitted. The filename is always optional and must not be used blindly by the application: path information should be stripped, and conversion to the server file system rules should be done. This parameter provides mostly indicative information. When used in combination with Content-Disposition: attachment , it is used as the default filename for an eventual “Save As” dialog presented to the user.

Edit: Like to add that if you are in total control (it’s not something that user can effect) of Content-Disposition filename then you don’t need to escape or do any of that.


#3

Take a look at Phoenix.Controller.send_download if you‘re using phoenix.


#4

Also, you’re sending the file name in the body, not the data–in fact, you never do anything with the data…


#6

[Re-Edit]

|> put_resp_header(“content-disposition”, “attachment; filename=”#{excel_file_name}"")