smartupload and JExcel

          Posted on 2007-04-07 17:15 它山の石 閱讀(723) 評論(0)  編輯  收藏

          編輯EXCEL一直用POI,忽然看見一個JExcel的文檔,貼過來,以便后用
          轉(zhuǎn)自:http://www.aygfsteel.com/rosen
                   最近遇到點讀取 Excel 數(shù)據(jù)的問題,于是花了點時間找開源工具。
          要解析 Excel,首當其沖的是上傳文件,以前在項目里我們用 SmartUpload 進行上傳,不過這個項目似乎已經(jīng)停止開發(fā)了,于是在這里我使用 Apache Commons FileUpload,可以在 http://jakarta.apache.org/commons/fileupload 找到。目前該項目的最新版本是 1.1.1,網(wǎng)上有大量的范例程序,不過后來用的時候發(fā)現(xiàn)大部分方法在新版本中都不推薦使用了,于是好好讀了一回 API 和官方范例。

          先來看看如何上傳文件,Servlet 很簡單,在這里我限制了最大上傳量為 1M,且直接讀進內(nèi)存中,不進行磁盤臨時文件緩存。

            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 組件需要的內(nèi)容 
           59        RequestContext requestContext  =   new  ServletRequestContext(request);
           60         //  判斷是否包含 multipart 內(nèi)容 
           61         if  (ServletFileUpload.isMultipartContent(requestContext)) {
           62             //  創(chuàng)建基于磁盤的文件工廠 
           63            DiskFileItemFactory factory  =   new  DiskFileItemFactory();
           64             //  設置直接存儲文件的極限大小,一旦超過則寫入臨時文件以節(jié)約內(nèi)存。默認為 1024 字節(jié) 
           65            factory.setSizeThreshold( 1024   *   1024 );
           66             //  創(chuàng)建上傳處理器,可以處理從單個 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                 //  由于提交了表單字段信息,需要進行循環(huán)區(qū)分。 
           75                 for  ( int  i  =   0 ; i  <  items.size(); i ++ ) {
           76                    FileItem fi  =  (FileItem) items.get(i);
           77                     //  如果不是表單內(nèi)容,取出 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                         //  創(chuàng)建一個待寫文件 
           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 解析,抽取有用的內(nèi)容。開源的 Excel 解析器很多,在此我選擇了 JExcelApi,可以在 http://jexcelapi.sourceforge.net 找到,據(jù)說是韓國人開發(fā)的,最新版本是 2.6.2。為什么沒有選 POI,原因也是因為它 N 久沒有更新了。我總是喜歡最新的東東,比如 Adobe 的 PDF Reader,硬是下載了 8.0,結(jié)果感覺還沒有 6.0 好用。:(

          以下程序修改直上傳,做了部分調(diào)整,取消了文件儲存,直接通過讀取輸入流進行解析,并假設約定的 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 組件需要的內(nèi)容 
           60        RequestContext requestContext  =   new  ServletRequestContext(request);
           61         //  判斷是否包含 multipart 內(nèi)容,如果不包含,則不進行任何處理。 
           62         if  (ServletFileUpload.isMultipartContent(requestContext)) {
           63             //  創(chuàng)建基于磁盤的文件工廠 
           64            DiskFileItemFactory factory  =   new  DiskFileItemFactory();
           65             //  設置直接存儲文件的極限大小,一旦超過則寫入臨時文件以節(jié)約內(nèi)存。默認為 1024 字節(jié) 
           66            factory.setSizeThreshold( 1024   *   1024 );
           67             //  創(chuàng)建上傳處理器,可以處理從單個 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                 //  由于提交了表單字段信息,需要進行循環(huán)區(qū)分。 
           76                 for  ( int  i  =   0 ; i  <  items.size(); i ++ ) {
           77                    FileItem fi  =  (FileItem) items.get(i);
           78                     //  如果不是表單內(nèi)容,取出 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             // 總行數(shù) 
          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             // 取出內(nèi)容 
          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 用起來很簡單,而且還可以根據(jù) Excel 中數(shù)據(jù)類型轉(zhuǎn)換成 Java 數(shù)據(jù)類型,比如 int、double,具體信息可以參考它的開發(fā)指南。當然,本范例還提供現(xiàn)構(gòu)造 Excel 然后下載的方法,如果以后遇到,一定繼續(xù)完善。

          請注意!引用、轉(zhuǎn)貼本文應注明原作者:Rosen Jiang 以及出處:http://www.aygfsteel.com/rosen

          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導航:
           
          主站蜘蛛池模板: 崇仁县| 永平县| 双城市| 宁都县| 新河县| 岳池县| 华蓥市| 正安县| 且末县| 灵武市| 河西区| 固原市| 平塘县| 广平县| 翁牛特旗| 来安县| 平原县| 汕尾市| 常州市| 石台县| 密云县| 温泉县| 河南省| 林西县| 凤翔县| 郓城县| 铁岭县| 边坝县| 建瓯市| 当雄县| 林口县| 犍为县| 乌审旗| 儋州市| 秦皇岛市| 宜宾县| 青神县| 玉溪市| 吉木萨尔县| 原平市| 泰州市|