Believe it,do it!

          Ideal is the beacon. Without ideal, there is no secure direction; without direction ,there is no life.
          理想是指路明燈。沒有理想,就沒有堅定的方向;沒有方向,就沒有生活。
          CTRL+T eclipse
          posts - 35, comments - 3, trackbacks - 0, articles - 0
            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          POI操作Excel文檔

          Posted on 2008-12-31 13:16 三羽 閱讀(2242) 評論(0)  編輯  收藏 所屬分類: 工作記錄

          一.POI簡介

          Jakarta POI 是apache的子項目,目標是處理ole2對象。它提供了一組操縱Windows文檔的Java API

          目前比較成熟的是HSSF接口,處理MS Excel(97-2002)對象。它不象我們僅僅是用csv生成的沒有格式的可以由Excel轉(zhuǎn)換的東西,而是真正的Excel對象,你可以控制一些屬性如sheet,cell等等。

          二.HSSF概況

          HSSF 是Horrible SpreadSheet Format的縮寫,也即“討厭的電子表格格式”。也許HSSF的名字有點滑稽,就本質(zhì)而言它是一個非常嚴肅、正規(guī)的API。通過HSSF,你可以用純Java代碼來讀取、寫入、修改Excel文件。

          HSSF 為讀取操作提供了兩類API:usermodel和eventusermodel,即“用戶模型”和“事件-用戶模型”。前者很好理解,后者比較抽象,但操作效率要高得多。

          三.開始編碼

          1 . 準備工作

          要求:JDK 1.4+POI開發(fā)包

          可以到 http://www.apache.org/dyn/closer.cgi/jakarta/poi/ 最新的POI工具包

          2 . EXCEL 結(jié)構(gòu)

          HSSFWorkbook excell 文檔對象介紹
          HSSFSheet excell的表單
          HSSFRow excell的行
          HSSFCell excell的格子單元
          HSSFFont excell字體
          HSSFName 名稱
          HSSFDataFormat 日期格式
          在poi1.7中才有以下2項:
          HSSFHeader sheet頭
          HSSFFooter sheet尾
          和這個樣式
          HSSFCellStyle cell樣式
          輔助操作包括
          HSSFDateUtil 日期
          HSSFPrintSetup 打印
          HSSFErrorConstants 錯誤信息表

          3 .具體用法實例 (采用 usermodel )

          如何讀Excel

          讀取Excel文件時,首先生成一個POIFSFileSystem對象,由POIFSFileSystem對象構(gòu)造一個HSSFWorkbook,該HSSFWorkbook對象就代表了Excel文檔。下面代碼讀取上面生成的Excel文件寫入的消息字串:

          代碼
          1. POIFSFileSystem fs=newPOIFSFileSystem(new FileInputStream("d:\test.xls"));    
          2. HSSFWorkbook  wb new HSSFWorkbook(fs);    
          3.   } catch (IOException e)    
          4.   e.printStackTrace();    
          5.   }    
          6.   HSSFSheet sheet wb.getSheetAt(0);    
          7.   HSSFRow row sheet.getRow(0);    
          8.   HSSFCell cell row.getCell((short0);    
          9.   String msg cell.getStringCellValue();   
          1. POIFSFileSystem fs=newPOIFSFileSystem(new FileInputStream("d:\test.xls"));    
          2. HSSFWorkbook  wb new HSSFWorkbook(fs);    
          3.   } catch (IOException e)    
          4.   e.printStackTrace();    
          5.   }    
          6.   HSSFSheet sheet wb.getSheetAt(0);    
          7.   HSSFRow row sheet.getRow(0);    
          8.   HSSFCell cell row.getCell((short0);    
          9.   String msg cell.getStringCellValue();   

          如何寫excel,

          將excel的第一個表單第一行的第一個單元格的值寫成“a test”。

          代碼
          1. POIFSFileSystem fs =new POIFSFileSystem(new FileInputStream("workbook.xls"));    
          2.   
          3.     HSSFWorkbook wb new HSSFWorkbook(fs);    
          4.   
          5.     HSSFSheet sheet wb.getSheetAt(0);    
          6.   
          7.     HSSFRow row sheet.getRow(0);    
          8.   
          9.     HSSFCell cell row.getCell((short)0);    
          10.   
          11.     cell.setCellValue("a test");    
          12.   
          13.     // Write the output to file    
          14.   
          15.     FileOutputStream fileOut new FileOutputStream("workbook.xls");    
          16.   
          17.     wb.write(fileOut);    
          18.   
          19. fileOut.close();   

          4 . 可參考文檔

          POI 主頁:http://jakarta.apache.org/poi/,

          初學者如何快速上手使用POI HSSF

          http://jakarta.apache.org/poi/hssf/quick-guide.html 。

          代碼例子 http://blog.java-cn.com/user1/6749/archives/2005/18347.html

          里面有很多例子代碼,可以很方便上手。

          POI的中級應(yīng)該用


          1、遍歷workbook

          代碼
          1. // load源文件   
          2. POIFSFileSystem fs new POIFSFileSystem(new FileInputStream(filePath));   
          3. HSSFWorkbook wb new HSSFWorkbook(fs);   
          4. for (int 0wb.getNumberOfSheets(); i++) {   
          5.     HSSFSheet sheet wb.getSheetAt(i);   
          6.     for (int sheet.getFirstRowNum(); sheet.getLastRowNum(); ++) {   
          7.     HSSFRow row sheet.getRow(i);   
          8.             if (row != null{   
          9.         。。。操作}   
          10.        }   
          11.      }   
          12. // 目標文件   
          13. FileOutputStream fos new FileOutputStream(objectPath);   
          14. //寫文件   
          15. swb.write(fos);   
          16. fos.close();  

          2、得到列和單元格

          代碼
          1. HSSFRow row sheet.getRow(i);   
          2. HSSFCell cell row.getCell((shortj);  

          3、設(shè)置sheet名稱和單元格內(nèi)容為中文

          代碼
          1. wb.setSheetName(n, "中文",HSSFCell.ENCODING_UTF_16);       
          2. cell.setEncoding((short1);   
          3. cell.setCellValue("中文");  

          4、單元格內(nèi)容未公式或數(shù)值,可以這樣讀寫

          代碼
          1. cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC);   
          2. cell.getNumericCellValue()  


          5、設(shè)置列寬、行高

          代碼
          1. sheet.setColumnWidth((short)column,(short)width);   
          2. row.setHeight((short)height);  


          6、添加區(qū)域,合并單元格

          代碼
          1. Region region new Region((short)rowFrom,(short)columnFrom,(short)rowTo,(short)columnTo);   
          2. sheet.addMergedRegion(region);   
          3. //得到所有區(qū)域   
          4. sheet.getNumMergedRegions()  

          7、常用方法
          根據(jù)單元格不同屬性返回字符串數(shù)值

          代碼
          1. public String getCellStringValue(HSSFCell cell) {   
          2.         String cellValue "";   
          3.         switch (cell.getCellType()) {   
          4.         case HSSFCell.CELL_TYPE_STRING:   
          5.             cellValue cell.getStringCellValue();   
          6.             if(cellValue.trim().equals("")||cellValue.trim().length()<=0)   
          7.                 cellValue=";   
          8.             break;   
          9.         case HSSFCell.CELL_TYPE_NUMERIC:   
          10.             cellValue String.valueOf(cell.getNumericCellValue());   
          11.             break;   
          12.         case HSSFCell.CELL_TYPE_FORMULA:   
          13.             cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC);   
          14.             cellValue String.valueOf(cell.getNumericCellValue());   
          15.             break;   
          16.         case HSSFCell.CELL_TYPE_BLANK:   
          17.             cellValue=";   
          18.             break;   
          19.         case HSSFCell.CELL_TYPE_BOOLEAN:   
          20.             break;   
          21.         case HSSFCell.CELL_TYPE_ERROR:   
          22.             break;   
          23.         default:   
          24.             break;   
          25.         }   
          26.         return cellValue;   
          27.      


          8、常用單元格邊框格式

          虛線HSSFCellStyle.BORDER_DOTTED
          實線HSSFCellStyle.BORDER_THIN

          代碼
          1. public static HSSFCellStyle getCellStyle(short type)   
          2.          
          3.        HSSFWorkbook wb new HSSFWorkbook();   
          4.        HSSFCellStyle style wb.createCellStyle();   
          5.        style.setBorderBottom(type);//下邊框    
          6.         style.setBorderLeft(type);//左邊框    
          7.         style.setBorderRight(type);//右邊框    
          8.         style.setBorderTop(type);//上邊框    
          9.        return style;   
          10.      


          9、設(shè)置字體和內(nèi)容位置

          代碼
          1. HSSFFont  wb.createFont();   
          2. f.setFontHeightInPoints((short11);//字號   
          3. f.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);//加粗   
          4. style.setFont(f);   
          5. style.setAlignment(HSSFCellStyle.ALIGN_CENTER);//左右居中   
          6. style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);//上下居中   
          7. style.setRotation(short rotation);//單元格內(nèi)容的旋轉(zhuǎn)的角度   
          8. HSSFDataFormat df wb.createDataFormat();   
          9. style1.setDataFormat(df.getFormat("0.00%"));//設(shè)置單元格數(shù)據(jù)格式   
          10. cell.setCellFormula(string);//給單元格設(shè)公式   
          11. style.setRotation(short rotation);//單元格內(nèi)容的旋轉(zhuǎn)的角度   
          12. cell.setCellStyle(style);   


          10、插入圖片

          論壇里看到的
          代碼
          1. //先把讀進來的圖片放到一個ByteArrayOutputStream中,以便產(chǎn)生ByteArray   
          2.       ByteArrayOutputStream byteArrayOut new ByteArrayOutputStream();   
          3.       BufferedImage bufferImg ImageIO.read(new File("ok.jpg"));   
          4.       ImageIO.write(bufferImg,"jpg",byteArrayOut);   
          5. //讀進一個excel模版   
          6. FileInputStream fos new FileInputStream(filePathName+"/stencil.xlt");    
          7. fs new POIFSFileSystem(fos);   
          8. //創(chuàng)建一個工作薄   
          9. HSSFWorkbook wb new HSSFWorkbook(fs);   
          10. HSSFSheet sheet wb.getSheetAt(0);   
          11. HSSFPatriarch patriarch sheet.createDrawingPatriarch();   
          12. HSSFClientAnchor anchor new HSSFClientAnchor(0,0,1023,255,(short0,0,(short)10,10);        
          13. patriarch.createPicture(anchor wb.addPicture(byteArrayOut.toByteArray(),HSSFWorkbook.PICTURE_TYPE_JPEG));  

          11、設(shè)置列自動換行

             HSSFCellStyle cellStyle =  workbook.createCellStyle();
             cellStyle.setWrapText(true);
             sheet.setDefaultColumnStyle((short)0, cellStyle);

              設(shè)置列的寬度

             sheet.setColumnWidth((short)0,(short)9000);

           

            sheet.setDefaultColumnStyle((short)0, cellStyle);

            與

            sheet.setDefaultColumnWidth((short)70);沖突

            只會換行 不會設(shè)置列寬


          單元格拷貝示例:


          package testpoi;


          import java.io.FileInputStream;

          import java.io.FileNotFoundException;

          import java.io.FileOutputStream;

          import java.io.IOException;


          import org.apache.poi.hssf.usermodel.HSSFCell;

          import org.apache.poi.hssf.usermodel.HSSFRow;

          import org.apache.poi.hssf.usermodel.HSSFSheet;

          import org.apache.poi.hssf.usermodel.HSSFWorkbook;

          import org.apache.poi.hssf.util.Region;

          import org.apache.poi.poifs.filesystem.POIFSFileSystem;

          /**

           * 將某SHEET頁中的某幾行復(fù)制到某SHEET頁的某幾行中。抱括被合并了的單元格。

           */

          public class RowCopy {


          /**

          * @param args

          * @throws IOException

          * @throws FileNotFoundException

          */


          @SuppressWarnings("deprecation")

          public static void main(String[] args) {

          try {

          POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(

          "d:\\exlsample.xls"));

          HSSFWorkbook wb = new HSSFWorkbook(fs);


          // source為源sheet 頁,target為目標sheet頁

          copyRows(wb, "source", "target", 5, 6, 20);

          FileOutputStream fileOut = new FileOutputStream("d:\\exlsample.xls");

          wb.write(fileOut);

          fileOut.flush();

          fileOut.close();

          System.out.println("Operation finished");

          } catch (Exception e) {

          e.printStackTrace();

          }

          }


          /**

          * @param wb HSSFWorkbook

          * @param pSourceSheetName 源sheet頁名稱

          * @param pTargetSheetName 目標sheet頁名稱

          * @param pStartRow 源sheet頁中的起始行

          * @param pEndRow  源sheet頁中的結(jié)束行

          * @param pPosition 目標sheet頁中的開始行

          */

          public static void copyRows(HSSFWorkbook wb, String pSourceSheetName,

          String pTargetSheetName, int intStartRow, int intEndRow, int intPosition) {

          // EXECL中的行是從1開始的,而POI中是從0開始的,所以這里要減1.

          int pStartRow = intStartRow - 1;

          int pEndRow = intEndRow - 1;

          int pPosition = intPosition - 1;

          HSSFRow sourceRow = null;

          HSSFRow targetRow = null;

          HSSFCell sourceCell = null;

          HSSFCell targetCell = null;

          HSSFSheet sourceSheet = null;

          HSSFSheet targetSheet = null;

          Region region = null;

          int cType;

          int i;

          int j;

          int targetRowFrom;

          int targetRowTo;


          if ((pStartRow == -1) || (pEndRow == -1)) {

          return;

          }

          sourceSheet = wb.getSheet(pSourceSheetName);

          targetSheet = wb.getSheet(pTargetSheetName);

          System.out.println(sourceSheet.getNumMergedRegions());

          // 拷貝合并的單元格

          for (i = 0; i < sourceSheet.getNumMergedRegions(); i++) {

          region = sourceSheet.getMergedRegionAt(i);

          if ((region.getRowFrom() >= pStartRow)

          && (region.getRowTo() <= pEndRow)) {

          targetRowFrom = region.getRowFrom() - pStartRow + pPosition;

          targetRowTo = region.getRowTo() - pStartRow + pPosition;

          region.setRowFrom(targetRowFrom);

          region.setRowTo(targetRowTo);

          targetSheet.addMergedRegion(region);

          }

          }

          // 設(shè)置列寬

          for (i = pStartRow; i <= pEndRow; i++) {

          sourceRow = sourceSheet.getRow(i);

          if (sourceRow != null) {

          for (j = sourceRow.getLastCellNum(); j > sourceRow

          .getFirstCellNum(); j--) {

          targetSheet

          .setColumnWidth(j, sourceSheet.getColumnWidth(j));

          targetSheet.setColumnHidden(j, false);

          }

          break;

          }

          }

          // 拷貝行并填充數(shù)據(jù)

          for (; i <= pEndRow; i++) {

          sourceRow = sourceSheet.getRow(i);

          if (sourceRow == null) {

          continue;

          }

          targetRow = targetSheet.createRow(i - pStartRow + pPosition);

          targetRow.setHeight(sourceRow.getHeight());

          for (j = sourceRow.getFirstCellNum(); j < sourceRow

          .getPhysicalNumberOfCells(); j++) {

          sourceCell = sourceRow.getCell(j);

          if (sourceCell == null) {

          continue;

          }

          targetCell = targetRow.createCell(j);

          targetCell.setCellStyle(sourceCell.getCellStyle());

          cType = sourceCell.getCellType();

          targetCell.setCellType(cType);

          switch (cType) {

          case HSSFCell.CELL_TYPE_BOOLEAN:

          targetCell.setCellValue(sourceCell.getBooleanCellValue());

          System.out.println("--------TYPE_BOOLEAN:"

          + targetCell.getBooleanCellValue());

          break;

          case HSSFCell.CELL_TYPE_ERROR:

          targetCell

          .setCellErrorValue(sourceCell.getErrorCellValue());

          System.out.println("--------TYPE_ERROR:"

          + targetCell.getErrorCellValue());

          break;

          case HSSFCell.CELL_TYPE_FORMULA:

          // parseFormula這個函數(shù)的用途在后面說明

          targetCell.setCellFormula(parseFormula(sourceCell

          .getCellFormula()));

          System.out.println("--------TYPE_FORMULA:"

          + targetCell.getCellFormula());

          break;

          case HSSFCell.CELL_TYPE_NUMERIC:

          targetCell.setCellValue(sourceCell.getNumericCellValue());

          System.out.println("--------TYPE_NUMERIC:"

          + targetCell.getNumericCellValue());

          break;

          case HSSFCell.CELL_TYPE_STRING:

          targetCell

          .setCellValue(sourceCell.getRichStringCellValue());

          System.out.println("--------TYPE_STRING:" + i

          + targetCell.getRichStringCellValue());

          break;

          }


          }


          }


          }


          /**

          * POI對Excel公式的支持是相當好的,但是有一個問題,如果公式里面的函數(shù)不帶參數(shù),比如now()或today(),

          * 那么你通過getCellFormula()取出來的值就是now(ATTR(semiVolatile))和today(ATTR(semiVolatile)),

          * 這樣的值寫入Excel是會出錯的,這也是我上面copyRow的函數(shù)在寫入公式前要調(diào)用parseFormula的原因,

          * parseFormula這個函數(shù)的功能很簡單,就是把ATTR(semiVolatile)刪掉。

          * @param pPOIFormula

          * @return

          */

          private static String parseFormula(String pPOIFormula) {

          final String cstReplaceString = "ATTR(semiVolatile)"; //$NON-NLS-1$

          StringBuffer result = null;

          int index;


          result = new StringBuffer();

          index = pPOIFormula.indexOf(cstReplaceString);

          if (index >= 0) {

          result.append(pPOIFormula.substring(0, index));

          result.append(pPOIFormula.substring(index

          + cstReplaceString.length()));

          } else {

          result.append(pPOIFormula);

          }


          return result.toString();

          }


          }

           



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


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 庄河市| 康乐县| 绵竹市| 高要市| 盘山县| 安塞县| 平山县| 扶余县| 德州市| 喀什市| 彭阳县| 松江区| 宁城县| 都兰县| 广宁县| 金溪县| 通辽市| 阿克陶县| 赤水市| 桂东县| 盖州市| 乌兰察布市| 洱源县| 威海市| 承德县| 玉林市| 固安县| 阳山县| 乌鲁木齐县| 资兴市| 阿克| 彭泽县| 同心县| 西和县| 高雄市| 滦南县| 邮箱| 巴里| 阳江市| 伽师县| 榆中县|