浏览器下载/导出文件
Posted redjk
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浏览器下载/导出文件相关的知识,希望对你有一定的参考价值。
1 比如以下按钮, 用于导出文件,如EXCEL文件。
<li>
<button class="whiteBg btn2" onclick="doExp(1);return false; ">
<i class="fa fa-save (alias) m-r-xs" ></i>导出所有工单
</button>
</li>
<li>
<button class="whiteBg btn2" onclick="doExp(2);return false; ">
- <i class="fa fa-file-text-o m-r-xs"></i>导出所选工单
</button>
</li>
2.1 调用的js方法如下 , 通过url传值的方式get请求到SpringMVC的控制器.
function expExcel(){
//alert("expExcel");
var url="../user/expExcel?loginName=${user.loginName}&userName=${user.userName}&moblie=${user.mobile}";
//alert(url);
window.location.href=url;
}
- 或者用
- function exportExcel(){ if(flag){ flag = false; window.location.href = "${ctx}/rpt/4gSite/empToExcel";setTimeout(function(){flag = true;},2000); } }
- 或者, 都是一样的用法.
- $(function(){ exp=function(){ var query_time=$(\'#query_time\').val(); window.location.href="../../doExp?query_time="+query_time; } });
window.location.href 为本页面跳转请求 (js中在本页面调整,上页面调整之类的用法可以延伸阅读), 对应的控制器代码如下, 从DB获取数据后生成对应的文件,然后通过ServletUtils.flushExcelOutputStream
输出流写给浏览器.
@RequestMapping("/expToExcel")
public void expToExcel(HttpServletRequest request, HttpServletResponse response) {
UserContext uc = this.getUserContext(request);
String loginName = request.getParameter("loginName");
String userName= request.getParameter("userName");
String moblie= request.getParameter("moblie");
- User user=new User();
user.setLoginName(loginName);
user.setUserName(userName);
user.setMobile(moblie);
List<User> users=this.userService.getListBy(user,uc);
ExcelExportUtils2<User> exUser = new ExcelExportUtils2<User>();
HSSFWorkbook workbook = exUser.exportExcel(new HSSFWorkbook(),"用户列表清单", users);
ServletUtils.flushExcelOutputStream(request, response, workbook,
"用户列表清单_"+DateUtil.formatDateToString("yyyyMMdd", new Date()));
}
对应ServletUtils.flushExcelOutputStream的代码 【ServletUtils的代码可以参考springside或者jeesite】】
分两个步骤,
1判断不同的浏览器,对文件名的中文字符进行编码。
2然后利用输出流将文件写出给浏览器。
/**
* 导出Excel,使用自定义的名字作为文件名
* @param request
* @param response
* @param dataList
* @throws UnsupportedEncodingException
* @throws IOException
*/
public static void flushExcelOutputStream(HttpServletRequest request, HttpServletResponse response,
HSSFWorkbook workbook,String fileName) {
String userAgent = request.getHeader("User-Agent");
String newFileName = null;
try {
fileName = URLEncoder.encode(fileName, "UTF8");
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
if (userAgent != null) {
userAgent = userAgent.toLowerCase();
// IE浏览器,只能采用URLEncoder编码
if (userAgent.indexOf("msie") != -1) {
newFileName = "filename=\\"" + fileName + ".xls\\"";
}
// Opera浏览器只能采用filename*
else if (userAgent.indexOf("opera") != -1) {
newFileName = "filename*=UTF-8\'\'" + fileName +".xls";
}
// Safari浏览器,只能采用ISO编码的中文输出
else if (userAgent.indexOf("safari") != -1) {
try {
newFileName = "filename=\\""
+ new String(fileName.getBytes("UTF-8"), "ISO8859-1")
+ ".xls\\"";
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
// Chrome浏览器,只能采用MimeUtility编码或ISO编码的中文输出
else if (userAgent.indexOf("applewebkit") != -1) {
try {
fileName = MimeUtility.encodeText(fileName, "UTF8", "B");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
newFileName = "filename=\\"" + fileName + ".xls\\"";
}
// FireFox浏览器,可以使用MimeUtility或filename*或ISO编码的中文输出
else if (userAgent.indexOf("mozilla") != -1) {
newFileName = "filename*=UTF-8\'\'" + fileName +".xls";
}
}
//文件名编码结束。
response.setHeader("Content-Disposition", "attachment;" + newFileName); // 这个很重要
ServletUtils.setDisableCacheHeader(response);
ServletOutputStream out = null;
try {
out = response.getOutputStream();
workbook.write(out);
out.flush();
} catch (IOException e) {
e.printStackTrace();
}finally{
if(out != null){
try {
out.close();
} catch (IOException e) {
logger.error(e.getMessage(), e);
e.printStackTrace();
}
}
}
}
2.2 以上都是基于url传值的方式(GET方式)就参数传给后台处理.
这是比较常用的方式.
问题有2个
1 参数过多的话传递麻烦.
2 get方式传递的长度有限制
针对 传参麻烦可以通过以下方式改进, 将表单序列化
window.location.href = "../../../../download?"+$(\'#form_Report\').serialize();
window.location.href = "../../../../download?userName=${user.userName}"+"&"+$(\'#form_Report\').serialize();
注意序列化中用到的是serialize().
注意serialize() 和serializearray()的不同
针对2的问题,只能通过post方式提交来规避.
3.1 实现方式1
js可以直接将表单table直接提交的方式来传递参数给SpringMVC的控制器: 效果也一样的. 这里要注意table的action被修改了. 表单查询调用时需注意.
//这里jeesite使用jbox插件.调用top.$.jBox.confirm 在父页面上弹出确认框,然后还是使用js
更改form的action并提交$("#submitForm").attr("action", url);
触发submit事件,再提交表单$("#submitForm").submit();
<input id="btnExport" class="btn btn-primary" type="button" value="导出"/>
$(document).ready(function() {
// 表格排序
tableSort({callBack : page});
$("#btnExport").click(function(){
top.$.jBox.confirm("确认要导出用户数据吗?","系统提示",function(v,h,f){
if(v == "ok"){
$("#searchForm").attr("action","${ctx}/sys/user/export").submit();
}
},{buttonsFocus:1});
top.$(\'.jbox-body .jbox-icon\').css(\'top\',\'55px\');
});
$("#btnImport").click(function(){
$.jBox($("#importBox").html(), {title:"导入数据", buttons:{"关闭":true},
bottomText:"导入文件不能超过5M,仅允许导入“xls”或“xlsx”格式文件!"});
});
});
3.2 本方法和3.1大同小异, 都是通过表单的方式来提交.3.2模拟一个表单将参数填入创建input
通过js模拟表单提交
调用如下
DownLoadFile2({url:\'../../../alarm/doExp\',data:ids}); //ids为选中的数据的id如拼接字符串,如: 1,2,3,55,333,123,
所调用方法如下
//提交表单
var DownLoadFile = function (options) {
var config = $.extend(true, { method: \'post\' }, options);
var $iframe = $(\'<iframe id="down-file-iframe" />\');
var $form = $(\'<form target="down-file-iframe" method="\' + config.method + \'" />\');
$form.attr(\'action\', config.url);
for (var key in config.data) {
$form.append(\'<input type="hidden" name="\' + key + \'" value="\' + config.data[key] + \'" />\');
}
$iframe.append($form);
$(document.body).append($iframe);
$form[0].submit();
$iframe.remove();
};
//提交参数
var DownLoadFile2 = function (options) {
var config = $.extend(true, { method: \'post\' }, options);
var $iframe = $(\'<iframe id="down-file-iframe" />\');
var $form = $(\'<form target="down-file-iframe" method="\' + config.method + \'" />\');
$form.attr(\'action\', config.url);
$form.append(\'<input type="hidden" name="ids" value="\' + options.data + \'" />\');
$iframe.append($form);
$(document.body).append($iframe);
$form[0].submit();
$iframe.remove();
};
如IE8下中文存在问题可以优化为
var DownLoadFile = function (options) {
var config ={ method: \'post\' };
var $form = $(\'<form method="\' + config.method + \'" />\');
$(document.body).append($form);
$form.attr(\'action\', options.url);
for (var key in options.data) {
$form.append(\'<input type="hidden" name="\' + key + \'" value="\' + options.data[key] + \'" />\');
}
$form[0].submit();
$form.remove();
};
调用方法举例
var DownLoadFile = function (options) {
var config ={ method: \'post\' };
var $form = $(\'<form method="\' + config.method + \'" />\');
$(document.body).append($form);
$form.attr(\'action\', options.url);
for (var key in options.data) {
$form.append(\'<input type="hidden" name="\' + key + \'" value="\' + options.data[key] + \'" />\');
}
$form[0].submit();
$form.remove();
};
后台方法一样, 控制器输出流写文件即可.
备注:
- $(selector).serialize() 序列表表格内容为字符串,用于 Ajax 请求。可以对整个form,也可以只针对某部分。
$(\'#form\').submit(function(event){
event.preventDefault();
$.ajax({
url:\' \',
type:\'post\',
data:$("form").serialize(),
}
- $(selector).serializeArray()
serializeArray() 方法序列化表单元素(类似 .serialize() 方法),返回 JSON 数据结构数据。
注意:此方法返回的是 JSON 对象而非 JSON 字符串。需要使用插件或者第三方库进行字符串化操作。
返回的 JSON 对象是由一个对象数组组成的,其中每个对象包含一个或两个名值对 —— name 参数和 value 参数(如果 value 不为空的话)。举例来说:
[ {name: \'firstname\', value: \'Hello\'}, {name: \'lastname\', value: \'World\'}, {name: \'alias\'}, // 值为空 ]
.serializeArray() 方法使用了 W3C 关于 successful controls(有效控件) 的标准来检测哪些元素应当包括在内。特别说明,元素不能被禁用(禁用的元素不会被包括在内),并且元素应当有含有 name 属性。提交按钮的值也不会被序列化。文件选择元素的数据也不会被序列化。
该方法可以对已选择单独表单元素的对象进行操作,比如 <input>, <textarea>, 和 <select>。不过,更方便的方法是,直接选择 <form> 标签自身来进行序列化操作。
$("form").submit(function() {
console.log($(this).serializeArray());
return false;
});
上面的代码产生下面的数据结构(假设浏览器支持 console.log):
[
{
name: a
value: 1
},
{
name: b
value: 2
},
{
name: c
value: 3
},
{
name: d
value: 4
},
{
name: e
value: 5
}
]
- $.params() $.param()方法是serialize()方法的核心,用来对一个数组或对象按照key/value进行序列化。
序列化一个 key/value 对象:
var params = { width:1900, height:1200 }; var str = jQuery.param(params); $("#results").text(str);结果:
width=1680&height=1050
以上是关于浏览器下载/导出文件的主要内容,如果未能解决你的问题,请参考以下文章