代码渣渣一枚,最近在实习(主要是javaweb后端),在实习期间,写了一点网页下载excel表格的代码,趁着现在对他还有印象,记录下来,方便以后用。第一次写博客,一定会很差,各位看官不要见怪!!废话就不多说了,下面正式开始介绍。
实现功能:网页点击下载,将参数传到后端,根据参数查询数据库,将查到的数据导入excel表,并返回前端下载。
实现上述功能大体分为以下几步:
一.查询数据库
这部分用spring框架实现,代码十分简单,不再赘述。由于我的功能实现中查询到的数据很多条,因此将查询到的数据封装到ArrayList中,ArrayList中的元素是预先定义好的bean。
二.生成excel
这部分用的是jxl的WritableWorkbook生成excel,网上说poi也可以,查了一下,各有优缺点,poi效率高,但当写入大量数据时,消耗内存大。用WritableWorkbook生成excel表格主要分为以下几步:
1.从配置文件中读取path和filename
这样做的好处是当要更改excel文件的存放地址,直接在配置文件中更改,不用改动程序。另外,path和filename最好不好出现中文,避免乱码,同时也显得更加专业。据说出现中文会被批不专业甚至被boss骂。
另外,path=配置文件中读取的固定路径+程序中年月日生成的可变路径,这样做的好处是每天生成一个文件夹,用于存放今天下载的excel表格。方便管理和查找,同时也避免了大量的excel表格都存放在同一个文件夹中,增加查找困难。同理,为了区分不同的将要下载的excel表,filename=配置文件中读取的固定exccel文件名+程序中小时分钟生成的可变文件名+“.xls”,这样做可以使同一天内的excel文件名保持不相同。
生成年月日的可变路径的代码如下:
java代码
1 public static String getRelativeDir() {
2 //Date d = new Date();
3 Calendar calendar = Calendar.getInstance();
4 SimpleDateFormat s=new SimpleDateFormat("yyyy-MM-dd");
5 String curDate = s.format(calendar.getTime()); //当前日期
6 return curDate;
7 }
生成小时分钟的可变文件名的代码如下:
java代码
1 public static String hourMinuteStr() {
2 Calendar cal = Calendar.getInstance();
3 //当前小时数
4 int time = cal.get(Calendar.HOUR_OF_DAY);
5 // 当前分钟数
6 int MINUTE = cal.get(Calendar.MINUTE);
7 String randomnum = time+""+MINUTE;
8 //如果月份为7转变为07
9 return randomnum.length()==3?"0"+randomnum:randomnum;
10 }
2.创建WritableWorkbook
在生成path和filenme后,就可以创建一个WritableWorkbook生成excel
java代码
1 //以file为文件名来创建一个Workbook
2 File file = new File(path+"/"+filename);
3 WritableWorkbook wwb = Workbook.createWorkbook(file);
4 // 创建工作表
5 WritableSheet ws = wwb.createSheet("Test Shee 1", 0);
3.设置excel表的格式
如果不设置excel表的格式,excel将使用默认的格式。在最初,我并没有设置excel表格的格式,然后发现excel表格不美观,因此添加了设置excel表格格式的代码。
java代码
1 //给sheet电子版中所有的列设置默认的列的宽度;
2 ws.getSettings().setDefaultColumnWidth(10);
3 //给某一列设置特殊的宽度
4 ws.setColumnView(4, 20);
5 //设置字体;
6 WritableFont font1 = new WritableFont(WritableFont.ARIAL,9,WritableFont.BOLD,false,UnderlineStyle.NO_UNDERLINE,Colour.BLACK);
7 WritableCellFormat cellFormat1 = new WritableCellFormat(font1);
8 //设置文字居中对齐方式; cellFormat1.setAlignment(jxl.format.Alignment.CENTRE);
9 // 设置边框线
10 cellFormat1.setBorder(Border.ALL, BorderLineStyle.THIN);
11 //设置背景颜色
12 cellFormat1.setBackground(jxl.format.Colour.YELLOW);
13 //设置自动换行;
14 cellFormat1.setWrap(true);
15 //设置垂直居中;
16 cellFormat1.setVerticalAlignment(VerticalAlignment.CENTRE);
4.生成excel表中的lable
设置了excel表格的样式后,就可以生成excel表格的元素了
java代码
1 //要插入到的Excel表格的列号,默认从0开始
2 Label label_serilaNum= new Label(0, 0, "序号",cellFormat1);
3 //表示第1行第2列的值
4 Label label_createdBy= new Label(1, 0, "负责人",cellFormat1);
5 Label label_province= new Label(2, 0, "区域",cellFormat1);
6 ws.addCell(label_serilaNum);
7 ws.addCell(label_createdBy);
8 ws.addCell(label_province);
如果不需要设置excel表的格式,在new Lable中去掉cellFormat1就可以了,这样excel会选择默认的格式
我们上面说到,从数据库中查到的信息是存放在ArrayList中,上面的代码只是生成了表格的标题行,ArrayList中存储的信息并没有添加到excel表格中,添加ArrayList中的信息到excel表格中,只需要遍历ArrayList,像上面的代码一样,将ArrayList中的信息填写在对应的label中就可以了。注意判断ArrayList是否为null,否者系统会抛出错误
5.写/关文档
在将ArrayList中的信息写入excel后,还需要完成以下两步
java代码
1 //写进文档
2 wwb.write();
3 // 关闭Excel工作簿对象
4 wwb.close();
三.将生成的excel表格的文件路径和文件名返回给前端
在上述excel文件生成后,将文件的路径和文件名返回给前端,这就完成了网页下载表格的一大半。另外需要注意的是,返回的路径最好不要是绝对路径,应该为相对路径。此处返回的路径=“/”+程序生成的年月日可变文件夹;这样做的好处是下载请求端不知道存放文件的具体位置,确保了文件的安全。
四.网页弹出下载excel文件的对话框
实现网页下载excel还需要最后一步:接收参数filename和filepath,这两个参数是第三步中传给前端的文件路径(相对)和文件名,为什么要如此麻烦,后端直接下载不更加简洁?这是因为这样可以确保当前用户还是发出下载请求的用户,而不是其他的用户;另外还可以再次确认下载的excel是哪一个。
1.检查文件路径和文件名称是否存在
在接收到前端传来的filename和filepath时,第一步做的是检测文件路径和文件名称是否存在,如果存在才进行下一步的下载,否则不下载。
java代码
1 //检查文件路径
2 BaseResponse baseResponse = new BaseResponse();
3 String loadDir=loadDir_prefix+filepath;
4 File exceldir=new File(loadDir);
5 if(!exceldir.isDirectory()) {
6 baseResponse.setMsg("待下载的文件路径不对,请输入正确的路径");
7 baseResponse.setCode(ResponseCode.PARAMETER_ERROR);
8 return baseResponse;
9 }
10 //检查文件
11 String path=loadDir+"/"+filename;
12 File file = new File(path);
13 if(!file.exists()) {
14 baseResponse.setMsg("待下载的文件不存在,请输入正确的文件名");
15 baseResponse.setCode(ResponseCode.PARAMETER_ERROR);
16 return baseResponse;
17 }
注意:前端传回的路径是相对路径(由年月日生成的文件夹),这样做的好处前面已经提到了。
2.使用HttpServletResponse下载excel文件
文件路径和文件检查通过后,使用HttpServletResponse下载文件
1 String filenametemp=filename.substring(filename.length()-8, filename.length()-4);
2 //设置excel文件名
3 response.setHeader("Content-Disposition", "attachment; filename=" +URLEncoder.encode("eSIM芯片管理平台消息预警查询及导出", "utf-8")+ "["+URLEncoder.encode("表样","utf-8")+"]"+filenametemp+".xls");
4 //4.获取要下载的文件输入流
5 InputStream in = new FileInputStream(new File(filepath+"/"+filename));
6 int len = 0;
7 //5.创建数据缓冲区
8 byte[] buffer = new byte[1024];
9 //6.通过response对象获取OutputStream流
10 OutputStream out = response.getOutputStream();
11 //7.将FileInputStream流写入到buffer缓冲区
12 while ((len = in.read(buffer)) > 0) {
13 //8.使用OutputStream将缓冲区的数据输出到客户端浏览器
14 out.write(buffer,0,len);
15 }
16 in.close();
17 out.flush();
18 response.flushBuffer();//不可少
19 out.close();
20 }
上诉代码中的filenametemp是获取的由小时分钟生成的相对文件名。另外上诉也提到了,excel的文件名是英文,但在response.setHeader中设置的文件名与传到前端的文件名不相同,这样做是没有问题的。response.setHeader参数中的文件名才是excel最后的下载名,之前叫什么完全没有关系。对于response.setHeader中的filename还有一点需要注意的是如果文件名是中文,需要utf-8进行编码,否则会出现乱码,特殊字符(如[ ] @等)不能进行utf-8编码,编码反而会导致出现乱码,直接将特殊字符添加在文件中就可以了。
最后的最后,response.setHeader要在检查文件路径和文件名之后再进行设置,因为一旦设置response.setHeader就意味着网页一定会弹出下载的对话框,哪怕文件名和文件路径都不存在。
结束语:
第一次写博客,写的不好大家多多见谅,同时也希望自己能够坚持下去。