zoukankan      html  css  js  c++  java
  • 浏览器下载/导出文件 及jQuery表单提交

    1 比如以下按钮, 用于导出文件,如EXCEL文件。
    1. <li>
    2. <button class="whiteBg btn2" onclick="doExp(1);return false; ">
    3.    <i class="fa fa-save (alias) m-r-xs" ></i>导出所有工单
    4. </button>
    5. </li>
    6. <li>
    7. <button class="whiteBg btn2" onclick="doExp(2);return false; "
    8. <i class="fa fa-file-text-o m-r-xs"></i>导出所选工单
    9. </button>
    10. </li>

    2.1 调用的js方法如下 , 通过url传值的方式get请求到SpringMVC的控制器.
    1. function expExcel(){
    2. //alert("expExcel");
    3. var url="../user/expExcel?loginName=${user.loginName}&userName=${user.userName}&moblie=${user.mobile}";
    4. //alert(url);
    5. window.location.href=url;
    6. }
    7. 或者用
    8. function exportExcel(){ if(flag){ flag = false; window.location.href = "${ctx}/rpt/4gSite/empToExcel";setTimeout(function(){flag = true;},2000); } }
    9. 或者, 都是一样的用法.
    10. $(function(){ exp=function(){ var query_time=$('#query_time').val(); window.location.href="../../doExp?query_time="+query_time; } });
    window.location.href  为本页面跳转请求 (js中在本页面调整,上页面调整之类的用法可以延伸阅读), 对应的控制器代码如下, 从DB获取数据后生成对应的文件,然后通过ServletUtils.flushExcelOutputStream
    输出流写给浏览器.
    1. @RequestMapping("/expToExcel")
    2. public void expToExcel(HttpServletRequest request, HttpServletResponse response) {
    3. UserContext uc = this.getUserContext(request);
    4. String loginName = request.getParameter("loginName");
    5. String userName= request.getParameter("userName");
    6. String moblie= request.getParameter("moblie");
    7. User user=new User();
    8. user.setLoginName(loginName);
    9. user.setUserName(userName);
    10. user.setMobile(moblie);
    11. List<User> users=this.userService.getListBy(user,uc);
    12. ExcelExportUtils2<User> exUser = new ExcelExportUtils2<User>();
    13. HSSFWorkbook workbook = exUser.exportExcel(new HSSFWorkbook(),"用户列表清单", users);
    14. ServletUtils.flushExcelOutputStream(request, response, workbook,
    15. "用户列表清单_"+DateUtil.formatDateToString("yyyyMMdd", new Date()));
    16. }
    对应ServletUtils.flushExcelOutputStream的代码  【ServletUtils的代码可以参考springside或者jeesite】
    分两个步骤, 
    1判断不同的浏览器,对文件名的中文字符进行编码。
    2然后利用输出流将文件写出给浏览器。
    1. /**
    2. * 导出Excel,使用自定义的名字作为文件名
    3. * @param request
    4. * @param response
    5. * @param dataList
    6. * @throws UnsupportedEncodingException
    7. * @throws IOException
    8. */
    9. public static void flushExcelOutputStream(HttpServletRequest request, HttpServletResponse response,
    10. HSSFWorkbook workbook,String fileName) {
    11. String userAgent = request.getHeader("User-Agent");
    12. String newFileName = null;
    13. try {
    14. fileName = URLEncoder.encode(fileName, "UTF8");
    15. } catch (UnsupportedEncodingException e1) {
    16. e1.printStackTrace();
    17. }
    18. if (userAgent != null) {
    19. userAgent = userAgent.toLowerCase();
    20. // IE浏览器,只能采用URLEncoder编码
    21. if (userAgent.indexOf("msie") != -1) {
    22. newFileName = "filename="" + fileName + ".xls"";
    23. }
    24. // Opera浏览器只能采用filename*
    25. else if (userAgent.indexOf("opera") != -1) {
    26. newFileName = "filename*=UTF-8''" + fileName +".xls";
    27. }
    28. // Safari浏览器,只能采用ISO编码的中文输出
    29. else if (userAgent.indexOf("safari") != -1) {
    30. try {
    31. newFileName = "filename=""
    32. + new String(fileName.getBytes("UTF-8"), "ISO8859-1")
    33. + ".xls"";
    34. } catch (UnsupportedEncodingException e) {
    35. e.printStackTrace();
    36. }
    37. }
    38. // Chrome浏览器,只能采用MimeUtility编码或ISO编码的中文输出
    39. else if (userAgent.indexOf("applewebkit") != -1) {
    40. try {
    41. fileName = MimeUtility.encodeText(fileName, "UTF8", "B");
    42. } catch (UnsupportedEncodingException e) {
    43. e.printStackTrace();
    44. }
    45. newFileName = "filename="" + fileName + ".xls"";
    46. }
    47. // FireFox浏览器,可以使用MimeUtility或filename*或ISO编码的中文输出
    48. else if (userAgent.indexOf("mozilla") != -1) {
    49. newFileName = "filename*=UTF-8''" + fileName +".xls";
    50. }
    51. }
    52. //文件名编码结束。

    53. response.setHeader("Content-Disposition", "attachment;" + newFileName); // 这个很重要
    54. ServletUtils.setDisableCacheHeader(response);
    55. ServletOutputStream out = null;
    56. try {
    57. out = response.getOutputStream();
    58. workbook.write(out);
    59. out.flush();
    60. } catch (IOException e) {
    61. e.printStackTrace();
    62. }finally{
    63. if(out != null){
    64. try {
    65. out.close();
    66. } catch (IOException e) {
    67. logger.error(e.getMessage(), e);
    68. e.printStackTrace();
    69. }
    70. }
    71. }
    72. }

     2.2 以上都是基于url传值的方式(GET方式)就参数传给后台处理.
    这是比较常用的方式.
    问题有2个
    1 参数过多的话传递麻烦.
    2 get方式传递的长度有限制
    针对 传参麻烦可以通过以下方式改进, 将表单序列化
    1. window.location.href = "../../../../download?"+$('#form_Report').serialize();
    2. 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();
    1. <input id="btnExport" class="btn btn-primary" type="button" value="导出"/>
    1. $(document).ready(function() {
    2. // 表格排序
    3. tableSort({callBack : page});
    4. $("#btnExport").click(function(){
    5. top.$.jBox.confirm("确认要导出用户数据吗?","系统提示",function(v,h,f){
    6. if(v == "ok"){
    7. $("#searchForm").attr("action","${ctx}/sys/user/export").submit();
    8. }
    9. },{buttonsFocus:1});
    10. top.$('.jbox-body .jbox-icon').css('top','55px');
    11. });
    12. $("#btnImport").click(function(){
    13. $.jBox($("#importBox").html(), {title:"导入数据", buttons:{"关闭":true},
    14. bottomText:"导入文件不能超过5M,仅允许导入“xls”或“xlsx”格式文件!"});
    15. });
    16. });
    3.2  本方法和3.1大同小异, 都是通过表单的方式来提交.3.2模拟一个表单将参数填入创建input
    通过js模拟表单提交
    调用如下
    1. DownLoadFile2({url:'../../../alarm/doExp',data:ids}); //ids为选中的数据的id如拼接字符串,如: 1,2,3,55,333,123,
    所调用方法如下
    1. //提交表单
    2. var DownLoadFile = function (options) {
    3. var config = $.extend(true, { method: 'post' }, options);
    4. var $iframe = $('<iframe id="down-file-iframe" />');
    5. var $form = $('<form target="down-file-iframe" method="' + config.method + '" />');
    6. $form.attr('action', config.url);
    7. for (var key in config.data) {
    8. $form.append('<input type="hidden" name="' + key + '" value="' + config.data[key] + '" />');
    9. }
    10. $iframe.append($form);
    11. $(document.body).append($iframe);
    12. $form[0].submit();
    13. $iframe.remove();
    14. };
    15. //提交参数
    16. var DownLoadFile2 = function (options) {
    17. var config = $.extend(true, { method: 'post' }, options);
    18. var $iframe = $('<iframe id="down-file-iframe" />');
    19. var $form = $('<form target="down-file-iframe" method="' + config.method + '" />');
    20. $form.attr('action', config.url);
    21. $form.append('<input type="hidden" name="ids" value="' + options.data + '" />');
    22. $iframe.append($form);
    23. $(document.body).append($iframe);
    24. $form[0].submit();
    25. $iframe.remove();
    26. };
    如IE8下中文存在问题可以优化为
    1. var DownLoadFile = function (options) {
    2. var config ={ method: 'post' };
    3. var $form = $('<form method="' + config.method + '" />');
    4. $(document.body).append($form);
    5. $form.attr('action', options.url);
    6. for (var key in options.data) {
    7. $form.append('<input type="hidden" name="' + key + '" value="' + options.data[key] + '" />');
    8. }
    9. $form[0].submit();
    10. $form.remove();
    11. };
    调用方法举例
    1. var DownLoadFile = function (options) {
    2. var config ={ method: 'post' };
    3. var $form = $('<form method="' + config.method + '" />');
    4. $(document.body).append($form);
    5. $form.attr('action', options.url);
    6. for (var key in options.data) {
    7. $form.append('<input type="hidden" name="' + key + '" value="' + options.data[key] + '" />');
    8. }
    9. $form[0].submit();
    10. $form.remove();
    11. };
    后台方法一样, 控制器输出流写文件即可.



    备注:

    • $(selector).serialize() 序列表表格内容为字符串,用于 Ajax 请求。可以对整个form,也可以只针对某部分。

    1. $('#form').submit(function(event){
    2. event.preventDefault();
    3. $.ajax({
    4. url:' ',
    5. type:'post',
    6. data:$("form").serialize(),
    7. }

    • $(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> 标签自身来进行序列化操作。

    1. $("form").submit(function() {
    2. console.log($(this).serializeArray());
    3. return false;
    4. });
    5. 上面的代码产生下面的数据结构(假设浏览器支持 console.log):
    6. [
    7. {
    8. name: a
    9. value: 1
    10. },
    11. {
    12. name: b
    13. value: 2
    14. },
    15. {
    16. name: c
    17. value: 3
    18. },
    19. {
    20. name: d
    21. value: 4
    22. },
    23. {
    24. name: e
    25. value: 5
    26. }
    27. ]
    • $.params() $.param()方法是serialize()方法的核心,用来对一个数组或对象按照key/value进行序列化。

    序列化一个 key/value 对象:

    var params = { 1900, height:1200 };
    var str = jQuery.param(params);
    $("#results").text(str);
    

    结果:

    width=1680&height=1050





  • 相关阅读:
    微软ASP.NET网站部署指南(4):配置项目属性
    iOS 设计模式之抽象工厂
    How can I move a MySQL database from one server to another?
    CentOS 7 上安装vim(默认未安装)
    How to resize slide dimensions without resizing any objects on the slide?
    CentOS 7.3 上安装docker
    美国留学访学(访问学者)必备信用卡
    西安理工大学税务登记证、银行账号信息
    Oracle联合多个子查询(inner join)
    linux tail
  • 原文地址:https://www.cnblogs.com/redcoatjk/p/5960937.html
Copyright © 2011-2022 走看看