动态生成 Excel 文件供浏览器下载的注意事项

2011-08-10 16:42

 

最近有一个软件项目,客户使用中,发现 IE6 会在页面中打开 Excel 文件,看到乱码。

 

经过调查,发现 IE6 有一些比较怪异的工作方式,可以认定为一个 bug.

发生问题时,通过 Firefox 的插件 Firebug , 发现我们在设置 HTTP response 的 header 时候,设置不当:

response.setContentType("text/csv");//出错在这一行

//以下代码设置文件名,IE 和非 IE 浏览器对于中文文件名处理不同。


String newFileName2 = null;
String userAgent = getUserAgent(request);
if (userAgent.indexOf("MSIE") >= 0) {
    URLCodec codec = new URLCodec();
    newFileName2 = codec.encode(fileName, "UTF-8");
} else {
    newFileName2 = new String(fileName.getBytes("UTF-8"), "ISO-8859-1");
}
if (fileName.toLowerCase().indexOf(".htm") < 0) {
    response.setHeader("Content-disposition", "attachment; filename=\"" + newFileName2 + "\"");
} 
		

以上代码,在 IE6/IE9/Firefox5上,正常运行都没有问题。但是客户报告 IE6上会有乱码。

反复测试后,发现:

如果直接在 IE6 浏览器地址栏中,输入

http://localhost/ctms/web_dispatcher/common/export_binary_file?uuid=1e48cbd96d1b4b25b64d5df234680d27

浏览器弹出一个“打开”“保存”的对话框,如果这时候选择“打开”,则会直接在浏览器中打开乱码窗口。相当于这一行代码失效:

response.setHeader("Content-disposition", "attachment; filename=\"" + newFileName2 + "\"");

但是,如果在页面中,用 javascript 将当前页导航到上述网址,则有的机器 IE6 会乱码,有的机器 IE6 不会乱码。

经过网上 google 搜索,发现Web 系统动态生成 Excel 文件,在 IE6 下很多人都碰到这个问题。

首先想到,把出错行改掉:

response.setContentType("text/csv"); ==> response.setContentType("application/vnd.ms-excel");

测试下来,结果:

chrome/firefox5/ie9 都正常,IE6 能正常下载,不会在当前浏览器窗口中打开出现乱码,但取不到 header 中的文件名,而换成从 url 中得到文件名,结果是: export_binary_file.xls

注意我们的动态网址是:

http://localhost/ctms/web_dispatcher/common/export_binary_file?uuid=1e48cbd96d1b4b25b64d5df234680d27

这很奇怪了。IE6 从 URL 中取文件名的前一半,自动加上 .xls 后缀,拼成新的文件名。

想到我们以后可能会生成 Excel 2007, 或者 Excel 2010 格式的文件,用 "application/vnd.ms-excel" 不合适。

尝试了其它两种办法:

a. response.setContentType("application/octet-stream");

//这个来源于 http://www.ietf.org/rfc/rfc1521.txt

结果:

chrome/firefox5/ie9 都正常, IE6 地址栏输入网址回车,取不到 header 中的文件名,而换成从 url 中得到文件名,结果是: export_binary_file。相比上面 vnd.ms-excel 的出错,少了 .xls 这个文件后缀名。

b. response.setContentType("application/force-download");

结果:

chrome/firefox5/ie9 都正常,IE6 地址栏输入网址回车,结果是: export_binary_file。同 a。

最后结论:

IE6 通过 javascript 导航到动态生成 Excel 的网址,与直接录入网址,保存时文件名是不同的。这应该是一个bug.

更改response.setContentType("text/csv"); 解决了乱码问题,无法彻底解决文件名问题。

推测原因:

在动态网页技术之前的时代,都是静态网页,文件下载的网址通常是这样的:

http://velocityweb.sourceforge.net/zsso_files/zsso-v2.0.1.zip

浏览器保存下载文件时,从网址中取文件名,很正常。

而在动态网页技术时代,网址变成这个样子:

http://localhost/ctms/web_dispatcher/common/export_binary_file?uuid=1e48cbd96d1b4b25b64d5df234680d27

再从网址中,取文件名,就会出乱子。

IE6 在 javascript 跳转到上述网址,正常;直接输入上述网址,文件名不正常,这应该 IE6 没有更改彻底的缘故。最新的浏览器,IE9/Firefox5/chrome,都正常。由于时间关系,我们没有测试 Firefox/chrome 的早期版本浏览器。

我们最后建议这个用户,安装一个 firefox 5 了事。

 

 

欢迎转载,转载请注明出处: https://www.zheguisoft.com/staff_blogs/jacklondon_chen/2011, 及 https://www.cnblogs.com/jacklondon/archive/2011/08/10/2133821.html

 

 

 


请选择网站语言: