最近的一个项目比较忙,一直没时间过来跟新博客。今天过来分享一下在此项目中遇到的一个小问题:导出Excel;相信导出Excel这个功能是特别常见的,也有很多的方式。好了,不多说了,直接说说自己遇到的各种坑,我后台用的是poi导出。

  首先,说一下需求,想要的结果就是:“符合导出条件时,正常导出,并弹出提示框让用户选下载地址,不符合导出条件时,提示用户不能导出,还要在用户导出的同时将导出按钮禁用,当导出成功后,再将导出按钮放开“

  (我首先会将我做的全过程的思路和所遇到的问题和解决方法说一下,干货会在下面贴出来)

    1、因为我们整个框架习惯用异步请求,所以一开始我使用ajax异步请求导出Excel,结果发现导出不了,后台程序也跑完了,日志也记录了,,就是没有出现excel,更别说提示框了,网上查了很多,都说是因为ajax和后台交流用的是字符流,浏览器是不会识别你让他下载的,所以此路不通。(也有小伙伴说用ajax同步,也试了,不行。又填上了一个坑。。。。)

  2、然后就准备用form表单submit提交导出,试了一下,发现可以啊,很高兴,但是问题又来了,form表单提交后页面其实刷新了,如果不符合导出条件我该怎么提示用户呢?新跳转一个页面吗?感觉这样不太合适,因为用户辛辛苦苦输入了半天的条件,然后等了半天后台校验(涉及到大数据量),结果等来的是跑到另一个页面跟你说不能导出,如果是我我会崩溃的,等了半天不说,奶奶个腿,我输入半天的查询条件还得重新输入,这个不能忍。。好吧,这种方法不行,然后试着从后台往jsp页面写脚本,但是也发现根本不执行,也就纳闷了,最后,网上有一位小伙伴说用一个iframe的隐藏域,如果不符合条件的话,再用流的方式将问题写回来,最终问题解决了(代码将会统一贴在下面)。

  3、这样感觉很完美了,但是问题还没有完全解决,还有一个禁用按钮的问题,这个问题想想很简单,用户点击导出时将按钮禁用,导出完成后传回来一个标志,然后再将按钮放开,但是问题来了,这个标志怎么穿回来?一开始我想当然的想和错误提示一样的结局方案,发现不行因为,我导出Excel已经将response流给用掉了,我不可能在用流的方式将标志写回来了。这样就会导致我放不开导出按钮,那老板就不同意了,加班加点的找方法。终于,让我找到了一个解决思路,用cookie来做。具体思路就是:用户点击导出后,禁用按钮,然后js写个定时器轮训找cookie,在将文件流写出后,我会放一个cookie在浏览器中,那么此时js就能找到这个cookie了,找到后,首先将定时器给干掉,再将cookie给干掉(有点过河拆桥的感觉,哈哈),然后将导出按钮给放开。

  (虽然问题解决了,但是cookie和定时器轮训还是有一点不靠谱,希望大家有更好的解决方法,请大家不吝赐教,谢谢!!!)

  前台代码:

<button class="btn btn-sm btn-success" type="submit" id="detailEp" οnclick="return exportCheck(true);" forbid="yes"><i class="icon-arrow-right bigger-110"></i> 导出
</button>
<script>
$(function() {var timer = "";
});//点击导出按钮时禁用导出按钮
$("#myForm").submit(function() {$("button[type=submit]",this).attr("disabled","disabled");//提交导出后定时去查看有没有导出成功timer = setInterval(refrashPg,1000);
})//导出成功后会放开导出按钮的禁用
function refrashPg() {if (getCk() =="1") {clearInterval(timer);$("#detailEp").removeAttr("disabled");}delCk();
}
//js获取到cookie
function getCk() {debuggervar ck = document.cookie.split(";"); var ckname = "";for (var i = 0;i<ck.length;i++) {var arr = ck[i].split("=");if (arr[0] =="updtstatus") {ckname = arr[1];break;}}return ckname;
}
//js删除掉cookie
function delCk() {var exp = new Date(); var name = "updtstatus";exp.setTime(exp.getTime()-1000);var cval = getCk();document.cookie = name  + "=" + cval + "; expires=" + exp.toGMTString();
}
}
</script>

  后台导出代码就是普通的Java POI代码:

1 public void buildExcelDocument(Map<String, Object>obj,String fileName,String type,2 HttpServletRequest request, HttpServletResponse response)3             throwsException {4         HSSFWorkbook workbook = newHSSFWorkbook();5         if ("1".equals(type)) {6             List<Map<String, Object>> contentList =  (List<Map<String, Object>>) obj.get("content");7             HSSFSheet sheet = workbook.createSheet("sheet1");//创建Excel的版本是2003-2007(xls) 如果需要2010的话,用 XSSFSheet
8             Map<String,String>  titleList = (Map<String, String>) obj.get("title");9             //表头的key 对应内容listMap中的map的key
10             List<String> mkey = new ArrayList<String>();11             //表头的value 表头
12             List<String> mvalue = new ArrayList<String>();13             Iterator<Entry<String, String>> it =titleList.entrySet().iterator();14             while(it.hasNext()){15                 @SuppressWarnings("rawtypes")16                 java.util.Map.Entry entry =(java.util.Map.Entry)it.next();17 mkey.add((String) entry.getKey());18 mvalue.add((String) entry.getValue());19 }20             sheet.setDefaultColumnWidth((short) 12);21             HSSFCell cell = null;22             for (int i = 0;i<mvalue.size();i++) {23                 cell = getCell(sheet, 0, i);24 setText(cell, mvalue.get(i));25 }26
27             for (short i = 0; i < contentList.size(); i++) {28                 HSSFRow sheetRow = sheet.createRow(i+1);29                 Map<String, Object> entity =contentList.get(i);30                 for (int j = 0;j< mkey.size();j++) {31                         if (entity.get(mkey.get(j)) instanceofString) {32 sheetRow.createCell(j).setCellValue((String)entity.get(mkey.get(j)));33                         } else if (entity.get(mkey.get(j)) instanceofDouble) {34 sheetRow.createCell(j).setCellValue((Double)entity.get(mkey.get(j)));35                         } else if (entity.get(mkey.get(j)) instanceofDate){36                             String date =(entity.get(mkey.get(j))).toString();37                             sheetRow.createCell(j).setCellValue(date.substring(0, 10));38                         } else if (entity.get(mkey.get(j)) instanceofBigDecimal){39 sheetRow.createCell(j).setCellValue((entity.get(mkey.get(j))).toString());40 }41 }42 }43 }44         } else if ("2".equals(type)) {45             List<String[]> contentList =  (List<String[]>) obj.get("content");46             HSSFSheet sheet = workbook.createSheet("sheet1");47             String[]  titleList = (String[]) obj.get("title");48             HSSFCell cell = null;49             for (int i = 0;i<titleList.length;i++) {50                 cell = getCell(sheet, 0, i);51 setText(cell, titleList[i]);52 }53             for (short i = 0; i < contentList.size(); i++) {54                 HSSFRow sheetRow = sheet.createRow(i+1);55                 String[] detail =contentList.get(i);56                 for (int j = 0;j< detail.length;j++) {57 sheetRow.createCell(j).setCellValue((String)contentList.get(i)[j]);58 }59 }60 }61
62        //设置下载时客户端Excel的名称
63         String filename = fileName + ".xls";64       //处理中文文件名
65         filename =Chineseutil.encodeFilename(filename, request);66         response.setContentType("application/Vnd.ms-excel;charset=UTF-8");67         response.setHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes("gb2312"), "iso8859-1"));68         OutputStream ouputStream =response.getOutputStream();69 workbook.write(ouputStream);70
71         //导出数据后将信息存入cookie
72      Cookie status = new Cookie("updtstatus", "1");73       status.setMaxAge(3600);//设置cookie存活时间1个小时
74 response.addCookie(status);75
76 ouputStream.flush();77 ouputStream.close();78     }

View Code

转载于:https://www.cnblogs.com/bdss/p/6295743.html

Java 导出Excel的各种尝试相关推荐

  1. java文件无法导出excel文件,【excel表格文件格式无效】java导出excel,excel打不开,报文件格式无效,怎么解决!...

    excel提示 打开的文件.xls的格式与文件扩展名不一致怎么办 如果打开文件的格式与文件的扩展名不一致,只要能够打开就不用去管他. java导出excel,excel打不开,报文件格式无效,怎么解决 ...

  2. java 导出excel到多个sheet

    java 导出excel 多个sheet 废话不多说了,直接上代码,有需要的盆友,可以看看.@TOC @RequestMapping("/exportAllyScoreCount" ...

  3. java导出excel无法打开

    如果你在使用 Java 导出 Excel 文件但是打开后出现了无法打开的问题,可能是出现了以下几种情况: 文件损坏:Excel 文件在生成和传输过程中可能已损坏,导致无法打开. 版本问题:生成的 Ex ...

  4. java导出excel设置行高列宽_使用POI生成Excel文件,可以自动调整excel列宽

    //autoSizeColumn()方法自动调整excel列宽 importjava.io.FileOutputStream; importorg.apache.poi.hssf.usermodel. ...

  5. java导出excel文件名_怎么解决java导出excel时文件名乱码

    怎么解决java导出excel时文件名乱码 发布时间:2020-06-19 16:59:00 来源:亿速云 阅读:137 作者:元一 java解决导出Excel时文件名乱码的方法示例:String a ...

  6. java 导出excel教程_Java导出Excel表格

    Java导出Excel表格 导出Excel表格需要一个poi-3.9.jar的包,该包在网上可以找到. 第一步,创建Excel对象. HSSFWorkbook workbook = new HSSFW ...

  7. java 浏览器 excel导出excel_使用Java导出Excel表格并由浏览器直接下载——基于POI框架...

    非异步方法 /** * 使用Java导出Excel表格并由浏览器直接下载--基于POI框架 * * @param response * @return * @throws IllegalAccessE ...

  8. Java 导出excel进行换行

    java 导出Excel进行换行 String.valueOf((char)10) 在导出excel 的时候,如果原始文字中含有 \n 字符, 如果把 \n 替换为<br/>,excel不 ...

  9. java导出Excel(POI模式 Ajax下载 Post传参) bootstrap table getVisibleColumns获取显示的列

    工具类 (正式使用) package com.qyj.utils;import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson. ...

最新文章

  1. Lucene核心数据结构——FST存词典,跳表存倒排或者roarning bitmap 见另外一个文章...
  2. FreeRTOS 任务优先级分配方案
  3. Codewar-008: Playing with passphrases 玩玩加密口令
  4. Attribute 和 Parameter 的区别
  5. python 获取json后 dict列表形式输出结果
  6. 扇贝有道180924每日一句
  7. 华为服务器开机启动项怎么设置_华为服务器怎么设置u盘启动
  8. 超方便快捷搜索的油猴插件
  9. 动态添加、删除文本框
  10. raise notice oracle,openGauss 循序渐进:通过 raise notice 模拟 Oracle 的 DBMS_OUTPUT
  11. 【1024个人爆款文章】Android 安卓原生UI实现游戏《俄罗斯方块》,算法太多,把我写崩溃了,附源码
  12. RocketMq之削峰
  13. Lazy evaluation
  14. nodejs追加写入日志文件
  15. oracle sql查询取整,Oracle SQL语句操作数字:取整、四舍五入及格式化
  16. VA液晶屏底色发白是什么原因?
  17. 宝塔php memory_limit,优化宝塔面板提高网站运行速度教程
  18. 计算机专业十六字口号,大学运动会十六字口号(精选50句)
  19. uniapp 点击按钮跳转到当前应用的App Store中
  20. 2013北邮网研机试

热门文章

  1. 三步搞定android应用底部导航栏
  2. PAT1003. 我要通过!
  3. C++知识整理 内存模型和命名空间
  4. 电子助力方向机控制模块_【技师投稿】使用道通MS908PRO更换宝马F20底盘方向机...
  5. pc工具不支持stb的加密方式_那些工作中常用的实用工具
  6. Ansible(六)对目标主机进行磁盘分区,创建逻辑卷、格式化并挂载
  7. 小猿圈python视频_小猿圈python学习-格式化打印
  8. adb指令通过uid控制_图文教程:PC利用adb工具通过CMD命令控制手机动作(备忘笔记)...
  9. 巴里克黄金CEO:加密货币并不是比黄金更好的价值储存方式
  10. Globe宣布将在Balancer拍卖14,000,000枚GDT代币