1. 程式人生 > >java操作Excel-Apache POI使用常用方法

java操作Excel-Apache POI使用常用方法

1.POI結構與常用類

(1)POI介紹

     Apache POI是Apache軟體基金會的開源專案,POI提供API給Java程式對Microsoft Office格式檔案讀和寫的功能。 .NET的開發人員則可以利用NPOI (POI for .NET) 來存取 Microsoft Office文件的功能。

(2)POI結構說明

 

包名稱說明

HSSF提供讀寫Microsoft Excel XLS格式檔案的功能。

XSSF提供讀寫Microsoft Excel OOXML XLSX格式檔案的功能。

HWPF提供讀寫Microsoft Word DOC格式檔案的功能。

HSLF提供讀寫Microsoft PowerPoint格式檔案的功能。

HDGF提供讀Microsoft Visio格式檔案的功能。

HPBF提供讀Microsoft Publisher格式檔案的功能。

HSMF提供讀Microsoft Outlook格式檔案的功能。

(3)POI常用類說明

類名                     說明

HSSFWorkbook           Excel的文件物件

HSSFSheet     

Excel的表單

HSSFRow               

Excel的行

HSSFCell     

Excel的格子單元

HSSFFont                Excel字型

 

HSSFDataFormat        格子單元的日期格式

HSSFHeader             Excel文件Sheet的頁首

HSSFFooter             Excel文件Sheet的頁尾

HSSFCellStyle          格子單元樣式

HSSFDateUtil           日期

HSSFPrintSetup        列印

 

HSSFErrorConstants   錯誤資訊表

2.Excel的基本操作

(1)建立Workbook和Sheet

  1. public class Test00
  2. {
  3.  public static void main(String[] args) throws IOException
  4.  {
  5.  String filePath="d:\\users\\lizw\\桌面\\POI\\sample.xls";//檔案路徑
  6.  HSSFWorkbook workbook = new HSSFWorkbook();//建立Excel檔案(Workbook)
  7.  HSSFSheet sheet = workbook.createSheet();//建立工作表(Sheet)
  8. sheet = workbook.createSheet("Test");//建立工作表(Sheet)
  9.  FileOutputStream out = new FileOutputStream(filePath);
  10. workbook.write(out);//儲存Excel檔案
  11. out.close();//關閉檔案流
  12.  System.out.println("OK!");
  13.  }
  14. }

(2)建立單元格

  1. HSSFSheet sheet = workbook.createSheet("Test");// 建立工作表(Sheet)
  2. HSSFRow row = sheet.createRow(0);// 建立行,從0開始
  3. HSSFCell cell = row.createCell(0);// 建立行的單元格,也是從0開始
  4. cell.setCellValue("李志偉");// 設定單元格內容
  5. row.createCell(1).setCellValue(false);// 設定單元格內容,過載
  6. row.createCell(2).setCellValue(new Date());// 設定單元格內容,過載
  7. row.createCell(3).setCellValue(12.345);// 設定單元格內容,過載

(3)建立文件摘要資訊

  1. workbook.createInformationProperties();//建立文件資訊
  2. DocumentSummaryInformation dsi=workbook.getDocumentSummaryInformation();//摘要資訊
  3. dsi.setCategory("類別:Excel檔案");//類別
  4. dsi.setManager("管理者:李志偉");//管理者
  5. dsi.setCompany("公司:--");//公司
  6. SummaryInformation si = workbook.getSummaryInformation();//摘要資訊
  7. si.setSubject("主題:--");//主題
  8. si.setTitle("標題:測試文件");//標題
  9. si.setAuthor("作者:李志偉");//作者
  10. si.setComments("備註:POI測試文件");//備註

(4)建立批註

  1. HSSFSheet sheet = workbook.createSheet("Test");// 建立工作表(Sheet)
  2. HSSFPatriarch patr = sheet.createDrawingPatriarch();
  3. HSSFClientAnchor anchor = patr.createAnchor(0, 0, 0, 0, 5, 1, 8,3);//建立批註位置
  4. HSSFComment comment = patr.createCellComment(anchor);//建立批註
  5. comment.setString(new HSSFRichTextString("這是一個批註段落!"));//設定批註內容
  6. comment.setAuthor("李志偉");//設定批註作者
  7. comment.setVisible(true);//設定批註預設顯示
  8. HSSFCell cell = sheet.createRow(2).createCell(1);
  9. cell.setCellValue("測試");
  10. cell.setCellComment(comment);//把批註賦值給單元格

     建立批註位置HSSFPatriarch.createAnchor(dx1, dy1, dx2, dy2, col1, row1, col2, row2)方法引數說明:

  1. dx1 第1個單元格中x軸的偏移量
  2. dy1 第1個單元格中y軸的偏移量
  3. dx2 第2個單元格中x軸的偏移量
  4. dy2 第2個單元格中y軸的偏移量
  5. col1 第1個單元格的列號
  6. row1 第1個單元格的行號
  7. col2 第2個單元格的列號
  8. row2 第2個單元格的行號

(5)建立頁首和頁尾

  1. HSSFSheet sheet = workbook.createSheet("Test");// 建立工作表(Sheet)
  2. HSSFHeader header =sheet.getHeader();//得到頁首
  3. header.setLeft("頁首左邊");
  4. header.setRight("頁首右邊");
  5. header.setCenter("頁首中間");
  6. HSSFFooter footer =sheet.getFooter();//得到頁尾
  7. footer.setLeft("頁尾左邊");
  8. footer.setRight("頁尾右邊");
  9. footer.setCenter("頁尾中間");

     也可以使用Office自帶的標籤定義,你可以通過HSSFHeader或HSSFFooter訪問到它們,都是靜態屬性,列表如下:

  1. HSSFHeader.tab &A 表名
  2. HSSFHeader.file &F 檔名
  3. HSSFHeader.startBold &B 粗體開始
  4. HSSFHeader.endBold &B 粗體結束
  5. HSSFHeader.startUnderline &U 下劃線開始
  6. HSSFHeader.endUnderline &U 下劃線結束
  7. HSSFHeader.startDoubleUnderline &E 雙下劃線開始
  8. HSSFHeader.endDoubleUnderline &E 雙下劃線結束
  9. HSSFHeader.time &T 時間
  10. HSSFHeader.date &D 日期
  11. HSSFHeader.numPages &N 總頁面數
  12. HSSFHeader.page &P 當前頁號

3.Excel的單元格操作

(1)設定格式

  1. HSSFSheet sheet = workbook.createSheet("Test");// 建立工作表(Sheet)
  2. HSSFRow row=sheet.createRow(0);
  3. //設定日期格式--使用Excel內嵌的格式
  4. HSSFCell cell=row.createCell(0);
  5. cell.setCellValue(new Date());
  6. HSSFCellStyle style=workbook.createCellStyle();
  7. style.setDataFormat(HSSFDataFormat.getBuiltinFormat("m/d/yy h:mm"));
  8. cell.setCellStyle(style);
  9. //設定保留2位小數--使用Excel內嵌的格式
  10. cell=row.createCell(1);
  11. cell.setCellValue(12.3456789);
  12. style=workbook.createCellStyle();
  13. style.setDataFormat(HSSFDataFormat.getBuiltinFormat("0.00"));
  14. cell.setCellStyle(style);
  15. //設定貨幣格式--使用自定義的格式
  16. cell=row.createCell(2);
  17. cell.setCellValue(12345.6789);
  18. style=workbook.createCellStyle();
  19. style.setDataFormat(workbook.createDataFormat().getFormat("¥#,##0"));
  20. cell.setCellStyle(style);
  21. //設定百分比格式--使用自定義的格式
  22. cell=row.createCell(3);
  23. cell.setCellValue(0.123456789);
  24. style=workbook.createCellStyle();
  25. style.setDataFormat(workbook.createDataFormat().getFormat("0.00%"));
  26. cell.setCellStyle(style);
  27. //設定中文大寫格式--使用自定義的格式
  28. cell=row.createCell(4);
  29. cell.setCellValue(12345);
  30. style=workbook.createCellStyle();
  31. style.setDataFormat(workbook.createDataFormat().getFormat("[DbNum2][$-804]0"));
  32. cell.setCellStyle(style);
  33. //設定科學計數法格式--使用自定義的格式
  34. cell=row.createCell(5);
  35. cell.setCellValue(12345);
  36. style=workbook.createCellStyle();
  37. style.setDataFormat(workbook.createDataFormat().getFormat("0.00E+00"));
  38. cell.setCellStyle(style);

     HSSFDataFormat.getFormat和HSSFDataFormat.getBuiltinFormat的區別: 當使用Excel內嵌的(或者說預定義)的格式時,直接用HSSFDataFormat.getBuiltinFormat靜態方法即可。當使用自己定義的格式時,必須先呼叫HSSFWorkbook.createDataFormat(),因為這時在底層會先找有沒有匹配的內嵌FormatRecord,如果沒有就會新建一個FormatRecord,所以必須先呼叫這個方法,然後你就可以用獲得的HSSFDataFormat例項的getFormat方法了,當然相對而言這種方式比較麻煩,所以內嵌格式還是用HSSFDataFormat.getBuiltinFormat靜態方法更加直接一些。

(2)合併單元格

  1. HSSFSheet sheet = workbook.createSheet("Test");// 建立工作表(Sheet)
  2. HSSFRow row=sheet.createRow(0);
  3. //合併列
  4. HSSFCell cell=row.createCell(0);
  5. cell.setCellValue("合併列");
  6. CellRangeAddress region=new CellRangeAddress(0, 0, 0, 5);
  7. sheet.addMergedRegion(region);
  8. //合併行
  9. cell=row.createCell(6);
  10. cell.setCellValue("合併行");
  11. region=new CellRangeAddress(0, 5, 6, 6);
  12. sheet.addMergedRegion(region);

     CellRangeAddress物件其實就是表示一個區域,其構造方法如下:CellRangeAddress(firstRow, lastRow, firstCol, lastCol),引數的說明:

  1. firstRow 區域中第一個單元格的行號
  2. lastRow 區域中最後一個單元格的行號
  3. firstCol 區域中第一個單元格的列號
  4. lastCol 區域中最後一個單元格的列號

     提示: 即使你沒有用CreateRow和CreateCell建立過行或單元格,也完全可以直接建立區域然後把這一區域合併,Excel的區域合併資訊是單獨儲存的,和RowRecord、ColumnInfoRecord不存在直接關係。

(3)單元格對齊

  1. HSSFCell cell=row.createCell(0);
  2. cell.setCellValue("單元格對齊");
  3. HSSFCellStyle style=workbook.createCellStyle();
  4. style.setAlignment(HSSFCellStyle.ALIGN_CENTER);//水平居中
  5. style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);//垂直居中
  6. style.setWrapText(true);//自動換行
  7. style.setIndention((short)5);//縮排
  8. style.setRotation((short)60);//文字旋轉,這裡的取值是從-90到90,而不是0-180度。
  9. cell.setCellStyle(style);

     水平對齊相關引數

  1. 如果是左側對齊就是 HSSFCellStyle.ALIGN_FILL;
  2. 如果是居中對齊就是 HSSFCellStyle.ALIGN_CENTER;
  3. 如果是右側對齊就是 HSSFCellStyle.ALIGN_RIGHT;
  4. 如果是跨列舉中就是 HSSFCellStyle.ALIGN_CENTER_SELECTION;
  5. 如果是兩端對齊就是 HSSFCellStyle.ALIGN_JUSTIFY;
  6. 如果是填充就是 HSSFCellStyle.ALIGN_FILL;

     垂直對齊相關引數

  1. 如果是靠上就是 HSSFCellStyle.VERTICAL_TOP;
  2. 如果是居中就是 HSSFCellStyle.VERTICAL_CENTER;
  3. 如果是靠下就是 HSSFCellStyle.VERTICAL_BOTTOM;
  4. 如果是兩端對齊就是 HSSFCellStyle.VERTICAL_JUSTIFY;

(4)使用邊框

     邊框和其他單元格設定一樣也是呼叫CellStyle介面,CellStyle有2種和邊框相關的屬性,分別是:

邊框相關屬性

說明

範例

Border+ 方向

邊框型別

BorderLeft, BorderRight 等

方向 +BorderColor

邊框顏色

TopBorderColor,BottomBorderColor 等

  1. HSSFCell cell=row.createCell(1);
  2. cell.setCellValue("設定邊框");
  3. HSSFCellStyle style=workbook.createCellStyle();
  4. style.setBorderTop(HSSFCellStyle.BORDER_DOTTED);//上邊框
  5. style.setBorderBottom(HSSFCellStyle.BORDER_THICK);//下邊框
  6. style.setBorderLeft(HSSFCellStyle.BORDER_DOUBLE);//左邊框
  7. style.setBorderRight(HSSFCellStyle.BORDER_SLANTED_DASH_DOT);//右邊框
  8. style.setTopBorderColor(HSSFColor.RED.index);//上邊框顏色
  9. style.setBottomBorderColor(HSSFColor.BLUE.index);//下邊框顏色
  10. style.setLeftBorderColor(HSSFColor.GREEN.index);//左邊框顏色
  11. style.setRightBorderColor(HSSFColor.PINK.index);//右邊框顏色
  12. cell.setCellStyle(style);

     其中邊框型別分為以下幾種:

邊框範例圖

對應的靜態值

HSSFCellStyle. BORDER_DOTTED

HSSFCellStyle. BORDER_HAIR

HSSFCellStyle. BORDER_DASH_DOT_DOT

HSSFCellStyle. BORDER_DASH_DOT

HSSFCellStyle. BORDER_DASHED

HSSFCellStyle. BORDER_THIN

HSSFCellStyle. BORDER_MEDIUM_DASH_DOT_DOT

HSSFCellStyle. BORDER_SLANTED_DASH_DOT

HSSFCellStyle. BORDER_MEDIUM_DASH_DOT

HSSFCellStyle. BORDER_MEDIUM_DASHED

HSSFCellStyle. BORDER_MEDIUM

HSSFCellStyle. BORDER_THICK

HSSFCellStyle. BORDER_DOUBLE

(5)設定字型

  1. HSSFCell cell = row.createCell(1);
  2. cell.setCellValue("設定字型");
  3. HSSFCellStyle style = workbook.createCellStyle();
  4. HSSFFont font = workbook.createFont();
  5. font.setFontName("華文行楷");//設定字型名稱
  6. font.setFontHeightInPoints((short)28);//設定字號
  7. font.setColor(HSSFColor.RED.index);//設定字型顏色
  8. font.setUnderline(FontFormatting.U_SINGLE);//設定下劃線
  9. font.setTypeOffset(FontFormatting.SS_SUPER);//設定上標下標
  10. font.setStrikeout(true);//設定刪除線
  11. style.setFont(font);
  12. cell.setCellStyle(style);

下劃線選項值:

單下劃線 FontFormatting.U_SINGLE

雙下劃線 FontFormatting.U_DOUBLE

會計用單下劃線 FontFormatting.U_SINGLE_ACCOUNTING

會計用雙下劃線 FontFormatting.U_DOUBLE_ACCOUNTING

無下劃線 FontFormatting.U_NONE

     上標下標選項值:

上標 FontFormatting.SS_SUPER

下標 FontFormatting.SS_SUB

普通,預設值 FontFormatting.SS_NONE

(6)背景和紋理

  1. HSSFCellStyle style = workbook.createCellStyle();
  2. style.setFillForegroundColor(HSSFColor.GREEN.index);//設定圖案顏色
  3. style.setFillBackgroundColor(HSSFColor.RED.index);//設定圖案背景色
  4. style.setFillPattern(HSSFCellStyle.SQUARES);//設定圖案樣式
  5. cell.setCellStyle(style);

     圖案樣式及其對應的值:

圖案樣式

常量

HSSFCellStyle. NO_FILL

HSSFCellStyle. ALT_BARS

HSSFCellStyle. FINE_DOTS

HSSFCellStyle. SPARSE_DOTS

HSSFCellStyle. LESS_DOTS

HSSFCellStyle. LEAST_DOTS

HSSFCellStyle. BRICKS

HSSFCellStyle. BIG_SPOTS

HSSFCellStyle. THICK_FORWARD_DIAG

HSSFCellStyle. THICK_BACKWARD_DIAG

HSSFCellStyle. THICK_VERT_BANDS

HSSFCellStyle. THICK_HORZ_BANDS

HSSFCellStyle. THIN_HORZ_BANDS

HSSFCellStyle. THIN_VERT_BANDS

HSSFCellStyle. THIN_BACKWARD_DIAG

HSSFCellStyle. THIN_FORWARD_DIAG

HSSFCellStyle. SQUARES

HSSFCellStyle. DIAMONDS

(7)設定寬度和高度

  1. HSSFSheet sheet = workbook.createSheet("Test");// 建立工作表(Sheet)
  2. HSSFRow row = sheet.createRow(1);
  3. HSSFCell cell = row.createCell(1);
  4. cell.setCellValue("123456789012345678901234567890");
  5. sheet.setColumnWidth(1, 31 * 256);//設定第一列的寬度是31個字元寬度
  6. row.setHeightInPoints(50);//設定行的高度是50個點

     這裡你會發現一個有趣的現象,setColumnWidth的第二個引數要乘以256,這是怎麼回事呢?其實,這個引數的單位是1/256個字元寬度,也就是說,這裡是把B列的寬度設定為了31個字元。

     設定行高使用HSSFRow物件的setHeight和setHeightInPoints方法,這兩個方法的區別在於setHeightInPoints的單位是點,而setHeight的單位是1/20個點,所以setHeight的值永遠是setHeightInPoints的20倍。

     你也可以使用HSSFSheet.setDefaultColumnWidth、HSSFSheet.setDefaultRowHeight和HSSFSheet.setDefaultRowHeightInPoints方法設定預設的列寬或行高。

(8)判斷單元格是否為日期

     判斷單元格是否為日期型別,使用DateUtil.isCellDateFormatted(cell)方法,例如:

  1. HSSFCell cell = row.createCell(1);
  2. cell.setCellValue(new Date());//設定日期資料
  3. System.out.println(DateUtil.isCellDateFormatted(cell));//輸出:false
  4. HSSFCellStyle style =workbook.createCellStyle();
  5. style.setDataFormat(HSSFDataFormat.getBuiltinFormat("m/d/yy h:mm"));
  6. cell.setCellStyle(style);//設定日期樣式
  7. System.out.println(DateUtil.isCellDateFormatted(cell));//輸出:true

4.使用Excel公式

(1)基本計算

  1. HSSFSheet sheet = workbook.createSheet("Test");// 建立工作表(Sheet)
  2. HSSFRow row = sheet.createRow(0);
  3. HSSFCell cell = row.createCell(0);
  4. cell.setCellFormula("2+3*4");//設定公式
  5. cell = row.createCell(1);
  6. cell.setCellValue(10);
  7. cell = row.createCell(2);
  8. cell.setCellFormula("A1*B1");//設定公式

(2)SUM函式

  1. HSSFSheet sheet = workbook.createSheet("Test");// 建立工作表(Sheet)
  2. HSSFRow row = sheet.createRow(0);
  3. row.createCell(0).setCellValue(1);
  4. row.createCell(1).setCellValue(2);
  5. row.createCell(2).setCellValue(3);
  6. row.createCell(3).setCellValue(4);
  7. row.createCell(4).setCellValue(5);
  8. row = sheet.createRow(1);
  9. row.createCell(0).setCellFormula("sum(A1,C1)");//等價於"A1+C1"
  10. row.createCell(1).setCellFormula("sum(B1:D1)");//等價於"B1+C1+D1"

(3)日期函式

  1. HSSFSheet sheet = workbook.createSheet("Test");// 建立工作表(Sheet)
  2. HSSFCellStyle style=workbook.createCellStyle();
  3. style.setDataFormat(workbook.createDataFormat().getFormat("yyyy-mm-dd"));
  4. HSSFRow row = sheet.createRow(0);
  5. Calendar date=Calendar.getInstance();//日曆物件
  6. HSSFCell cell=row.createCell(0);
  7. date.set(2011,2, 7);
  8. cell.setCellValue(date.getTime());
  9. cell.setCellStyle(style);//第一個單元格開始時間設定完成
  10. cell=row.createCell(1);
  11. date.set(2014,4, 25);
  12. cell.setCellValue(date.getTime());
  13. cell.setCellStyle(style);//第一個單元格結束時間設定完成
  14. cell=row.createCell(3);
  15. cell.setCellFormula("CONCATENATE(DATEDIF(A1,B1,\"y\"),\"年\")");
  16. cell=row.createCell(4);
  17. cell.setCellFormula("CONCATENATE(DATEDIF(A1,B1,\"m\"),\"月\")");
  18. cell=row.createCell(5);
  19. cell.setCellFormula("CONCATENATE(DATEDIF(A1,B1,\"d\"),\"日\")");

    

以上程式碼中的公式說明:

     DATEDIF(A1,B1,\"y\") :取得 A1 單元格的日期與 B1 單元格的日期的時間間隔。 ( “ y ” : 表示以年為單位 , ” m ”表示以月為單位 ; ” d ”表示以天為單位 ) 。

 

          CONCATENATE( str1,str2, … ) :連線字串。

          更多 Excel 的日期函式可參考:http://tonyqus.sinaapp.com/archives/286

(4)字串相關函式

  1. HSSFSheet sheet = workbook.createSheet("Test");// 建立工作表(Sheet)
  2. HSSFRow row = sheet.createRow(0);
  3. row.createCell(0).setCellValue("abcdefg");
  4. row.createCell(1).setCellValue("aa bb cc dd ee fF GG");
  5. row.createCell(3).setCellFormula("UPPER(A1)");
  6. row.createCell(4).setCellFormula("PROPER(B1)");

    

以上程式碼中的公式說明:

     UPPER( String ) :將文字轉換成大寫形式。

 

          PROPER( String ) :將文字串的首字母及任何非字母字元之後的首字母轉換成大寫。將其餘的字母轉換成小寫。

          更多 Excel 的字串函式可參考:http://tonyqus.sinaapp.com/archives/289

(5)IF函式

  1. HSSFSheet sheet = workbook.createSheet("Test");// 建立工作表(Sheet)
  2. HSSFRow row = sheet.createRow(0);
  3. row.createCell(0).setCellValue(12);
  4. row.createCell(1).setCellValue(23);
  5. row.createCell(3).setCellFormula("IF(A1>B1,\"A1大於B1\",\"A1小於等於B1\")");

     以上程式碼中的公式說明:

          IF(logical_test,value_if_true,value_if_false)用來用作邏輯判斷。其中Logical_test表示計算結果為 TRUE 或 FALSE 的任意值或表示式 ; value_if_true表示當表示式Logical_test的值為TRUE時的返回值;value_if_false表示當表示式Logical_test的值為FALSE時的返回值。

(6)CountIf和SumIf函式

  1. HSSFSheet sheet = workbook.createSheet("Test");// 建立工作表(Sheet)
  2. HSSFRow row = sheet.createRow(0);
  3. row.createCell(0).setCellValue(57);
  4. row.createCell(1).setCellValue(89);
  5. row.createCell(2).setCellValue(56);
  6. row.createCell(3).setCellValue(67);
  7. row.createCell(4).setCellValue(60);
  8. row.createCell(5).setCellValue(73);
  9. row.createCell(7).setCellFormula("COUNTIF(A1:F1,\">=60\")");
  10. row.createCell(8).setCellFormula("SUMIF(A1:F1,\">=60\",A1:F1)");

     以上程式碼中的公式說明:

          COUNTIF(range,criteria):滿足某條件的計數的函式。引數range:需要進行讀數的計數;引數criteria:條件表示式,只有當滿足此條件時才進行計數。

          SumIF(criteria_range, criteria,sum_range):用於統計某區域內滿足某條件的值的求和。引數criteria_range:條件測試區域,第二個引數Criteria中的條件將與此區域中的值進行比較;引數criteria:條件測試值,滿足條件的對應的sum_range項將進行求和計算;引數sum_range:彙總資料所在區域,求和時會排除掉不滿足Criteria條件的對應的項。

(7)Lookup函式

  1. HSSFSheet sheet = workbook.createSheet("Test");// 建立工作表(Sheet)
  2. HSSFRow row = sheet.createRow(0);
  3. row.createCell(0).setCellValue(0);
  4. row.createCell(1).setCellValue(59);
  5. row.createCell(2).setCellValue("不及格");
  6. row = sheet.createRow(1);
  7. row.createCell(0).setCellValue(60);
  8. row.createCell(1).setCellValue(69);
  9. row.createCell(2).setCellValue("及格");
  10. row = sheet.createRow(2);
  11. row.createCell(0).setCellValue(70);
  12. row.createCell(1).setCellValue(79);
  13. row.createCell(2).setCellValue("良好");
  14. row = sheet.createRow(3);
  15. row.createCell(0).setCellValue(80);
  16. row.createCell(1).setCellValue(100);
  17. row.createCell(2).setCellValue("優秀");
  18. row = sheet.createRow(4);
  19. row.createCell(0).setCellValue(75);
  20. row.createCell(1).setCellFormula("LOOKUP(A5,$A$1:$A$4,$C$1:$C$4)");
  21. row.createCell(2).setCellFormula("VLOOKUP(A5,$A$1:$C$4,3,true)");

    

以上程式碼中的公式說明:

     LOOKUP(lookup_value,lookup_vector,result_vector) ,第一個引數:需要查詢的內容,本例中指向 A5 單元格,也就是 75 ;第二個引數:比較物件區域,本例中的成績需要與 $A$1:$A$4 中的各單元格中的值進行比較;第三個引數:查詢結果區域,如果匹配到會將此區域中對應的資料返回。如本例中返回$C$1:$C$4 中對應的值。

 

 

可能有人會問,字典中沒有 75 對應的成績啊,那麼 Excel 中怎麼匹配的呢?答案是模糊匹配,並且 LOOKUP 函式只支援模糊匹配。 Excel 會在 $A$1:$A$4 中找小於 75 的最大值,也就是 A3 對應的 70 ,然後將對應的 $C$1:$C$4 區域中的 C3 中的值返回,這就是最終結果“良好”的由來。

     VLOOKUP(lookup_value,lookup_area,result_col,is_fuzzy ) ,第一個引數:需要查詢的內容,這裡是 A5 單元格;第二個引數:需要比較的表,這裡是 $A$1:$C$4 ,注意 VLOOKUP 匹配時只與表中的第一列進行匹配。第三個引數:匹配結果對應的列序號。這裡要對應的是成績列,所以為 3 。第四個引數:指明是否模糊匹配。例子中的 TRUE 表示模糊匹配,與上例中一樣。匹配到的是第三行。如果將此引數改為 FALSE ,因為在表中的第 1 列中找不到 75 ,所以會報“#N/A ”的計算錯誤。

 

另外,還有與 VLOKUP 類似的 HLOOKUP 。不同的是 VLOOKUP 用於在表格或數值陣列的首列查詢指定的數值,並由此返回表格或陣列當前行中指定列處的數值。而HLOOKUP 用於在表格或數值陣列的首行查詢指定的數值,並由此返回表格或陣列當前列中指定行處的數值。讀者可以自已去嘗試。

(8)隨機數函式

  1. HSSFSheet sheet = workbook.createSheet("Test");// 建立工作表(Sheet)
  2. HSSFRow row = sheet.createRow(0);
  3. row.createCell(0).setCellFormula("RAND()");//取0-1之間的隨機數
  4. row.createCell(1).setCellFormula("int(RAND()*100)");//取0-100之間的隨機整數
  5. row.createCell(2).setCellFormula("rand()*10+10");//取10-20之間的隨機實數
  6. row.createCell(3).setCellFormula("CHAR(INT(RAND()*26)+97)");//隨機小寫字母
  7. row.createCell(4).setCellFormula("CHAR(INT(RAND()*26)+65)");//隨機大寫字母
  8. //隨機大小寫字母
  9. row.createCell(5).setCellFormula("CHAR(INT(RAND()*26)+if(INT(RAND()*2)=0,97,65))");

     以上程式碼中的公式說明:

          上面幾例中除了用到RAND函式以外,還用到了CHAR函式用來將ASCII碼換為字母,INT函式用來取整。值得注意的是INT函式不會四捨五入,無論小數點後是多少都會被捨去。

(9)獲得公式的返回值

  1. HSSFSheet sheet = workbook.createSheet("Test");// 建立工作表(Sheet)
  2. HSSFRow row = sheet.createRow(0);
  3. row.createCell(0).setCellValue(7);//A1
  4. row.createCell(1).setCellValue(8);//B1
  5. HSSFCell cell=row.createCell(2);
  6. cell.setCellFormula("A1*B1+14");
  7. HSSFFormulaEvaluator e = newHSSFFormulaEvaluator(workbook);
  8. cell = e.evaluateInCell(cell);//若Excel檔案不是POI建立的,則不必呼叫此方法
  9. System.out.println("公式計算結果:"+cell.getNumericCellValue());

5.使用圖形

(1)畫線

  1. HSSFSheet sheet = workbook.createSheet("Test");// 建立工作表(Sheet)
  2. HSSFPatriarch patriarch=sheet.createDrawingPatriarch();
  3. HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 0, 0,(short)1, 0,(short)4, 4);
  4. HSSFSimpleShape line = patriarch.createSimpleShape(anchor);
  5. line.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);//設定圖形型別
  6. line.setLineStyle(HSSFShape.LINESTYLE_SOLID);//設定圖形樣式
  7. line.setLineWidth(6350);//在POI中線的寬度12700表示1pt,所以這裡是0.5pt粗的線條。

     通常,利用POI畫圖主要有以下幾個步驟:

          1. 建立一個Patriarch(注意,一個sheet中通常只建立一個Patriarch物件);

          2. 建立一個Anchor,以確定圖形的位置;

          3. 呼叫Patriarch建立圖形;

          4. 設定圖形型別(直線,矩形,圓形等)及樣式(顏色,粗細等)。

     關於HSSFClientAnchor(dx1,dy1,dx2,dy2,col1,row1,col2,row2)的引數,有必要在這裡說明一下:

          dx1:起始單元格的x偏移量,如例子中的0表示直線起始位置距B1單元格左側的距離;

          dy1:起始單元格的y偏移量,如例子中的0表示直線起始位置距B1單元格上側的距離;

          dx2:終止單元格的x偏移量,如例子中的0表示直線起始位置距E5單元格左側的距離;

          dy2:終止單元格的y偏移量,如例子中的0表示直線起始位置距E5單元格上側的距離;

          col1:起始單元格列序號,從0開始計算;

          row1:起始單元格行序號,從0開始計算,如例子中col1=1,row1=0就表示起始單元格為B1;

          col2:終止單元格列序號,從0開始計算;

          row2:終止單元格行序號,從0開始計算,如例子中col2=4,row2=4就表示起始單元格為E5;

     最後,關於LineStyle屬性,有如下一些可選值,對應的效果分別如圖所示:

(2)畫矩形

  1. HSSFSheet sheet = workbook.createSheet("Test");// 建立工作表(Sheet)
  2. HSSFPatriarch patriarch=sheet.createDrawingPatriarch();
  3. HSSFClientAnchor anchor = new HSSFClientAnchor(255,122,255, 122, (short)1, 0,(short)4, 3);
  4. HSSFSimpleShape rec = patriarch.createSimpleShape(anchor);
  5. rec.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE);
  6. rec.setLineStyle(HSSFShape.LINESTYLE_DASHGEL);//設定邊框樣式
  7. rec.setFillColor(255, 0, 0);//設定填充色
  8. rec.setLineWidth(25400);//設定邊框寬度
  9. rec.setLineStyleColor(0, 0, 255);//設定邊框顏色

(3)畫圓形

     更改上例的程式碼如下:

         rec.setShapeType(HSSFSimpleShape.OBJECT_TYPE_OVAL);//設定圖片型別

(4)畫Grid

     在POI中,本身沒有畫Grid(網格)的方法。但我們知道Grid其實就是由橫線和豎線構成的,所在我們可以通過畫線的方式來模擬畫Grid。程式碼如下:

  1. HSSFSheet sheet = workbook.createSheet("Test");// 建立工作表(Sheet)
  2. HSSFRow row = sheet.createRow(2);
  3. row.createCell(1);
  4. row.setHeightInPoints(240);
  5. sheet.setColumnWidth(2, 9000);
  6. int linesCount = 20;
  7. HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
  8. //因為HSSFClientAnchor中dx只能在0-1023之間,dy只能在0-255之間,這裡採用比例的方式
  9. double xRatio = 1023.0 / (linesCount * 10);
  10. double yRatio = 255.0 / (linesCount * 10);
  11. // 畫豎線
  12. int x1 = 0;
  13. int y1 = 0;
  14. int x2 = 0;
  15. int y2 = 200;
  16. for (int i = 0; i < linesCount; i++)
  17. {
  18.  HSSFClientAnchor a2 = new HSSFClientAnchor();
  19. a2.setAnchor((short) 2, 2, (int) (x1 * xRatio),
  20.  (int) (y1 * yRatio), (short) 2, 2, (int) (x2 * xRatio),
  21.  (int) (y2 * yRatio));
  22.  HSSFSimpleShape shape2 = patriarch.createSimpleShape(a2);
  23. shape2.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);
  24. x1 += 10;
  25. x2 += 10;
  26. }
  27. // 畫橫線
  28. x1 = 0;
  29. y1 = 0;
  30. x2 = 200;
  31. y2 = 0;
  32. for (int i = 0; i < linesCount; i++)
  33. {
  34.  HSSFClientAnchor a2 = new HSSFClientAnchor();
  35. a2.setAnchor((short) 2, 2, (int) (x1 * xRatio),
  36.  (int) (y1 * yRatio), (short) 2, 2, (int) (x2 * xRatio),
  37.  (int) (y2 * yRatio));
  38.  HSSFSimpleShape shape2 = patriarch.createSimpleShape(a2);
  39. shape2.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);
  40. y1 += 10;
  41. y2 += 10;
  42. }

(5)插入圖片

  1. HSSFSheet sheet = workbook.createSheet("Test");// 建立工作表(Sheet)
  2. FileInputStream stream=newFileInputStream("d:\\POI\\Apache.gif");
  3. byte[] bytes=new byte[(int)stream.getChannel().size()];
  4. stream.read(bytes);//讀取圖片到二進位制陣列
  5. int pictureIdx = workbook.addPicture(bytes,HSSFWorkbook.PICTURE_TYPE_JPEG);
  6. HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
  7. HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 0, 0,(short)0, 0, (short)5, 5);
  8. HSSFPicture pict = patriarch.createPicture(anchor,pictureIdx);
  9. //pict.resize();//自動調節圖片大小,圖片位置資訊可能丟失

(6)從Excel檔案提取圖片

  1. InputStream inp = new FileInputStream(filePath);
  2. HSSFWorkbook workbook = new HSSFWorkbook(inp);//讀取現有的Excel檔案
  3. List<HSSFPictureData> pictures = workbook.getAllPictures();
  4. for(int i=0;i<pictures.size();i++)
  5. {
  6.  HSSFPictureData pic=pictures.get(i);
  7.  String ext = pic.suggestFileExtension();
  8.  if (ext.equals("png"))//判斷檔案格式
  9.  {
  10.  FileOutputStream png=newFileOutputStream("d:\\POI\\Apache.png");
  11. png.write(pic.getData());
  12. png.close();//儲存圖片
  13.  }
  14. }

6.Excel表操作

(1)設定預設工作表

  1. HSSFWorkbook workbook = new HSSFWorkbook();// 建立Excel檔案(Workbook)
  2. workbook.createSheet("Test0");// 建立工作表(Sheet)
  3. workbook.createSheet("Test1");// 建立工作表(Sheet)
  4. workbook.createSheet("Test2");// 建立工作表(Sheet)
  5. workbook.createSheet("Test3");// 建立工作表(Sheet)
  6. workbook.setActiveSheet(2);//設定預設工作表

(2)重新命名工作表

  1. HSSFWorkbook workbook = new HSSFWorkbook();// 建立Excel檔案(Workbook)
  2. workbook.createSheet("Test0");// 建立工作表(Sheet)
  3. workbook.createSheet("Test1");// 建立工作表(Sheet)
  4. workbook.createSheet("Test2");// 建立工作表(Sheet)
  5. workbook.createSheet("Test3");// 建立工作表(Sheet)
  6. workbook.setSheetName(2, "1234");//重新命名工作表

(3)調整表單顯示比例

  1. HSSFWorkbook workbook = new HSSFWorkbook();// 建立Excel檔案(Workbook)
  2. HSSFSheet sheet1= workbook.createSheet("Test0");// 建立工作表(Sheet)
  3. HSSFSheet sheet2=workbook.createSheet("Test1");// 建立工作表(Sheet)
  4. HSSFSheet sheet3=workbook.createSheet("Test2");// 建立工作表(Sheet)
  5. sheet1.setZoom(1,2);//50%顯示比例
  6. sheet2.setZoom(2,1);//200%顯示比例
  7. sheet3.setZoom(1,10);//10%顯示比例

(4)顯示/隱藏網格線

  1. HSSFWorkbook workbook = new HSSFWorkbook();// 建立Excel檔案(Workbook)
  2. HSSFSheet sheet1= workbook.createSheet("Test0");// 建立工作表(Sheet)
  3. HSSFSheet sheet2=workbook.createSheet("Test1");// 建立工作表(Sheet)
  4. sheet1.setDisplayGridlines(false);//隱藏Excel網格線,預設值為true
  5. sheet2.setGridsPrinted(true);//列印時顯示網格線,預設值為false

(5)遍歷Sheet

  1. String filePath = "d:\\users\\lizw\\桌面\\POI\\sample.xls";
  2. FileInputStream stream = new FileInputStream(filePath);
  3. HSSFWorkbook workbook = new HSSFWorkbook(stream);//讀取現有的Excel
  4. HSSFSheet sheet= workbook.getSheet("Test0");//得到指定名稱的Sheet
  5. for (Row row : sheet)
  6. {
  7.  for (Cell cell : row)
  8.  {
  9.  System.out.print(cell + "\t");
  10.  }
  11.  System.out.println();
  12. }

7.Excel行列操作

(1)組合行、列

  1. HSSFSheet sheet= workbook.createSheet("Test0");// 建立工作表(Sheet)
  2. sheet.groupRow(1, 3);//組合行
  3. sheet.groupRow(2, 4);//組合行
  4. sheet.groupColumn(2, 7);//組合列

     這裡簡單的介紹一下什麼叫做組合:組合分為行組合和列組合,所謂行組合,就是讓n行組合成一個集合,能夠進行展開和合攏操作。

     使用POI也可以取消組合,例如:sheet.ungroupColumn(1, 3);//取消列組合

(2)鎖定列

     在Excel中,有時可能會出現列數太多或是行數太多的情況,這時可以通過鎖定列來凍結部分列,不隨滾動條滑動,方便檢視。

  1. HSSFSheet sheet= workbook.createSheet("Test0");// 建立工作表(Sheet)
  2. sheet.createFreezePane(2, 3, 15, 25);//凍結行列

     下面對CreateFreezePane的引數作一下說明:

          第一個引數表示要凍結的列數;

          第二個引數表示要凍結的行數,這裡只凍結列所以為0;

          第三個引數表示右邊區域可見的首列序號,從1開始計算;

          第四個引數表示下邊區域可見的首行序號,也是從1開始計算,這裡是凍結列,所以為0;

(3)上下移動行

  1. FileInputStream stream = new FileInputStream(filePath);
  2. HSSFWorkbook workbook = new HSSFWorkbook(stream);
  3. HSSFSheet sheet = workbook.getSheet("Test0");
  4. sheet.shiftRows(2, 4, 2);//把第3行到第4行向下移動兩行

     HSSFSheet.shiftRows(startRow, endRow, n)引數說明

          startRow:需要移動的起始行;

          endRow:需要移動的結束行;

          n:移動的位置,正數表示向下移動,負數表示向上移動;

 

8.Excel的其他功能

(1)設定密碼

  1. HSSFSheet sheet= workbook.createSheet("Test0");// 建立工作表(Sheet)
  2. HSSFRow row=sheet.createRow(1);
  3. HSSFCell cell=row.createCell(1);
  4. cell.setCellValue("已鎖定");
  5. HSSFCellStyle locked = workbook.createCellStyle();
  6. locked.setLocked(true);//設定鎖定
  7. cell.setCellStyle(locked);
  8. cell=row.createCell(2);
  9. cell.setCellValue("未鎖定");
  10. HSSFCellStyle unlocked = workbook.createCellStyle();
  11. unlocked.setLocked(false);//設定不鎖定
  12. cell.setCellStyle(unlocked);
  13. sheet.protectSheet("password");//設定保護密碼

(2)資料有效性

  1. HSSFSheet sheet= workbook.createSheet("Test0");// 建立工作表(Sheet)
  2. HSSFRow row=sheet.createRow(0);
  3. HSSFCell cell=row.createCell(0);
  4. cell.setCellValue("日期列");
  5. CellRangeAddressList regions = new CellRangeAddressList(1, 65535,0, 0);//選定一個區域
  6. DVConstraint constraint = DVConstraint.createDateConstraint(DVConstraint . OperatorType . BETWEEN , "1993-01-01" ,"2014-12-31" , "yyyy-MM-dd" );
  7. HSSFDataValidation dataValidate = new HSSFDataValidation(regions,constraint);<