UTF-8 Encoding name in downloaded file

65,437

Solution 1

I got it solved as the following.

fileName = dateString+"_マイページ情報.xls"; 
fileName = URLEncoder.encode(fileName,"UTF-8"); 
try {
        response.setContentType("application/ms-excel; charset=UTF-8");
        response.setCharacterEncoding("UTF-8");
        if(browserType.equals("IE")||browserType.equals("Chrome"))
            response.setHeader("Content-Disposition","attachment; filename="+fileName);
        if(browserType.endsWith("Firefox"))
            response.setHeader("Content-Disposition","attachment; filename*=UTF-8''"+fileName);
    } catch (Exception e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }

Solution 2

Use method setCharacterEncoding:

Sets the character encoding (MIME charset) of the response being sent to the client, for example, to UTF-8. If the character encoding has already been set by setContentType(java.lang.String) or setLocale(java.util.Locale), this method overrides it. Calling setContentType(java.lang.String) with the String of text/html and calling this method with the String of UTF-8 is equivalent with calling setContentType with the String of text/html; charset=UTF-8.

This method can be called repeatedly to change the character encoding. This method has no effect if it is called after getWriter has been called or after the response has been committed.

Modify your code with following:

response.setContentType("application/ms-excel; charset=UTF-8");
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-Disposition","attachment; filename="+URLEncoder.encode(fileName, "UTF-8"));

Solution 3

In the URLEncoder call, pass the second optional argument "UTF-8". See http://docs.oracle.com/javase/1.4.2/docs/api/java/net/URLEncoder.html#encode(java.lang.String,%20java.lang.String)

Solution 4

Here's what I did, and it works across ALL browsers that I tried (Chrome, Firefox and Safari). Also, I didn't have to write any browser-specific code.

According to this link: http://blogs.msdn.com/b/ieinternals/archive/2010/06/07/content-disposition-attachment-and-international-unicode-characters.aspx

all browsers will attempt to derive the filename from the path component of the URL

So, if the browser requests a URL with the filename at the end, it will name the file correctly. This seems to be true for all browsers.

In my personal case, the client doesn't know the filename that it wants to download. Our system does a GET for a file based on an ID. For example:

/api/file/download/<file_id>

So, what I did is to have that API look up the filename (we store it in the db, by file_id), URL-encode it, and redirect to a 2nd API that includes the filename. For example:

/api/file/download/<file_id>/<url-encoded filename>

Then, the 2nd API will use the file_id to find and stream back the contents of the file, and the browser will use the filename part to name the downloaded file.

NOTE: The 2nd API ignores the filename (doesn't need it). It also sets the Content-Disposition header to "attachment;" only (DO NOT set the filename. Let the browser get it from the URL.)

Solution 5

below works fine.

String fileName = URLEncoder.encode(fileName, "UTF-8");
response.setHeader("Content-Disposition","attachment; filename="+fileName );
Share:
65,437
zawhtut
Author by

zawhtut

Updated on December 11, 2020

Comments

  • zawhtut
    zawhtut over 3 years

    I'm trying to let the user download the excel file with japanese name. It seems that it works IE 8 only and other IE and firefox, it is not working. Kindly suggest me how to hadndle this.

    String fileName = dateString+"_マイページ情報.xls";
    byte[] data = writer.getData();
    response.setContentType("application/ms-excel");
    response.setContentLength(data.length);
    response.setHeader("Expires:", "0"); // eliminates browser caching
    response.setHeader("Content-Disposition","attachment; filename="+URLEncoder.encode(fileName));
    
  • Mahmoud Saleh
    Mahmoud Saleh about 9 years
    @zawhtut, what code do you use to get the browser type ?
  • zawhtut
    zawhtut about 9 years
    request.getHeader("User-Agent"); I think. Its been a long time I posted this answer and now can't recall much.
  • rakeeee
    rakeeee almost 9 years
    This blog post is very helpful while solving this kind of issues blogs.msdn.com/b/ieinternals/archive/2010/06/07/… and to know the browser details fromdev.com/2009/06/dealing-with-different-client-browsers.h‌​tml
  • Amir Amiri
    Amir Amiri about 6 years
    One of the most frequent reasons for this problem is white spaces between filename and file type specially in IE.
  • yngwietiger
    yngwietiger over 5 years
    @rakeeee Thanks for the link. Based on that, I came up with a different solution, using a redirect. The best part is that it doesn't require any browser-specific code. See my answer below.
  • brady
    brady over 5 years
    Sounds like you're in good shape, but as a note for other readers, be super careful about including user input (like the URL-encoded filename here) in file paths that you use on the server. This opens the door to path-traversal attacks. Instead, use an ID for files, and store the actual file name in a database; alternatively, establish a safe pattern for file names, and validate user input against that pattern.
  • yngwietiger
    yngwietiger over 5 years
    This worked fine on Chrome. But did not work for me on Safari and Firefox. Both named the file according to the their URL-encoded "filename" attribute.
  • Ankur Lathi
    Ankur Lathi over 5 years
    @yngwietiger: try using this for firefox- response.setHeader("Content-Disposition","attachment; filename*=UTF-8''"+fileName);
  • jack_07
    jack_07 over 4 years
    Given link is dead, instead use docs.oracle.com/javase/7/docs/api/java/net/…
  • Neil Bryson
    Neil Bryson about 4 years
    This is actually what Google Drive does, except instead of browser checking they just include both parameters i.e. it'd be something like "Content-Disposition": "attachment; filename="fileName"; filename*=UTF-8''"+fileName);
  • fatih yavuz
    fatih yavuz over 2 years
    URLEncoder.encode(fileName,"UTF-8"); fixed my issue.I had file name character problem and i tried all change encoding stufs but just have solved the code my problem.