Java 导出Excel的各种尝试

  最近的一个项目比较忙,一直没时间过来跟新博客。今天过来分享一下在此项目中遇到的一个小问题:导出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" onclick="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() {
	debugger
	var 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             throws Exception {
 4         HSSFWorkbook workbook = new HSSFWorkbook();
 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)) instanceof String) {
32                             sheetRow.createCell(j).setCellValue((String)entity.get(mkey.get(j)));
33                         } else if (entity.get(mkey.get(j)) instanceof Double) {
34                             sheetRow.createCell(j).setCellValue((Double)entity.get(mkey.get(j)));
35                         } else if (entity.get(mkey.get(j)) instanceof Date){
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)) instanceof BigDecimal){
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     }

时间: 2024-10-23 10:33:45

Java 导出Excel的各种尝试的相关文章

实现java导出Excel表

实现java导出Excel表 1.项目需要导入的包 其中jxl.jar就是操作excel表的核心包,其他的包都是struts2的包 2.项目的结构 ExcelAction.java package com.jxl.action; import java.io.InputStream; import java.io.UnsupportedEncodingException; import com.jxl.service.ExcelServiceImpl; import com.jxl.servic

java 操作 Excel,java导出excel

WritableWorkbook out = null; try { response.getServletResponse().reset(); ((HttpServletResponse) response.getServletResponse()).setHeader("Content-Disposition", "attachment;filename=export.xls"); response.getServletResponse().setConten

Java导出Excel表(poi)名中文乱码问题处理

<pre name="code" class="java">String _filename = ValidateTools.date2Str(date, "yyyyMMddHHmmss"); String filename = f_name + _filename; HSSFSheet sheet; HSSFCell cell; response.setContentType("application/x-download

Java 通过Xml导出Excel文件,Java Excel 导出工具类,Java导出Excel工具类

Java 通过Xml导出Excel文件,Java Excel 导出工具类,Java导出Excel工具类 ============================== ?Copyright 蕃薯耀 2017年9月13日 http://www.cnblogs.com/fanshuyao/ 直接上代码: import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.ref

Java导出Excel三表头

1.问题背景 Java导出Excel表格时,表头出现了三个,即多表头Excel 2.实现源码 /** * * @Project:Report * @Title:ThreeHead.java * @Package:com.you.excel * @Description: * @Author:YouHaiDong * @Date:2015年11月4日 下午3:10:12 * @Version: */ package com.you.excel; import java.io.FileOutputS

Java POI 导出EXCEL经典实现 Java导出Excel弹出下载框

在web开发中,有一个经典的功能,就是数据的导入导出.特别是数据的导出,在生产管理或者财务系统中用的非常普遍,因为这些系统经常要做一些报表打印的工作.而数据导出的格式一般是EXCEL或者PDF,我这里就用两篇文章分别给大家介绍下.(注意,我们这里说的数据导出可不是数据库中的数据导出!么误会啦^_^) 呵呵,首先我们来导出EXCEL格式的文件吧.现在主流的操作Excel文件的开源工具有很多,用得比较多的就是Apache的POI及JExcelAPI.这里我们用Apache POI!我们先去Apach

java导出excel不需要额外jar包

目前我知道的在java中导出Excel可以用poi或在jsp的文件头改变输出流.下面再介绍一种就用java基础包导出的Excel.导出的格式形如: 源码如下: package csvExcel; import java.io.FileWriter; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java

Java学习之道:Java 导出EXCEL

1.Apache POI简介 Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程式对Microsoft Office格式档案读和写的功能. .NET的开发人员则可以利用NPOI (POI for .NET) 来存取 POI 的功能. 2.POI结构 HSSF - 提供读写Microsoft Excel XLS格式档案的功能. XSSF - 提供读写Microsoft Excel OOXML XLSX格式档案的功能. HWPF - 提供读写Microsoft

java导出excel报表

1.java导出excel报表: package cn.jcenterhome.util; import java.io.OutputStream;import java.util.List;import java.util.Map;import javax.servlet.http.HttpServletResponse;import jxl.Workbook;import jxl.format.Alignment;import jxl.format.Border;import jxl.for