ユーザーに日本語の名前のExcelファイルをダウンロードさせようとしています。動作しているようですIE 8のみ、および他のIEおよびfirefox、動作していません。
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));
次のように解決しました。
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();
}
メソッドの使用 setCharacterEncoding :
クライアントに送信される応答の文字エンコード(MIME文字セット)を、たとえばUTF-8に設定します。文字エンコードがsetContentType(Java.lang.String)またはsetLocale(Java.util.Locale)によってすでに設定されている場合、このメソッドはそれをオーバーライドします。 text/htmlの文字列でsetContentType(Java.lang.String)を呼び出し、UTF-8の文字列でこのメソッドを呼び出すことは、text/htmlの文字列でsetContentTypeを呼び出すことと同等です。 charset = UTF-8。
このメソッドを繰り返し呼び出して、文字エンコーディングを変更できます。 getWriterが呼び出された後、または応答がコミットされた後に呼び出された場合、このメソッドは効果がありません。
以下を使用してコードを変更します。
response.setContentType("application/ms-Excel; charset=UTF-8");
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-Disposition","attachment; filename="+URLEncoder.encode(fileName, "UTF-8"));
URLEncoder呼び出しで、2番目のオプション引数「UTF-8」を渡します。 http://docs.Oracle.com/javase/1.4.2/docs/api/Java/net/URLEncoder.html#encode(Java.lang.String、%20Java.lang.String) を参照してください=
これが私がしたことで、[〜#〜] all [〜#〜]ブラウザー(Chrome、Firefox、Safari)で動作します。また、ブラウザ固有のコードを記述する必要はありませんでした。
すべてのブラウザは、URLのパスコンポーネントからファイル名を取得しようとします
そのため、ブラウザが最後にファイル名を含むURLを要求すると、ファイルに正しく名前が付けられます。これはすべてのブラウザに当てはまるようです。
私の場合、クライアントはダウンロードしたいファイル名を知りません。システムは、IDに基づいてファイルのGETを実行します。例えば:
/api/file/download/<file_id>
だから、私がやったことは、そのAPIにファイル名を検索させ(dbにfile_idで保存する)、URLエンコードし、redirectファイル名を含む2番目のAPIへ。例えば:
/api/file/download/<file_id>/<url-encoded filename>
次に、2番目のAPIはfile_idを使用してファイルのコンテンツを見つけてストリームバックし、ブラウザはファイル名の部分を使用してダウンロードしたファイルに名前を付けます。
注:2番目のAPIはファイル名を無視します(必要ありません)。また、Content-Dispositionヘッダーを「attachment;」に設定します。のみ(ファイル名を設定しないでください。ブラウザにURLから取得させます。)
以下は正常に動作します。
String fileName = URLEncoder.encode(fileName, "UTF-8");
response.setHeader("Content-Disposition","attachment; filename="+fileName );