分享java帶來的快樂

          我喜歡java新東西

          java poi 讀取excel各種數(shù)據(jù)

          Microsoft的Office系列產(chǎn)品擁有大 量的用戶,Word、Excel也成為辦公文件的首選。在Java中,已經(jīng)有很多對(duì)于Word、Excel的開源的解決方案,其中比較出色的是 Apache的Jakata項(xiàng)目的POI子項(xiàng)目。該項(xiàng)目的官方網(wǎng)站是http://jakarta.apache.org/poi/。
          POI 包括一系列的API,它們可以操作基于MicroSoft OLE 2 Compound Document Format的各種格式文件,可以通過這些API在Java中讀寫Excel、Word等文件。POI是完全的Java Excel和Java Word解決方案。POI子項(xiàng)目包括:POIFS、HSSF、HDF、HPSF。表7-2對(duì)它們進(jìn)行了簡要介紹。
          表7-2  POI子項(xiàng)目介紹
          子項(xiàng)目名
          說明
          POIFS(POI File System)
          POIFS是POI項(xiàng)目中最早的最基礎(chǔ)的一個(gè)模塊,是Java到OLE 2 Compound Document Format的接口,支持讀寫功能,所有的其他項(xiàng)目都依賴與該項(xiàng)目。
          HSSF(Horrible Spreadsheet Format)
          HSSF是Java到Microsoft Excel 97(-2002)文件的接口,支持讀寫功能
          HWPF(Horrible Word Processing Format)
          HWPF是Java到Microsoft Word 97文件的接口,支持讀寫功能,但目前該模塊還處于剛開始開發(fā)階段,只能實(shí)現(xiàn)一些簡單文件的操作,在后續(xù)版本中,會(huì)提供更強(qiáng)大的支持
          HPSF(Horrible Property Set Format)
          HPSF 是Java到OLE 2 Compound Document Format文件的屬性設(shè)置的接口,屬性設(shè)置通常用來設(shè)置文檔的屬性(標(biāo)題,作者,最后修改日期等),還可以設(shè)置用戶定義的屬性。HPSF支持讀寫功能,當(dāng)前發(fā)布版本中直支持讀功能。
          7.3.1  對(duì)Excel的處理類
          下 面通過HSSF提供的接口對(duì)Excel文件經(jīng)行處理。首先需要下載POI的包,可以到apache的官方網(wǎng)站下載,地址為:http: //apache.justdn.org/jakarta/poi/,本書采用的是poi-2.5.1-final-20040804.jar,讀者可以 下載當(dāng)前的穩(wěn)定版本。把下載的包按照前面介紹的方式加入Build Path,然后新建一個(gè)ch7.poi包,并創(chuàng)建一個(gè)ExcelReader類。
          ExcelReader類可以讀取一個(gè)XLS文件,然后將其內(nèi)容逐行提取出來,寫入文本文件。其代碼如下。
          java 代碼
          1. public class ExcelReader{  
          2.   
          3.    // 創(chuàng)建文件輸入流  
          4.   
          5.    private BufferedReader reader = null;  
          6.   
          7.    // 文件類型  
          8.   
          9.    private String filetype;  
          10.   
          11.    // 文件二進(jìn)制輸入流  
          12.   
          13.    private InputStream is = null;  
          14.   
          15.    // 當(dāng)前的Sheet  
          16.   
          17.    private int currSheet;  
          18.   
          19.    // 當(dāng)前位置  
          20.   
          21.    private int currPosition;  
          22.   
          23.    // Sheet數(shù)量  
          24.   
          25.    private int numOfSheets;  
          26.   
          27.    // HSSFWorkbook  
          28.   
          29.    HSSFWorkbook workbook = null;  
          30.   
          31.    // 設(shè)置Cell之間以空格分割  
          32.   
          33.    private static String EXCEL_LINE_DELIMITER = " ";  
          34.   
          35.    // 設(shè)置最大列數(shù)  
          36.   
          37.    private static int MAX_EXCEL_COLUMNS = 64;  
          38.   
          39.    // 構(gòu)造函數(shù)創(chuàng)建一個(gè)ExcelReader  
          40.   
          41.    public ExcelReader(String inputfile) throws IOException, Exception{  
          42.   
          43.       // 判斷參數(shù)是否為空或沒有意義  
          44.   
          45.       if (inputfile == null || inputfile.trim().equals("")){  
          46.   
          47.          throw new IOException("no input file specified");  
          48.   
          49.       }  
          50.   
          51.       // 取得文件名的后綴名賦值給filetype  
          52.   
          53.       this.filetype = inputfile.substring(inputfile.lastIndexOf(".") + 1);  
          54.   
          55.       // 設(shè)置開始行為0  
          56.   
          57.       currPosition = 0;  
          58.   
          59.       // 設(shè)置當(dāng)前位置為0  
          60.   
          61.       currSheet = 0;  
          62.   
          63.       // 創(chuàng)建文件輸入流  
          64.   
          65.       is = new FileInputStream(inputfile);  
          66.   
          67.       // 判斷文件格式  
          68.   
          69.       if (filetype.equalsIgnoreCase("txt")){  
          70.   
          71.          // 如果是txt則直接創(chuàng)建BufferedReader讀取  
          72.   
          73.          reader = new BufferedReader(new InputStreamReader(is));  
          74.   
          75.       }  
          76.   
          77. else if (filetype.equalsIgnoreCase("xls")){  
          78.   
          79.          // 如果是Excel文件則創(chuàng)建HSSFWorkbook讀取  
          80.   
          81.          workbook = new HSSFWorkbook(is);  
          82.   
          83.          // 設(shè)置Sheet數(shù)  
          84.   
          85.          numOfSheets = workbook.getNumberOfSheets();  
          86.   
          87.       }  
          88.   
          89. else{  
          90.   
          91.          throw new Exception("File Type Not Supported");  
          92.   
          93.       }  
          94.   
          95.    }  
          96.   
          97.    // 函數(shù)readLine讀取文件的一行  
          98.   
          99.    public String readLine() throws IOException{  
          100.   
          101.       // 如果是txt文件則通過reader讀取  
          102.   
          103.       if (filetype.equalsIgnoreCase("txt")){  
          104.   
          105.          String str = reader.readLine();  
          106.   
          107.          // 空行則略去,直接讀取下一行  
          108.   
          109.          while (str.trim().equals("")){  
          110.   
          111.             str = reader.readLine();  
          112.   
          113.          }  
          114.   
          115.          return str;  
          116.   
          117.       }  
          118.   
          119.       // 如果是XLS文件則通過POI提供的API讀取文件  
          120.   
          121.       else if (filetype.equalsIgnoreCase("xls")){  
          122.   
          123.          // 根據(jù)currSheet值獲得當(dāng)前的sheet  
          124.   
          125.          HSSFSheet sheet = workbook.getSheetAt(currSheet);  
          126.   
          127.          // 判斷當(dāng)前行是否到但前Sheet的結(jié)尾  
          128.   
          129.          if (currPosition > sheet.getLastRowNum()){  
          130.   
          131.             // 當(dāng)前行位置清零  
          132.   
          133.             currPosition = 0;  
          134.   
          135.             // 判斷是否還有Sheet  
          136.   
          137.             while (currSheet != numOfSheets - 1){  
          138.   
          139.                // 得到下一張Sheet  
          140.   
          141.                sheet = workbook.getSheetAt(currSheet + 1);  
          142.   
          143.                // 當(dāng)前行數(shù)是否已經(jīng)到達(dá)文件末尾  
          144.   
          145.                if (currPosition == sheet.getLastRowNum()){  
          146.   
          147.                   // 當(dāng)前Sheet指向下一張Sheet  
          148.   
          149.                   currSheet++;  
          150.   
          151.                   continue;  
          152.   
          153.                } else{  
          154.   
          155.                   // 獲取當(dāng)前行數(shù)  
          156.   
          157.                   int row = currPosition;  
          158.   
          159.                   currPosition++;  
          160.   
          161.                   // 讀取當(dāng)前行數(shù)據(jù)  
          162.   
          163.                   return getLine(sheet, row);  
          164.   
          165.                }  
          166.   
          167.             }  
          168.   
          169.             return null;  
          170.   
          171.          }  
          172.   
          173.          // 獲取當(dāng)前行數(shù)  
          174.   
          175.          int row = currPosition;  
          176.   
          177.          currPosition++;  
          178.   
          179.          // 讀取當(dāng)前行數(shù)據(jù)  
          180.   
          181.          return getLine(sheet, row);  
          182.   
          183.       }  
          184.   
          185.       return null;  
          186.   
          187.    }  
          188.   
          189.    // 函數(shù)getLine返回Sheet的一行數(shù)據(jù)  
          190.   
          191.    private String getLine(HSSFSheet sheet, int row){  
          192.   
          193.       // 根據(jù)行數(shù)取得Sheet的一行  
          194.   
          195.       HSSFRow rowline = sheet.getRow(row);  
          196.   
          197.       // 創(chuàng)建字符創(chuàng)緩沖區(qū)  
          198.   
          199.       StringBuffer buffer = new StringBuffer();  
          200.   
          201.       // 獲取當(dāng)前行的列數(shù)  
          202.   
          203.       int filledColumns = rowline.getLastCellNum();  
          204.   
          205.       HSSFCell cell = null;  
          206.   
          207.       // 循環(huán)遍歷所有列  
          208.   
          209.       for (int i = 0; i < filledColumns; i++){  
          210.   
          211.          // 取得當(dāng)前Cell  
          212.   
          213.          cell = rowline.getCell((short) i);  
          214.   
          215.          String cellvalue = null;  
          216.   
          217.          if (cell != null){  
          218.   
          219.             // 判斷當(dāng)前Cell的Type  
          220.   
          221.             switch (cell.getCellType()){  
          222.   
          223.             // 如果當(dāng)前Cell的Type為NUMERIC  
          224.   
          225.             case HSSFCell.CELL_TYPE_NUMERIC:{  
          226.   
          227.                // 判斷當(dāng)前的cell是否為Date  
          228.   
          229.                if (HSSFDateUtil.isCellDateFormatted(cell)){  
          230.   
          231.                   // 如果是Date類型則,取得該Cell的Date值  
          232.   
          233.                   Date date = cell.getDateCellValue();  
          234.   
          235.                   // 把Date轉(zhuǎn)換成本地格式的字符串  
          236.   
          237.                   cellvalue = cell.getDateCellValue().toLocaleString();  
          238.   
          239.                }  
          240.   
          241.                // 如果是純數(shù)字  
          242.   
          243.                else{  
          244.   
          245.                   // 取得當(dāng)前Cell的數(shù)值  
          246.   
          247.                   Integer num = new Integer((int) cell  
          248.   
          249.                         .getNumericCellValue());  
          250.   
          251.                   cellvalue = String.valueOf(num);  
          252.   
          253.                }  
          254.   
          255.                break;  
          256.   
          257.             }  
          258.   
          259.             // 如果當(dāng)前Cell的Type為STRIN  
          260.   
          261.             case HSSFCell.CELL_TYPE_STRING:  
          262.   
          263.                // 取得當(dāng)前的Cell字符串  
          264.   
          265.                cellvalue = cell.getStringCellValue().replaceAll("'""''");  
          266.   
          267.                break;  
          268.   
          269.             // 默認(rèn)的Cell值  
          270.   
          271.             default:  
          272.   
          273.                cellvalue = " ";  
          274.   
          275.             }  
          276.   
          277.          } else{  
          278.   
          279.             cellvalue = "";  
          280.   
          281.          }  
          282.   
          283.          // 在每個(gè)字段之間插入分割符  
          284.   
          285.          buffer.append(cellvalue).append(EXCEL_LINE_DELIMITER);  
          286.   
          287.       }  
          288.   
          289.       // 以字符串返回該行的數(shù)據(jù)  
          290.   
          291.       return buffer.toString();  
          292.   
          293.    }  
          294.   
          295.    // close函數(shù)執(zhí)行流的關(guān)閉操作  
          296.   
          297.    public void close(){  
          298.   
          299.       // 如果is不為空,則關(guān)閉InputSteam文件輸入流  
          300.   
          301.       if (is != null){  
          302.   
          303.          try{  
          304.   
          305.             is.close();  
          306.   
          307.          } catch (IOException e){  
          308.   
          309.             is = null;  
          310.   
          311.          }  
          312.   
          313.       }  
          314.   
          315.       // 如果reader不為空則關(guān)閉BufferedReader文件輸入流  
          316.   
          317.       if (reader != null){  
          318.   
          319.          try{  
          320.   
          321.             reader.close();  
          322.   
          323.          } catch (IOException e){  
          324.   
          325.             reader = null;  
          326.   
          327.          }  
          328.   
          329.       }  
          330.   
          331.    }  
          332.   
          333. }  
          7.3.2  ExcelReader的運(yùn)行效果
          下面創(chuàng)建一個(gè)main函數(shù),用來測(cè)試上面的ExcelReader類,代碼如下。
          java 代碼
          1. public static void main(String[] args){  
          2.       try{  
          3.           ExcelReader er=new ExcelReader("c:\xp.xls");     
          4.           String line=er.readLine();  
          5.           while(line != null){  
          6.               System.out.println(line);  
          7.               line=er.readLine();  
          8.           }  
          9.           er.close();  
          10.       }catch(Exception e){  
          11.           e.printStackTrace();  
          12.       }  
          13.   }  
          main函數(shù)先創(chuàng)建一個(gè)ExcelReader類,然后調(diào)用它提供的接口readLine,對(duì)XLS文件進(jìn)行讀取,打印到控制臺(tái),處理前的XLS文件如圖7-12所示。
          圖7-12  處理前的XLS文件內(nèi)容
          運(yùn)行main函數(shù)進(jìn)行內(nèi)容提取后,Eclipse的控制臺(tái)輸出如圖7-13所示。
          圖7-13  輸出結(jié)果
          可以看到,Excel文件中的內(nèi)容已經(jīng)被成功的輸出了出來。

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

          表7-4  HSSFDataFormat的數(shù)據(jù)格式
          內(nèi)置數(shù)據(jù)類型
          編號(hào)
          "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 2009-04-23 00:07 強(qiáng)強(qiáng) 閱讀(17928) 評(píng)論(2)  編輯  收藏

          評(píng)論

          # re: java poi 讀取excel各種數(shù)據(jù) 2009-11-05 14:11 斯蒂芬

          你上面要是多張sheet的話 有一個(gè)死循環(huán)  回復(fù)  更多評(píng)論   

          # re: java poi 讀取excel各種數(shù)據(jù) 2009-11-05 14:12 斯蒂芬

          while (currSheet != numOfSheets - 1){

          // 得到下一張Sheet

          sheet = workbook.getSheetAt(currSheet + 1);

          // 當(dāng)前行數(shù)是否已經(jīng)到達(dá)文件末尾
          currSheet = currSheet+1;
          if (currPosition == sheet.getLastRowNum()){
          // 當(dāng)前Sheet指向下一張Sheet
          //currSheet++;
          continue;

          } else{   回復(fù)  更多評(píng)論   


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


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 云浮市| 磴口县| 孝义市| 博湖县| 磐安县| 和田市| 鄂托克旗| 龙州县| 梧州市| 德昌县| 八宿县| 屏东县| 麻阳| 湘乡市| 泗水县| 达尔| 周宁县| 塔城市| 铜陵市| 雷山县| 河津市| 宁海县| 高台县| 永吉县| 普格县| 华池县| 泊头市| 泰州市| 漯河市| 曲靖市| 永善县| 禄丰县| 岳普湖县| 永登县| 普安县| 陕西省| 仪征市| 叶城县| 水富县| 象山县| 西贡区|