js下载文件以及下载文件名乱码问题的解决

时间:2025-03-03 10:34:30

原文链接    js发送post请求下载文件

关键点:

1.封装form表单提交,做成类似post请求传递多参数下载文件的效果。

2.请求参数乱码的简单纪要

3.下载功能,中文文件名的乱码解决

4.下载CSV格式的文件的乱码问题分析


大家都知道ajax是不能直接下载文件的,所以一般都是通过一个超链接的形式去下载一个文件

但是当牵扯到需要发送很多数据到服务器上再下载的时候超链接的形式就有些太过勉强了

如下是一个工具方法(依赖jquery) 可以通过发送多数据的情况下下载文件,代码如下:

/*===================下载文件
 * options:{
 * url:'',  //下载地址
 * data:{name:value}, //要发送的数据
 * method:'post'
 * }
 */
var DownLoadFile = function (options) {
    var config = $.extend(true, { method: 'post' }, options);
    var $iframe = $('<iframe  />');
    var $form = $('<form target="down-file-iframe" method="' +  + '" />');
    $('action', );
    for (var key in ) {
        $('<input type="hidden" name="' + key + '" value="' + [key] + '" />');
    }
    $($form);
    $().append($iframe);
    $form[0].submit();
    $();
}

很简单的,传如url和数据就可以啦

demo: DownLoad({

url:'.....', //请求的url

data:{sc:'xxx'}//要发送的数据

});


根据博主的文章,我自己测试了下,确实可行。

本质上这个已经不是$Ajax的post请求了。而是form表单的post请求,请求同步的,而不是异步的。


针对ie8下不兼容的问题。解决方案:

最后的解决方案是直接用一个form,没有嵌套iframe。(时间问题,没有亲试,但是这种form表单的post请求方案,理论上是绝对可行的。

下面是我自己做js导出CVS文档的例子:

jsp页面,就一个按钮

<body>
 <button >导出CVS</button> 
</body>


js:

<script type="text/javascript" src="/jquery/jquery-1.8."></script>
<script type="text/javascript">
/*===================下载文件
 * options:{
 * url:'',  //下载地址
 * data:{name:value}, //要发送的数据
 * method:'post'
 * }
 * 过了有一段时间了,忘记当时IE8具体是哪里的问题。
 最后的解决方案是直接用一个form,没有嵌套iframe。
 */
var DownLoadFile = function (options) {
    var config = $.extend(true, { method: 'post' }, options);
    var $iframe = $('<iframe  />');
    var $form = $('<form target="down-file-iframe" method="' +  + '" />');
    $('action', );
    for (var key in ) {
        $('<input type="hidden" name="' + key + '" value="' + [key] + '" />');
    }
    $($form);
    $().append($iframe);
    $form[0].submit();
    $();
}
 
 
 
  $('#getcsv').click(function () {
		var  csv_data ="姓名,年龄";
		for (var i = 0; i < 100; i++) {
			csv_data+="\n长征,123";
		}
		DownLoadFile({ 
			url:'', //请求的url
			data:{csv:csv_data,flag:'exportExcel'}//要发送的数据
			});
  });
</script>

servlet代码:

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
	      /**
	       * 注意,Request格式的设置只有在doPost方法中才会有效,如果是在doPost的方法内部的方法中调用,
	       * 如exportExcel(req,resp)方法内部调用("UTF-8"),参数仍然是乱码。
	       * 
	       * get请求的参数,是web服务器决定编码,默认是URIEncoding=iso8859-1。所以可以在servlet中使用
	       * String param = new String(("iso8859-1"),"UTF-8");
	       * 当然,更直接的方法是修改tomcat中的URIEncoding,如下
	       * 修改tomcat的配置文件:
             <Connector URIEncoding="UTF-8" 
                 port="8080"   maxHttpHeaderSize="8192"
               maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
               connectionTimeout="20000" disableUploadTimeout="true" />
                                             只需增加 URIEncoding="UTF-8"  这一句,然后重启tomcat即可。
	       * 
	       */
		   ("UTF-8");//只对post请求的参数有效
		  String flag=("flag");
		  //根据flag分发请求
	     if(("login")){
		  doLogin(req,resp);
           }else if(("out")){
           	doOut(req,resp);
         }else if(("exportExcel")){
        	 exportExcel(req,resp);
         }   
	}

具体导出CSV的方法:

/**
	 * js导出Excel
	 * @param req
	 * @param resp
	 */
	private void exportExcel(HttpServletRequest req, HttpServletResponse resp){
	/**
	 * ("application/csv;charset=gbk"); 
	 * ("Content-Disposition","attachment; filename="); 
	 * PrintWriter out = (); 
	 * 因为excel是用ansi编码打开,不是你导出文件乱码,而是它渲染乱码了. 所以如果你的用户是win,应该设置为gbk编码.
	 * 当然这样在linux下应该就是乱码了.. 另外导出excel可以参考我写的 jfinal-ext中 excelRender
	 * 
	 * 如果您的CSV是由Windows Live Mail导出,那么,这是由于您所用的CSV文件编码不同有关的。
	 * 在Windows Live Mail中所到处的CSV文件编码为“UTF-8”,而Outlook 2007所支持的格式为“ANSI”。
	 * 您需要将导出的CSV文件另存一份,保存时在“编码”下选择“ANSI”,然后再尝试在Outlook 2007下导入另存后的CSV文件。
	 */
			try {
				String 	csv = ("csv");
				String filename  = "中国你好.csv";
				//方式一:ie,迅雷下乱码,谷歌,火狐下正常,360急速模式正常,兼容模式乱码
				//filename = new String((), "ISO8859_1"); 
				//方式二:360下2种模式都正常,ie,谷歌和迅雷下文件都没有乱码,但是火狐下出现乱码
				//filename = (filename, "UTF-8");
				//方式三:全部正常
				filename = processFileName(req,filename);
						
				("application/csv;charset=GBK");// ("GBK");这里注意,csv默认使用的是GBK的编码格式
				("Content-Disposition","attachment; filename=" + filename);
				// 
				
				if(csv!=null && !"".equals(csv)) {
				    	().print(csv);
				    }
			} catch (Exception e) {
				// TODO Auto-generated catch block
				();
			}
	}

处理导出文件名乱码的方法:

/** 
     *  处理导出生成的Excel文件名在火狐或ie下出现乱码的问题
     * @Title: processFileName 
     *  
     * @Description: ie,chrom,firfox下处理文件名显示乱码 
     */  
    public static String processFileName(HttpServletRequest request, String fileNames) {  
        String codedfilename = null;  
        try {  
            String agent = ("USER-AGENT");  
            if (null != agent && -1 != ("MSIE") || null != agent  
                    && -1 != ("Trident")) {// ie  
  
                String name = (fileNames, "UTF8");  
  
                codedfilename = name;  
            } else if (null != agent && -1 != ("Mozilla")) {// 火狐,chrome等  
  
  
                codedfilename = new String(("UTF-8"), "iso-8859-1");  
            }  
        } catch (Exception e) {  
            ();  
        }  
        return codedfilename;  
    }