posts - 5,  comments - 7,  trackbacks - 0
          Microsoft的Office系列產品擁有大 量的用戶,Word、Excel也成為辦公文件的首選。在Java中,已經有很多對于Word、Excel的開源的解決方案,其中比較出色的是 Apache的Jakata項目的POI子項目。該項目的官方網站是http://jakarta.apache.org/poi/。
          POI 包括一系列的API,它們可以操作基于MicroSoft OLE 2 Compound Document Format的各種格式文件,可以通過這些API在Java中讀寫Excel、Word等文件。POI是完全的Java Excel和Java Word解決方案。POI子項目包括:POIFS、HSSF、HDF、HPSF。表7-2對它們進行了簡要介紹。
          表7-2  POI子項目介紹
          子項目名
          說明
          POIFS(POI File System)
          POIFS是POI項目中最早的最基礎的一個模塊,是Java到OLE 2 Compound Document Format的接口,支持讀寫功能,所有的其他項目都依賴與該項目。
          HSSF(Horrible Spreadsheet Format)
          HSSF是Java到Microsoft Excel 97(-2002)文件的接口,支持讀寫功能
          HWPF(Horrible Word Processing Format)
          HWPF是Java到Microsoft Word 97文件的接口,支持讀寫功能,但目前該模塊還處于剛開始開發階段,只能實現一些簡單文件的操作,在后續版本中,會提供更強大的支持
          HPSF(Horrible Property Set Format)
          HPSF 是Java到OLE 2 Compound Document Format文件的屬性設置的接口,屬性設置通常用來設置文檔的屬性(標題,作者,最后修改日期等),還可以設置用戶定義的屬性。HPSF支持讀寫功能,當前發布版本中直支持讀功能。
          7.3.1  對Excel的處理類
          下 面通過HSSF提供的接口對Excel文件經行處理。首先需要下載POI的包,可以到apache的官方網站下載,地址為:http: //apache.justdn.org/jakarta/poi/,本書采用的是poi-2.5.1-final-20040804.jar,讀者可以 下載當前的穩定版本。把下載的包按照前面介紹的方式加入Build Path,然后新建一個ch7.poi包,并創建一個ExcelReader類。
          ExcelReader類可以讀取一個XLS文件,然后將其內容逐行提取出來,寫入文本文件。其代碼如下。
          java 代碼
          1. public class ExcelReader{   
               
               
            // 創建文件輸入流   
               
               
            private BufferedReader reader = null;   
               
               
            // 文件類型   
               
               
            private String filetype;   
               
               
            // 文件二進制輸入流   
               
               
            private InputStream is = null;   
               
               
            // 當前的Sheet   
               
               
            private int currSheet;   
               
               
            // 當前位置   
               
               
            private int currPosition;   
               
               
            // Sheet數量   
               
               
            private int numOfSheets;   
               
               
            // HSSFWorkbook   
               
               HSSFWorkbook workbook 
            = null;   
               
               
            // 設置Cell之間以空格分割   
               
               
            private static String EXCEL_LINE_DELIMITER = " ";   
               
               
            // 設置最大列數   
               
               
            private static int MAX_EXCEL_COLUMNS = 64;   
               
               
            // 構造函數創建一個ExcelReader   
               
               
            public ExcelReader(String inputfile) throws IOException, Exception{   
               
                  
            // 判斷參數是否為空或沒有意義   
               
                  
            if (inputfile == null || inputfile.trim().equals("")){   
               
                     
            throw new IOException("no input file specified");   
               
                  }
               
               
                  
            // 取得文件名的后綴名賦值給filetype   
               
                  
            this.filetype = inputfile.substring(inputfile.lastIndexOf("."+ 1);   
               
                  
            // 設置開始行為0   
               
                  currPosition 
            = 0;   
               
                  
            // 設置當前位置為0   
               
                  currSheet 
            = 0;   
               
                  
            // 創建文件輸入流   
               
                  is 
            = new FileInputStream(inputfile);   
               
                  
            // 判斷文件格式   
               
                  
            if (filetype.equalsIgnoreCase("txt")){   
               
                     
            // 如果是txt則直接創建BufferedReader讀取   
               
                     reader 
            = new BufferedReader(new InputStreamReader(is));   
               
                  }
               
               
            else if (filetype.equalsIgnoreCase("xls")){   
               
                     
            // 如果是Excel文件則創建HSSFWorkbook讀取   
               
                     workbook 
            = new HSSFWorkbook(is);   
               
                     
            // 設置Sheet數   
               
                     numOfSheets 
            = workbook.getNumberOfSheets();   
               
                  }
               
               
            else{   
               
                     
            throw new Exception("File Type Not Supported");   
               
                  }
               
               
               }
               
               
               
            // 函數readLine讀取文件的一行   
               
               
            public String readLine() throws IOException{   
               
                  
            // 如果是txt文件則通過reader讀取   
               
                  
            if (filetype.equalsIgnoreCase("txt")){   
               
                     String str 
            = reader.readLine();   
               
                     
            // 空行則略去,直接讀取下一行   
               
                     
            while (str.trim().equals("")){   
               
                        str 
            = reader.readLine();   
               
                     }
               
               
                     
            return str;   
               
                  }
               
               
                  
            // 如果是XLS文件則通過POI提供的API讀取文件   
               
                  
            else if (filetype.equalsIgnoreCase("xls")){   
               
                     
            // 根據currSheet值獲得當前的sheet   
               
                     HSSFSheet sheet 
            = workbook.getSheetAt(currSheet);   
               
                     
            // 判斷當前行是否到但前Sheet的結尾   
               
                     
            if (currPosition > sheet.getLastRowNum()){   
               
                        
            // 當前行位置清零   
               
                        currPosition 
            = 0;   
               
                        
            // 判斷是否還有Sheet   
               
                        
            while (currSheet != numOfSheets - 1){   
               
                           
            // 得到下一張Sheet   
               
                           sheet 
            = workbook.getSheetAt(currSheet + 1);   
               
                           
            // 當前行數是否已經到達文件末尾   
               
                           
            if (currPosition == sheet.getLastRowNum()){   
               
                              
            // 當前Sheet指向下一張Sheet   
               
                              currSheet
            ++;   
               
                              
            continue;   
               
                           }
             else{   
               
                              
            // 獲取當前行數   
               
                              
            int row = currPosition;   
               
                              currPosition
            ++;   
               
                              
            // 讀取當前行數據   
               
                              
            return getLine(sheet, row);   
               
                           }
               
               
                        }
               
               
                        
            return null;   
               
                     }
               
               
                     
            // 獲取當前行數   
               
                     
            int row = currPosition;   
               
                     currPosition
            ++;   
               
                     
            // 讀取當前行數據   
               
                     
            return getLine(sheet, row);   
               
                  }
               
               
                  
            return null;   
               
               }
               
               
               
            // 函數getLine返回Sheet的一行數據   
               
               
            private String getLine(HSSFSheet sheet, int row){   
               
                  
            // 根據行數取得Sheet的一行   
               
                  HSSFRow rowline 
            = sheet.getRow(row);   
               
                  
            // 創建字符創緩沖區   
               
                  StringBuffer buffer 
            = new StringBuffer();   
               
                  
            // 獲取當前行的列數   
               
                  
            int filledColumns = rowline.getLastCellNum();   
               
                  HSSFCell cell 
            = null;   
               
                  
            // 循環遍歷所有列   
               
                  
            for (int i = 0; i < filledColumns; i++){   
               
                     
            // 取得當前Cell   
               
                     cell 
            = rowline.getCell((short) i);   
               
                     String cellvalue 
            = null;   
               
                     
            if (cell != null){   
               
                        
            // 判斷當前Cell的Type   
               
                        
            switch (cell.getCellType()){   
               
                        
            // 如果當前Cell的Type為NUMERIC   
               
                        
            case HSSFCell.CELL_TYPE_NUMERIC:{   
               
                           
            // 判斷當前的cell是否為Date   
               
                           
            if (HSSFDateUtil.isCellDateFormatted(cell)){   
               
                              
            // 如果是Date類型則,取得該Cell的Date值   
               
                              Date date 
            = cell.getDateCellValue();   
               
                              
            // 把Date轉換成本地格式的字符串   
               
                              cellvalue 
            = cell.getDateCellValue().toLocaleString();   
               
                           }
               
               
                           
            // 如果是純數字   
               
                           
            else{   
               
                              
            // 取得當前Cell的數值   
               
                              Integer num 
            = new Integer((int) cell   
               
                                    .getNumericCellValue());   
               
                              cellvalue 
            = String.valueOf(num);   
               
                           }
               
               
                           
            break;   
               
                        }
               
               
                        
            // 如果當前Cell的Type為STRIN   
               
                        
            case HSSFCell.CELL_TYPE_STRING:   
               
                           
            // 取得當前的Cell字符串   
               
                           cellvalue 
            = cell.getStringCellValue().replaceAll("'""''");   
               
                           
            break;   
               
                        
            // 默認的Cell值   
               
                        
            default:   
               
                           cellvalue 
            = " ";   
               
                        }
               
               
                     }
             else{   
               
                        cellvalue 
            = "";   
               
                     }
               
               
                     
            // 在每個字段之間插入分割符   
               
                     buffer.append(cellvalue).append(EXCEL_LINE_DELIMITER);   
               
                  }
               
               
                  
            // 以字符串返回該行的數據   
               
                  
            return buffer.toString();   
               
               }
               
               
               
            // close函數執行流的關閉操作   
               
               
            public void close(){   
               
                  
            // 如果is不為空,則關閉InputSteam文件輸入流   
               
                  
            if (is != null){   
               
                     
            try{   
               
                        is.close();   
               
                     }
             catch (IOException e){   
               
                        is 
            = null;   
               
                     }
               
               
                  }
               
               
                  
            // 如果reader不為空則關閉BufferedReader文件輸入流   
               
                  
            if (reader != null){   
               
                     
            try{   
               
                        reader.close();   
               
                     }
             catch (IOException e){   
               
                        reader 
            = null;   
               
                     }
               
               
                  }
               
               
               }
               
               
            }
              
             
          7.3.2  ExcelReader的運行效果
          下面創建一個main函數,用來測試上面的ExcelReader類,代碼如下。
          java 代碼
          1. public static void main(String[] args){   
                  
            try{   
                      ExcelReader er
            =new ExcelReader("c:\xp.xls");      
                      String line
            =er.readLine();   
                      
            while(line != null){   
                          System.out.println(line);   
                          line
            =er.readLine();   
                      }
               
                      er.close();   
                  }
            catch(Exception e){   
                      e.printStackTrace();   
                  }
               
              }
              
             
          main函數先創建一個ExcelReader類,然后調用它提供的接口readLine,對XLS文件進行讀取,打印到控制臺,處理前的XLS文件如圖7-12所示。
          圖7-12  處理前的XLS文件內容
          運行main函數進行內容提取后,Eclipse的控制臺輸出如圖7-13所示。
          圖7-13  輸出結果
          可以看到,Excel文件中的內容已經被成功的輸出了出來。

          7.3.3  POI中Excel文件Cell的類型
          在讀取每一個Cell的值的時候,通過getCellType方法獲得當前Cell的類型,在Excel中Cell有6種類型,如表7-3所示。
          表7-3  Cell的類型
          CellType
          說明
          CELL_TYPE_BLANK
          空值
          CELL_TYPE_BOOLEAN
          布爾型
          CELL_TYPE_ERROR
          錯誤
          CELL_TYPE_FORMULA
          公式型
          CELL_TYPE_STRING
          字符串型
          CELL_TYPE_NUMERIC
          數值型
          本 例采用了CELL_TYPE_STRING和CELL_TYPE_NUMERIC類型,因為在Excel文件中只有字符串和數字。如果Cell的Type 為CELL_TYPE_NUMERIC時,還需要進一步判斷該Cell的數據格式,因為它有可能是Date類型,在Excel中的Date類型也是以 Double類型的數字存儲的。Excel中的Date表示當前時間與1900年1月1日相隔的天數,所以需要調用HSSFDateUtil的 isCellDateFormatted方法,判斷該Cell的數據格式是否是Excel Date類型。如果是,則調用getDateCellValue方法,返回一個Java類型的Date。
          實際上Excel的數據格式有很多,還支持用戶自定義的類型,在Excel中,選擇一個單元格然后右鍵選擇“設置單元格格式”,在彈出的單元格格式中選中“數字”,如圖7-14所示。
          圖7-14  Excel的單元格格式
          圖中的數據有數值、貨幣、時間、日期、文本等格式。這些數據格式在POI中的HSSFDataFormat類里都有相應的定義。
          HSSFDataFormat 是HSSF子項目里面定義的一個類。類HSSFDataFormat允許用戶新建數據格式類型。HSSFDataFormat類包含靜態方法 static java.lang.String getBuiltinFormat(short index),它可以根據編號返回內置數據類型。另外static short getBuiltinFormat(java.lang.String format)方法則可以根據數據類型返回其編號, static java.util.List getBuiltinFormats()可以返回整個內置的數據格式列表。
          在HSSFDataFormat里一共定義了49種內置的數據格式,如表7-4所示。

          表7-4  HSSFDataFormat的數據格式
          內置數據類型
          編號
          "General"
          0
          "0"
          1
          "0.00"
          2
          "#,##0"
          3
          "#,##0.00"
          4
          "($#,##0_);($#,##0)"
          5
          "($#,##0_);[Red]($#,##0)"
          6
          "($#,##0.00);($#,##0.00)"
          7
          "($#,##0.00_);[Red]($#,##0.00)"
          8
          "0%"
          9
          "0.00%"
          0xa
          "0.00E+00"
          0xb
          "# ?/?"
          0xc
          posted on 2008-11-29 09:50 Vincent-chen 閱讀(1041) 評論(0)  編輯  收藏 所屬分類: POI 、Print
          主站蜘蛛池模板: 凤山市| 任丘市| 定襄县| 满洲里市| 大宁县| 新绛县| 台中市| 广汉市| 南投市| 泗洪县| 酒泉市| 桂东县| 澄城县| 横山县| 东城区| 兴隆县| 乐平市| 长乐市| 宜都市| 象山县| 深州市| 长白| 通城县| 临沂市| 师宗县| 门源| 道孚县| 平度市| 阿合奇县| 富宁县| 通化市| 怀来县| 新田县| 和顺县| 兴山县| 张掖市| 正蓝旗| 汨罗市| 开江县| 洛浦县| 麟游县|