您的位置:首页 > 其它

在IE下-下载文件-文件名中文名乱码问题

2016-07-05 15:36 267 查看
首先说明下各浏览器对文件下载的文件名解析编码如下:

1.  IE浏览器,采用URLEncoder编码 

2.  Opera浏览器,采用filename*方式 

3.  Safari浏览器,采用ISO编码的中文输出

4.  Chrome浏览器,采用Base64编码或ISO编码的中文输出 

5.  FireFox浏览器,采用Base64或filename*或ISO编码的中文输出 

那么IE浏览器的文件名编码解析就得单独处理了。

Sturts2的下载处理方法如下:

package com.dhcc.iscp.web.filedownload.action;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.Date;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.InterceptorRef;
import org.apache.struts2.convention.annotation.InterceptorRefs;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.springframework.context.annotation.Scope;

import com.dhcc.framework.exception.DataBaseException;
import com.dhcc.framework.util.StringUtils;
import com.dhcc.iscp.service.exchangestandard.BusinessOrganDictionaryInfoService;
import com.dhcc.iscp.service.exchangestandard.OrganTermRangeInfoService;
import com.dhcc.iscp.util.DateUtil;
import com.opensymphony.xwork2.ActionSupport;

@Namespace(value = "/download")
@Scope("prototype")
@Action("MappingDownloadCtrl")
@Results({
@Result(name = "success", type = "stream", params = { "contentType", "application/vnd.ms-excel;charset=UTF-8",
// 两个是一对属性设置
"inputName", "excelStream", "contentDisposition", "attachment;filename=\"${fileName}.xls\"" }) })
@InterceptorRefs({@InterceptorRef("fileUpload"),@InterceptorRef("dhccStack")})
public class MappingDownloadAction extends ActionSupport {

private static final long serialVersionUID = -8499404699578479452L;

private InputStream excelStream;
// 文件名称
private String fileName;

/**
* @return fileName
*/
public String getFileName() {
return fileName;
}

/**
* @param fileName
* fileName
*/
public void setFileName(String fileName) {
this.fileName = fileName;
}

public InputStream getExcelStream() {
return excelStream;
}

@Resource
OrganTermRangeInfoService organTermRangeInfoService;
@Resource
BusinessOrganDictionaryInfoService organDicInfoService;

private void templateDownload(String fileName) {
HttpServletRequest request = ServletActionContext.getRequest();
try {
InputStream inputStream = MappingDownloadAction.class.getClassLoader()
.getResourceAsStream("/download/" + fileName + ".xls");
HSSFWorkbook workbook = new HSSFWorkbook(inputStream);
this.workbook2InputStream(workbook,fileName,request);
} catch (Exception e) {
throw new DataBaseException(e.getMessage(), e);
}
}

private void workbook2InputStream(HSSFWorkbook workbook, String fileName,HttpServletRequest request) throws Exception {
//如果是IE浏览器,则用URLEncode解析
if(isMSBrowser(request)){
fileName = URLEncoder.encode(fileName, "UTF-8");
}else{//如果是谷歌、火狐则解析为ISO-8859-1
fileName = new String(fileName.getBytes("UTF-8"), "ISO-8859-1");
}
this.fileName = fileName; // 设置fileName
ByteArrayOutputStream baos = new ByteArrayOutputStream();
workbook.write(baos);
baos.flush();
byte[] aa = baos.toByteArray();
excelStream = new ByteArrayInputStream(aa, 0, aa.length);
baos.close();
}

//方法功能描述: 判断是否是IE浏览器
public boolean isMSBrowser(HttpServletRequest request) {
String[] IEBrowserSignals = {"MSIE", "Trident", "Edge"};
String userAgent = request.getHeader("User-Agent");
for (String signal : IEBrowserSignals) {
if (userAgent.contains(signal)){
return true;
}
}
return false;
}

}

注意:对文件名的解析请在统一位置处理,避免反复编码解析而导致的中文乱码。

经测试该方法对IE8可行,谷歌火狐也没无异常。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息