文件导出ie文件名乱码解决

 

Content-Disposition值

Content-Disposition值可以有以下几种编码格式:

  1. 直接urlencode:

    Content-Disposition: attachment; filename="struts2.0%E4%B8%AD%E6%96%87%E6%95%99%E7%A8%8B.chm"

  2. Base64编码:

    Content-Disposition: attachment; filename="=?UTF8?B?c3RydXRzMi4w5Lit5paH5pWZ56iLLmNobQ==?="

  3. RFC2231规定的标准:

    Content-Disposition: attachment; filename*=UTF-8''%E5%9B%9E%E6%89%A7.msg

  4. 直接ISO编码的文件名:

    Content-Disposition: attachment;filename="测试.txt"

各浏览器支持的对应编码格式

  • IE浏览器,采用URLEncoder编码
  • Opera浏览器,采用filename*方式
  • Safari浏览器,采用ISO编码的中文输出
  • Chrome浏览器,采用Base64编码或ISO编码的中文输出
  • FireFox浏览器,采用Base64或filename*或ISO编码的中文输出

实现


/**
 * 根据User-Agent 判断是什么浏览器 生成不同的header 防止下载文件 中文乱码
 * @param request
 * @param filename
 * @return
 * @throws UnsupportedEncodingException
 * @see <a href="https://www.cnblogs.com/zhangzhen894095789/p/6479033.html">https://www.cnblogs.com/zhangzhen894095789/p/6479033.html</a>
 */
private String getFileName(HttpServletRequest request, String filename) throws UnsupportedEncodingException {
    String userAgent = request.getHeader("User-Agent");
    String new_filename = URLEncoder.encode(filename, StandardCharsets.UTF_8.name());
    // 如果没有UA,则默认使用IE的方式进行编码,因为毕竟IE还是占多数的
    String rtn = "filename=\"" + new_filename + "\"";
    if (userAgent != null) {
        userAgent = userAgent.toLowerCase();
        // IE浏览器,只能采用URLEncoder编码
        if (userAgent.contains("msie")) {
            rtn = "filename=\"" + new_filename + "\"";
        }
        // Opera浏览器只能采用filename*
        else if (userAgent.contains("opera")) {
            rtn = "filename*=UTF-8''" + new_filename;
        }
        // Safari浏览器,只能采用ISO编码的中文输出
        else if (userAgent.contains("safari")) {
            rtn = "filename=\"" + new String(filename.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1) + "\"";
        }
        // Chrome浏览器,只能采用MimeUtility编码或ISO编码的中文输出
        else if (userAgent.contains("applewebkit")) {
            new_filename = MimeUtility.encodeText(filename, StandardCharsets.UTF_8.name(), "B");
            rtn = "filename=\"" + new_filename + "\"";
        }
        // FireFox浏览器,可以使用MimeUtility或filename*或ISO编码的中文输出
        else if (userAgent.contains("mozilla")) {
            rtn = "filename*=UTF-8''" + new_filename;
        }
    }
    return rtn;
}

使用:response.addHeader("Content-Disposition", "attachment;" + getFileName(request, exportFileName));

不同浏览器上中文文件名的下载乱码问题