跳坑留下的伤疤都是我们程序员最好的勋章。
文件导出是在web项目中常用的功能之一。在这里我也谈一下本人的拙见。
此次我遇到的是从easyUI框架中查询数据的导出,当然,不管框架怎么变,万变不离其宗,导出功能学懂一个就差不多够用了。
这里我的前台查询条件是name和age。先查询,前台看到信息后,才可以导出。
按照我找博客的习惯,直接上代码。
后台导出方法:
/*
* 导出文件方法
*/
@SuppressWarnings("unchecked")
@RequestMapping(value = "/getfile.do")
public @ResponseBody void getfile (HttpServletRequest request,HttpServletResponse response) throws IOException {
String data1= request.getParameter("data");
List<String> userIdList = JSON.parseArray(data1, String.class);
List<SPSSUserIdTemporaryTable> UserIdlist = new ArrayList<SPSSUserIdTemporaryTable>();
spssCustomerService.createUserIdTemporaryTable(UserIdlist);
String Name=request.getName("Name");
String Age=request.getAge("Age");
//调用查询方法,拿到数据。(可以封装前台使用的查询方法,共用一个,防止页面显示和导出数据不一致)
List<CustomerEnterpriseData> dataList = selectEnterprise(Name,Age);
try {
//List dataList = dao.getData(bean);
String[] sheet = new String[2];
sheet[0] = "个人信息表"; //工作区名称
sheet[1] = "个人信息统计表"; //标题名称
//字段自己根据数据长度实际情况设置
//设置字段及字段宽度(类型暂定为2,以后可扩展)
//设定列名、列宽
String[][] field = new String[][]{
{"维度", "车险数量"}
,{"5000", "5000"}};
List<List> datas = new ArrayList();
//为了通用性,不能直接设置对象,所以内嵌List集合
for(CustomerEnterpriseData b : dataList){
List contents = new ArrayList();//存储对象属性数据
contents.add(b.getName());
contents.add(b.getAge());
datas.add(contents);//添加到数据集合里
}
PoiBuildExcel pbe = new PoiBuildExcel(sheet, field, datas);
HSSFWorkbook workbook = pbe.exportExcel();
response.reset();
response.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
String disposition = "attachment;filename="+java.net.URLEncoder.encode("person.xls", "UTF-8");
response.setHeader("Content-Disposition", disposition);// 设定输出文件头
response.setContentType("application/msexcel"); // 设定输出类型
ByteArrayOutputStream baos = new ByteArrayOutputStream();
workbook.write(baos);
baos.flush();
byte[] aa = baos.toByteArray();
InputStream is = new ByteArrayInputStream(aa, 0, aa.length);
// 得到响应对象的输出流,用于向客户端输出二进制数据
ServletOutputStream sos = response.getOutputStream();
byte[] data = new byte[2048];
int len = 0;
while ((len = is.read(data)) > 0) {
sos.write(data, 0, len);
}
is.close();
sos.close();
baos.close();
} catch (Exception e) {
e.printStackTrace();
}
前端jsp代码:
<a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-export" οnclick="export_exl()" >导出</a>
<form id="fm_excel_export" method="post" >
<input type = "hidden" id = "hd_excel_data" name = "data" >
<input type = "hidden" id = "Name1" name = "Name" >
<input type = "hidden" id = "Age1" name = "Age" >
</form>
前端导出按钮触发的方法:
function export_exl(){
var data = JSON.stringify($('#dg').datagrid('getRows'));
var Name=$("#Name").combobox("getValue");
var Age=$("#Age").combobox("getValue");
var userIdListJson = [];
$($("#cc").combotree("tree").tree("getChecked")).each(function(i,n){
if ($(this).tree('isLeaf', n.target)) {
userIdListJson.push(n.id);
}
})
if (userIdListJson.length === 0){
var userId = $("#userId").val();
userIdListJson.push("a");
}
userIdListJson = JSON.stringify(userIdListJson);
if(data.length>2){
$('#hd_excel_data') .val(userIdListJson) ;
$("#Name1").val(Name);
$("#Age1").val(Age);
$('#fm_excel_export').form({
url:"../spss/getfile.do",
onSubmit: function(){
},
success:function(data){
}
});
$('#fm_excel_export').submit();
return;
}else{
alert("请先进行查询操作!");
return;
}
}
可能代码有些地方比较多余,是因为有些代码的私密性,从而进行了一定程度的修改,忘大家见谅。
这里面源码对操作做了很多的判断等等,希望大家看的时候多理解一下。
我在这里遇到的问题是:
1、第一次是采用前台传递json串给后台进行解析,然后写入Excel表文件,但是后来发现当前台数据量大的时候,就会出现错误,因此才会封装调用前台的查询方法,直接从数据库拿取数据。
2、from表单提交不会刷新。刚开始没有手动写入,所以在form表单提交一次后,就算是我改变了查询条件,导出来的数据也不会再改变,所以迫于无奈选择了将查询条件手动写入form表单。
总结不好,请多多包涵!如有更好的见解,愿洗耳恭听!