使用jxl,Servlet,JSP 动态生成excel文件并提示下载的简单方法

来源:互联网 发布:人民日报数据库账号 编辑:程序博客网 时间:2024/04/30 05:03

1.下载jxl.rar包

项目地址:http://www.andykhan.com/jexcelapi/
下载地址:http://www.andykhan.com/jexcelapi/download.html

2.把包放到WEB-INF的lib目录下在开发环境中引入这个包

3.开始写代码了,这里以一个Struts1.2的ActionMethod为例,其实只要能取了request和response对象,操作都是一样的的

 /** *//**
 2     * 生成信息的XLS
 3     * alex 2007-7-3 下午05:01:56
 4     */
 5    public ActionForward makeRichVoteRZ(ActionMapping mapping, ActionForm form,
 6            HttpServletRequest request, HttpServletResponse response)
 7            throws Exception {
 8       
 9        //读出数据
10        String richvote_id = Common.getValue("richvote_id", request);
11        String sql = "select user_name,user_sex,user_address,card_id,postalcode,mobile,tel_day,email from tbl_member where member_id in (select user_id from tbl_vote_detail where vote_id in(select vote_id from tbl_vote where vote_board = '"+richvote_id+"'))";
12        RowSet rs = table.select(sql);
13       
14        //生成xls
15        try{
16           
17            response.setContentType("application/vnd.ms-excel");
18            response.addHeader("Content-Disposition","attachment;   filename=/""   +  Common.getFileName()+".xls"  +   "/"");   
19            OutputStream os = response.getOutputStream();
20            WritableWorkbook wwb = Workbook.createWorkbook(os);
21           
22           
23            int ncout = rs.length();
24            int maxnum = 50000; //一次最多写入量
25            int times = (ncout+maxnum-1)/maxnum;
26           
27            //大循环
28            for(int t=0; t<times; t++){
29               
30                //新建一张表
31                WritableSheet wsheet = wwb.createSheet("members_"+(t+1),t);
32                //设置表头
33                Label label = new Label(0,0,"");
34                wsheet.addCell(label);
35                label = new Label(0,0,"会员姓名");
36                wsheet.addCell(label);
37                label = new Label(1,0,"卡号");
38                wsheet.addCell(label);
39                label = new Label(2,0,"联系地址");
40                wsheet.addCell(label);
41                label = new Label(3,0,"邮编");
42                wsheet.addCell(label);
43                label = new Label(4,0,"联系电话");
44                wsheet.addCell(label);
45                label = new Label(5,0,"手机");
46                wsheet.addCell(label);
47                label = new Label(6,0,"Email");
48                wsheet.addCell(label);
49                label = new Label(7,0,"性别");
50                wsheet.addCell(label);
51               
52               
53                //读出数据
54                int base = (t*maxnum);
55                for(int i = 0; i < rs.length(); i++){
56                    Row rw = rs.get(i+base);
57                    //System.out.println((i+1));
58                    label = new Label(0,(i+1),(String)rw.get("user_name")    );
59                    wsheet.addCell(label);
60                    label = new Label(1,(i+1),(String)rw.get("card_id"));
61                    wsheet.addCell(label);
62                    label = new Label(2,(i+1),(String)rw.get("user_address"));
63                    wsheet.addCell(label);
64                    label = new Label(3,(i+1),(String)rw.get("postalcode"));
65                    wsheet.addCell(label);
66                    label = new Label(4,(i+1),(String)rw.get("tel_day"));
67                    wsheet.addCell(label);
68                    label = new Label(5,(i+1),(String)rw.get("mobile"));
69                    wsheet.addCell(label);
70                    label = new Label(6,(i+1),(String)rw.get("email"));
71                    wsheet.addCell(label);
72                    label = new Label(7,(i+1),(String)rw.get("user_sex"));
73                    wsheet.addCell(label);
74                }   
75               
76            }//结束大循环
77           
78            wwb.write();
79            wwb.close();
80            os.close();
81            response.flushBuffer();
82           
83        }catch(Exception e){
84            System.out.println("生成信息表(Excel格式)时出错:");
85            e.printStackTrace();
86        }
87       
88        return null;
89    } 

 

根据项目需求,需要在页面动态到处excel文件。导出excel主要有两类方法:
(1)使用POI,JXL的API自己写。
(2)使用列表组件,如displaytag,ecside等。
我试着用了jxl和displaytag。不难,挺好玩的。且记些资料、心得在这里。
(1)用jxl API
jxl的doc很完善,尤其是里面的demo,简单的应用参考demo的相关文件,就可照猫画虎。在struts+spring+hibernate的架构中,可以定义一个非持久化类,用来存放包含若干字段的查询结果。jxl导出一个excel文件的步骤很reasonable。先根据输出流建立一个WritableWorkbook对象wwb;excel文件中的每一个sheet,在wwb中都对应一个WritableSheet对象,然后,对于每一个WritableSheet对象,再逐个填写cell数据。其间,可以根据填写内容的类型选择填写方式,还可以灵活的设置字体等格式信息。
倘若需求只要求客户点击“导出”时,弹出对话框,提示文件并下载,且此文件是动态生成,不用在服务器端事先保存的话,用jxl的API可以很方便灵活的实现。在http://www.blogjava.net/netnova/archive/2007/09/20/146776.html中有很好的例子。对于中文字符的文件名乱码问题,只需使用java中的一般解决办法,new String(filename.getBytes(),"iso8859-1");作为新的文件名即可。文件内容一般不会出现中文乱码。
(2)用displaytag
列表组件在实现excel导出时,也是用了POI或者JXL。使用列表组件有一个前提:就是无论列表显示还是excel文件导出,都要使用这个组件。这个对于只需导出文件的需求当然不适用。但如果要同时实现两项功能,且系统中没有专门的分页处理逻辑的话,使用列表组件是个不错的选择。我花了不多的时间试了试displaytag。对于action的编写,与一般的列表显示没什么区别,action要做的只是把要显示的对象信息一并放在request的attribute里。主要工作是在jsp页面中使用displaytag标签,把对应的信息按照一定的排列显示出来。它可以方便的设置需要导出哪些数据,到处文件的类型等。对于中文乱码问题,这里的解决就不似jxl那么简单了。我使用最新版本的displaytag,尽管用了它说的filter,但导出的文件内容中的中文字符还是乱码。看了下文档,说一般支持ascii码的excel导出。应该也支持非ascii码的导出吧。估计是我还没看得足够深入。不过,displaytag中提供的几个默认样式不错,在显示列表时可以省掉一些工作。