smartupload and JExcel

Posted on 2007-04-07 17:15 它山の石 阅读(699) 评论(0)  编辑  收藏

编辑EXCEL一直用POI,忽然看见一个JExcel的文档,贴过来,以便后用
转自:http://www.blogjava.net/rosen
         最近遇到点读取 Excel 数据的问题,于是花了点时间找开源工具。
要解析 Excel,首当其冲的是上传文件,以前在项目里我们用 SmartUpload 进行上传,不过这个项目似乎已经停止开发了,于是在这里我使用 Apache Commons FileUpload,可以在 http://jakarta.apache.org/commons/fileupload 找到。目前该项目的最新版本是 1.1.1,网上有大量的范例程序,不过后来用的时候发现大部分方法在新版本中都不推荐使用了,于是好好读了一回 API 和官方范例。

先来看看如何上传文件,Servlet 很简单,在这里我限制了最大上传量为 1M,且直接读进内存中,不进行磁盘临时文件缓存。

  1import  java.io.IOException;
  2import  java.io.PrintWriter;
  3import  java.io.File;
  4import  java.net.URI;
  5import  java.net.URL;
  6
  7import  javax.servlet.ServletException;
  8import  javax.servlet.http.HttpServlet;
  9import  javax.servlet.http.HttpServletRequest;
 10import  javax.servlet.http.HttpServletResponse;
 11
 12import  java.util.List;
 13
 14import  org.apache.commons.fileupload.RequestContext;
 15import  org.apache.commons.fileupload.servlet.ServletRequestContext;
 16import  org.apache.commons.fileupload.servlet.ServletFileUpload;
 17import  org.apache.commons.fileupload.disk.DiskFileItemFactory;
 18import  org.apache.commons.fileupload.FileItem;
 19
 20public   class  UploadServlet  extends  HttpServlet {
 21
 22     /** 
 23     * Constructor of the object.
 24      */
 
 25     public  UploadServlet() {
 26         super ();
 27    }

 28
 29     /** 
 30     * Destruction of the servlet.
 31      */
 
 32     public   void  destroy() {
 33         super .destroy();
 34    }

 35
 36     public   void  doGet(HttpServletRequest request, HttpServletResponse response)
 37             throws  ServletException, IOException {
 38    }

 39
 40     /** 
 41     * 上传文件
 42     * 
 43     *  @param  request
 44     *  @param  response
 45     *  @throws  ServletException
 46     *  @throws  IOException
 47      */
 
 48     public   void  doPost(HttpServletRequest request, HttpServletResponse response)
 49             throws  ServletException, IOException {
 50        response.setContentType( " text/html " );
 51        response.setCharacterEncoding( " gbk " );
 52        PrintWriter out  =  response.getWriter();
 53        out.println( " <html> " );
 54        out.println( "   <head><title>提示</title></head> " );
 55        out.println( "   <body> " );
 56         //  不用获取 URL 对象也行,直接用 getServletContext().getRealPath("/") 代替。 
 57        URL url  =  getServletContext().getResource( " / " );
 58         //  从 HTTP servlet 获取 fileupload 组件需要的内容 
 59        RequestContext requestContext  =   new  ServletRequestContext(request);
 60         //  判断是否包含 multipart 内容 
 61         if  (ServletFileUpload.isMultipartContent(requestContext)) {
 62             //  创建基于磁盘的文件工厂 
 63            DiskFileItemFactory factory  =   new  DiskFileItemFactory();
 64             //  设置直接存储文件的极限大小,一旦超过则写入临时文件以节约内存。默认为 1024 字节 
 65            factory.setSizeThreshold( 1024   *   1024 );
 66             //  创建上传处理器,可以处理从单个 HTML 上传的多个上传文件。 
 67            ServletFileUpload upload  =   new  ServletFileUpload(factory);
 68             //  最大允许上传的文件大小 
 69            upload.setSizeMax( 1024   *   1024 );
 70             //  处理上传 
 71            List items  =   null ;
 72             try  {
 73                items  =  upload.parseRequest(requestContext);
 74                 //  由于提交了表单字段信息,需要进行循环区分。 
 75                 for  ( int  i  =   0 ; i  <  items.size(); i ++ ) {
 76                    FileItem fi  =  (FileItem) items.get(i);
 77                     //  如果不是表单内容,取出 multipart。 
 78                     if  ( ! fi.isFormField()) {
 79                         //  上传文件路径和文件、扩展名。 
 80                        String sourcePath  =  fi.getName();
 81                        String[] sourcePaths  =  sourcePath.split( " \\\\ " );
 82                         //  获取真实文件名 
 83                        String fileName  =  sourcePaths[sourcePaths.length  -   1 ];
 84                         //  创建一个待写文件 
 85                        File uploadedFile  =   new  File( new  URI(url.toString() + fileName));
 86                         //  写入 
 87                        fi.write(uploadedFile);
 88                        out.println(fileName + " 上传成功。 " );
 89                    }

 90                }

 91            }
  catch  (Exception e) {
 92                out.println( " 上传失败,请检查上传文件大小是否超过1兆,并保证在上传时该文件没有被其他程序占用。 " );
 93                out.println( " <br>原因: " + e.toString());
 94                e.printStackTrace();
 95            }

 96        }

 97        out.println( "   </body> " );
 98        out.println( " </html> " );
 99        out.flush();
100        out.close();
101    }

102
103     /** 
104     * Initialization of the servlet.
105     * 
106     *  @throws  ServletException
107      */
 
108     public   void  init()  throws  ServletException {
109    }

110}
 

上面的程序示范了如何上传文件到服务器,本文的主要目的不光是上传,还要进行 Excel 解析,抽取有用的内容。开源的 Excel 解析器很多,在此我选择了 JExcelApi,可以在 http://jexcelapi.sourceforge.net 找到,据说是韩国人开发的,最新版本是 2.6.2。为什么没有选 POI,原因也是因为它 N 久没有更新了。我总是喜欢最新的东东,比如 Adobe 的 PDF Reader,硬是下载了 8.0,结果感觉还没有 6.0 好用。:(

以下程序修改直上传,做了部分调整,取消了文件储存,直接通过读取输入流进行解析,并假设约定的 Excel 文件有五列 N 行,第一行为标题信息。

  1import  java.io.IOException;
  2import  java.io.PrintWriter;
  3
  4import  javax.servlet.ServletException;
  5import  javax.servlet.http.HttpServlet;
  6import  javax.servlet.http.HttpServletRequest;
  7import  javax.servlet.http.HttpServletResponse;
  8
  9import  java.util.List;
 10
 11import  org.apache.commons.fileupload.RequestContext;
 12import  org.apache.commons.fileupload.servlet.ServletRequestContext;
 13import  org.apache.commons.fileupload.servlet.ServletFileUpload;
 14import  org.apache.commons.fileupload.disk.DiskFileItemFactory;
 15import  org.apache.commons.fileupload.FileItem;
 16
 17import  jxl.Workbook;
 18import  jxl.Sheet;
 19import  jxl.Cell;
 20
 21public   class  UploadServlet  extends  HttpServlet {
 22        
 23     /** 
 24     * Constructor of the object.
 25      */
 
 26     public  UploadServlet() {
 27         super ();
 28    }

 29
 30     /** 
 31     * Destruction of the servlet.
 32      */
 
 33     public   void  destroy() {
 34         super .destroy();
 35    }

 36
 37     public   void  doGet(HttpServletRequest request, HttpServletResponse response)
 38             throws  ServletException, IOException {
 39    }

 40
 41     /** 
 42     * 上传文件
 43     * 
 44     *  @param  request
 45     *  @param  response
 46     *  @throws  ServletException
 47     *  @throws  IOException
 48      */
 
 49     public   void  doPost(HttpServletRequest request, HttpServletResponse response)
 50             throws  ServletException, IOException {
 51        response.setContentType( " text/html " );
 52        response.setCharacterEncoding( " gbk " );
 53        PrintWriter out  =  response.getWriter();
 54        out.println( " <html> " );
 55        out.println( "   <head><title>提示</title></head> " );
 56        out.println( "   <body> " );
 57         //  声明文件域 
 58        FileItem fileItem  =   null ;
 59         //  从 HTTP servlet 获取 fileupload 组件需要的内容 
 60        RequestContext requestContext  =   new  ServletRequestContext(request);
 61         //  判断是否包含 multipart 内容,如果不包含,则不进行任何处理。 
 62         if  (ServletFileUpload.isMultipartContent(requestContext)) {
 63             //  创建基于磁盘的文件工厂 
 64            DiskFileItemFactory factory  =   new  DiskFileItemFactory();
 65             //  设置直接存储文件的极限大小,一旦超过则写入临时文件以节约内存。默认为 1024 字节 
 66            factory.setSizeThreshold( 1024   *   1024 );
 67             //  创建上传处理器,可以处理从单个 HTML 上传的多个上传文件。 
 68            ServletFileUpload upload  =   new  ServletFileUpload(factory);
 69             //  最大允许上传的文件大小 
 70            upload.setSizeMax( 1024   *   1024 );
 71             try  {
 72                 //  处理上传 
 73                List items  =   null ;
 74                items  =  upload.parseRequest(requestContext);
 75                 //  由于提交了表单字段信息,需要进行循环区分。 
 76                 for  ( int  i  =   0 ; i  <  items.size(); i ++ ) {
 77                    FileItem fi  =  (FileItem) items.get(i);
 78                     //  如果不是表单内容,取出 multipart。 
 79                     if  ( ! fi.isFormField()) {
 80                        fileItem  =  fi;
 81                         // 一次只上传单个文件 
 82                         break ;
 83                    }

 84                }

 85                out.println(parseExcel(fileItem));
 86            }
  catch  (Exception e) {
 87                out.println( " 上传失败!请检查上传的文件是否为excel格式、信息是否完整完整、且大小是否超过1兆。 " );
 88                out.println( " <br>原因: " + e.toString());
 89                e.printStackTrace();
 90            }

 91        }

 92        out.println( "   </body> " );
 93        out.println( " </html> " );
 94        out.flush();
 95        out.close();
 96    }

 97
 98     /** 
 99     * 分析excel文件
100     * 
101     *  @param  FileItem fi 文件域
102     *  @return  String
103     *  @throws  Exception
104      */
 
105     private  String parseExcel(FileItem fi)  throws  Exception{
106         //  声明 Workbook 
107        Workbook workbook  =   null ;
108         try {
109            workbook  =  Workbook.getWorkbook(fi.getInputStream());
110            Sheet sheet  =  workbook.getSheet( 0 );
111             // 总行数 
112             int  count  =  sheet.getRows();
113             // 取出标题 
114              String a1  =  sheet.getCell( 0 , 0 ).getContents();
115              String a2  =  sheet.getCell( 1 , 0 ).getContents();
116              String a3  =  sheet.getCell( 2 , 0 ).getContents();
117              String a4  =  sheet.getCell( 3 , 0 ).getContents();
118              String a5  =  sheet.getCell( 4 , 0 ).getContents();
119             // 取出内容 
120             for ( int  i  =   1 ;i  <  count;i ++ ){
121                Cell[] cells  =  sheet.getRow(i);
122                System.out.println(cells[ 0 ].getContents()
123                         + cells[ 1 ].getContents() + cells[ 2 ].getContents()
124                         + cells[ 3 ].getContents() + cells[ 4 ].getContents());
125            }

126             return   " 上传成功。 " ;            
127        }
 catch (Exception e){
128             throw  e;
129        }
 finally {
130             if (workbook != null ){
131                workbook.close();
132            }

133        }

134    }

135    
136     /** 
137     * Initialization of the servlet.
138     * 
139     *  @throws  ServletException
140      */
 
141     public   void  init()  throws  ServletException {
142    }

143}
 
JExcelApi 用起来很简单,而且还可以根据 Excel 中数据类型转换成 Java 数据类型,比如 int、double,具体信息可以参考它的开发指南。当然,本范例还提供现构造 Excel 然后下载的方法,如果以后遇到,一定继续完善。

请注意!引用、转贴本文应注明原作者:Rosen Jiang 以及出处:http://www.blogjava.net/rosen

只有注册用户登录后才能发表评论。


网站导航: