from http://my.oschina.net/u/128568/blog/198276
先说说下载文件的方式,一般情况下,对于报表系统,导出数据时有两种方式下载,比如导出10万数据,一种是直接以流的形式传输,即直接输出数据到客户端,这种方式的坏处是一旦网络出现一点问题,比如公司杀毒给你闪断一下,下载后文件打开就会有问题;一种是直接在服务端把导出的数据写成一个本地文件,放在临时文件夹下,然后进行文件下载,这样即使比较大的数据导出也不会有问题。
接下来说说文件下载乱码的问题,由于编码不同,不同的浏览器接收文件下载方式不同,导致在某些浏览器下载时出现文件名乱码的情况,此时需要针对不同浏览器进行文件名编码:
首先在文件下载时,请求类型需要设置编码 :
1 | request.setCharacterEncoding( "UTF-8" ); |
2 | response.setContentType( "application/octet-stream; charset=utf-8" ); |
3 | response.setHeader( "Content-disposition" , |
4 | "attachment;" + UserAgentUtil.encodeFileName(request, fileName)); |
5 | response.setHeader( "Content-Length" , String.valueOf(fileLength)); |
源码文件FileOperateUtil.java
最终文件名处理交给UserAgentUtil的encodeFileName:
10 | public static String encodeFileName(HttpServletRequest request, String fileName) { |
11 | String userAgent = request.getHeader( "User-Agent" ); |
14 | String new_filename = URLEncoder.encode(fileName, "UTF8" ); |
16 | rtn = "filename=\"" + new_filename + "\"" ; |
17 | if (userAgent != null ) { |
18 | userAgent = userAgent.toLowerCase(); |
20 | if (userAgent.indexOf( "msie" ) != - 1 ) { |
21 | rtn = "filename=\"" + new_filename + "\"" ; |
24 | else if (userAgent.indexOf( "opera" ) != - 1 ) { |
25 | rtn = "filename*=UTF-8''" + new_filename; |
28 | else if (userAgent.indexOf( "safari" ) != - 1 ) { |
29 | rtn = "filename=\"" + new String(fileName.getBytes( "UTF-8" ), "ISO8859-1" ) + "\"" ; |
32 | else if (userAgent.indexOf( "applewebkit" ) != - 1 ) { |
33 | new_filename = MimeUtility.encodeText(fileName, "UTF8" , "B" ); |
34 | rtn = "filename=\"" + new_filename + "\"" ; |
37 | else if (userAgent.indexOf( "mozilla" ) != - 1 ) { |
38 | rtn = "filename*=UTF-8''" + new_filename; |
41 | } catch (UnsupportedEncodingException e) { |
源码文件:UserAgentUtil.java
这样在进行文件下载时,使用这个工具类对文件名进行一次编码,就可以处理不同浏览器下载文件乱码的问题了。