轉(zhuǎn)自鏈接
2.3.6 CountIf和SumIf函數(shù)
2.3.9通過NPOI獲得公式的返回值
2.4創(chuàng)建圖形
2.4.4畫Grid
2.6
高級功能
2.6.5顯示/隱藏網(wǎng)格線
2.3.5用NPOI操作EXCEL--If函數(shù)
在Excel中,IF(logical_test,value_if_true,value_if_false)用來用作邏輯判斷艰猬。其中Logical_test表示計算結(jié)果為TRUE或FALSE的任意值或表達(dá)式; value_if_true表示當(dāng)表達(dá)式Logical_test的值為TRUE時的返回值驻债;value_if_false表示當(dāng)表達(dá)式Logical_test的值為FALSE時的返回值敞临。同樣在NPOI中也可以利用這個表達(dá)式進(jìn)行各種邏輯運算扮授。如下代碼分別設(shè)置了B2和D2單元格的用于邏輯判斷的公式闸天。
HSSFSheet?sheet1?=?hssfworkbook.CreateSheet("Sheet1");
HSSFRow?row1?=?sheet1.CreateRow(
0);
row1.CreateCell(
0).SetCellValue("姓名");
row1.CreateCell(
1).SetCellValue("身份證號");
row1.CreateCell(
2).SetCellValue("性別");
row1.CreateCell(
3).SetCellValue("語文");
row1.CreateCell(
4).SetCellValue("是否合格");
HSSFRow?row2?=?sheet1.CreateRow(
1);
row2.CreateCell(
0).SetCellValue("令狐沖");
row2.CreateCell(
1).SetCellValue("420821198808101014");
row2.CreateCell(
2).SetCellFormula("IF(MOD(MID(B2,18,1),2)=0,\"男\(zhòng)",\"女\")");
row2.CreateCell(
3).SetCellValue(85);
row2.CreateCell(
4).SetCellFormula("IF(D2>60,IF(D2>90,\"優(yōu)秀\",\"合格\"),\"不合格\")");
其中最關(guān)鍵的兩句執(zhí)行結(jié)果如下:
row2.CreateCell(2).SetCellFormula("IF(MOD(MID(B2,18,1),2)=0,\"男\(zhòng)",\"女\")");
row2.CreateCell(4).SetCellFormula("IF(D2>60,IF(D2>90,\"優(yōu)秀\",\"合格\"),\"不合格\")");
下面分別對這幾個函數(shù)作一些說明:
MOD(MID(B2,18,1),2)
:我們知道18位身份證號的第18位表示性別犬绒,偶數(shù)為男性,奇數(shù)為女性挂签,所以用了MID(B2,18,1)取第18位數(shù)字(與C#中一般從0計數(shù)不同疤祭,第二個參數(shù)是從1算起,有關(guān)MID函數(shù)的更多信息饵婆,請參見字符串函數(shù))勺馆,用MOD取余函數(shù)判斷奇偶。在Excel中對數(shù)據(jù)類型的控制沒有C#中那么嚴(yán)格侨核,如此例中我截取出來的是字符串草穆,但當(dāng)我做取余運算時Excel會自動轉(zhuǎn)換。
IF(D2>60,IF(D2>90,"
優(yōu)秀","合格"),"不合格"):這是IF的嵌套使用搓译,表示90分以上為優(yōu)秀悲柱,60分以上為合格,否則為不合格些己。
2.3.6用NPOI操作EXCEL--COUNTIF和SUMIF函數(shù)
一豌鸡、COUNTIF這一節(jié),我們一起來學(xué)習(xí)Excel中另一個常用的函數(shù)--COUNTIF函數(shù)段标,看函數(shù)名就知道這是一個用來在做滿足某條件的計數(shù)的函數(shù)涯冠。先來看一看它的語法:COUNTIF(range,criteria),參數(shù)說明如下:
Range需要進(jìn)行讀數(shù)的計數(shù)
Criteria條件表達(dá)式逼庞,只有當(dāng)滿足此條件時才進(jìn)行計數(shù)
接下來看一個例子蛇更,代碼如下:
HSSFSheet?sheet1?=?hssfworkbook.CreateSheet("Sheet1");
HSSFRow?row1?=?sheet1.CreateRow(
0);
row1.CreateCell(
0).SetCellValue("姓名");
row1.CreateCell(
1).SetCellValue("成績");
HSSFRow?row2?=?sheet1.CreateRow(
1);
row2.CreateCell(
0).SetCellValue("令狐沖");
row2.CreateCell(
1).SetCellValue(85);
HSSFRow?row3?=?sheet1.CreateRow(
2);
row3.CreateCell(
0).SetCellValue("任盈盈");
row3.CreateCell(
1).SetCellValue(90);
HSSFRow?row4?=?sheet1.CreateRow(
3);
row4.CreateCell(
0).SetCellValue("任我行");
row4.CreateCell(
1).SetCellValue(70);
HSSFRow?row5?=?sheet1.CreateRow(
4);
row5.CreateCell(
0).SetCellValue("左冷嬋");
row5.CreateCell(
1).SetCellValue(45);
HSSFRow?row6?=?sheet1.CreateRow(
5);
row6.CreateCell(
0).SetCellValue("岳不群");
row6.CreateCell(
1).SetCellValue(50);
HSSFRow?row7?=?sheet1.CreateRow(
6);
row7.CreateCell(
0).SetCellValue("合格人數(shù):");
row7.CreateCell(
1).SetCellFormula("COUNTIF(B2:B6,\">60\")");
執(zhí)行結(jié)果如下:
我們可以看到,CountIf函數(shù)成功的統(tǒng)計出了區(qū)域“B2:B6”中成績合格的人數(shù)(這里定義成績大于60為合格)往堡。
二械荷、SUMIF
接下來,順便談?wù)劻硪粋€與CountIF類似的函數(shù)—SumIf函數(shù)虑灰。此函數(shù)用于統(tǒng)計某區(qū)域內(nèi)滿足某條件的值的求和(CountIf是計數(shù))吨瞎。與CountIF不同,SumIF有三個參數(shù)穆咐,語法為SumIF(criteria_range, criteria,sum_range)颤诀,各參數(shù)的說明如下:
criteria_range條件測試區(qū)域,第二個參數(shù)Criteria中的條件將與此區(qū)域中的值進(jìn)行比較
criteria條件測試值对湃,滿足條件的對應(yīng)的sum_range項將進(jìn)行求和計算
sum_range匯總數(shù)據(jù)所在區(qū)域崖叫,求和時會排除掉不滿足Criteria條件的對應(yīng)的項
我們還是以例子來加以說明:
Code
HSSFSheet?sheet1?=?hssfworkbook.CreateSheet(
"Sheet1");
HSSFRow?row1?=?sheet1.CreateRow(
0);
row1.CreateCell(
0).SetCellValue("姓名");
row1.CreateCell(
1).SetCellValue("月份");
row1.CreateCell(
2).SetCellValue("銷售額");
HSSFRow?row2?=?sheet1.CreateRow(
1);
row2.CreateCell(
0).SetCellValue("令狐沖");
row2.CreateCell(
1).SetCellValue("一月");
row2.CreateCell(
2).SetCellValue(1000);
HSSFRow?row3?=?sheet1.CreateRow(
2);
row3.CreateCell(
0).SetCellValue("任盈盈");
row3.CreateCell(
1).SetCellValue("一月");
row3.CreateCell(
2).SetCellValue(900);
HSSFRow?row4?=?sheet1.CreateRow(
3);
row4.CreateCell(
0).SetCellValue("令狐沖");
row4.CreateCell(
1).SetCellValue("二月");
row4.CreateCell(
2).SetCellValue(2000);
HSSFRow?row5?=?sheet1.CreateRow(
4);
row5.CreateCell(
0).SetCellValue("任盈盈");
row5.CreateCell(
1).SetCellValue("二月");
row5.CreateCell(
2).SetCellValue(1000);
HSSFRow?row6?=?sheet1.CreateRow(
5);
row6.CreateCell(
0).SetCellValue("令狐沖");
row6.CreateCell(
1).SetCellValue("三月");
row6.CreateCell(
2).SetCellValue(3000);
HSSFRow?row7?=?sheet1.CreateRow(
6);
row7.CreateCell(
0).SetCellValue("任盈盈");
row7.CreateCell(
1).SetCellValue("三月");
row7.CreateCell(
2).SetCellValue(1200);
HSSFRow?row8?=?sheet1.CreateRow(
7);
row8.CreateCell(
0).SetCellValue("令狐沖一季度銷售額:");
row8.CreateCell(
2).SetCellFormula("SUMIF(A2:A7,\"=令狐沖\",C2:C7)");
HSSFRow?row9?=?sheet1.CreateRow(
8);
row9.CreateCell(
0).SetCellValue("任盈盈一季度銷售額:");
row9.CreateCell(
2).SetCellFormula("SUMIF(A2:A7,\"=任盈盈\",C2:C7)");
執(zhí)行結(jié)果如下:
如上圖,SUMIF統(tǒng)計出了不同人一季度的銷售額拍柒。
2.3.7用NPOI操作EXCEL--LOOKUP函數(shù)
今天心傀,我們一起學(xué)習(xí)Excel中的查詢函數(shù)--LOOKUP。其基本語法形式為LOOKUP(lookup_value,lookup_vector,result_vector)拆讯。還是以例子加以說明更容易理解:
Code
HSSFSheet?sheet1?=?hssfworkbook.CreateSheet(
"Sheet1");
HSSFRow?row1?=?sheet1.CreateRow(
0);
row1.CreateCell(
0).SetCellValue("收入最低");
row1.CreateCell(
1).SetCellValue("收入最高");
row1.CreateCell(
2).SetCellValue("稅率");
HSSFRow?row2?=?sheet1.CreateRow(
1);
row2.CreateCell(
0).SetCellValue(0);
row2.CreateCell(
1).SetCellValue(3000);
row2.CreateCell(
2).SetCellValue(0.1);
HSSFRow?row3?=?sheet1.CreateRow(
2);
row3.CreateCell(
0).SetCellValue(3001);
row3.CreateCell(
1).SetCellValue(10000);
row3.CreateCell(
2).SetCellValue(0.2);
HSSFRow?row4?=?sheet1.CreateRow(
3);
row4.CreateCell(
0).SetCellValue(10001);
row4.CreateCell(
1).SetCellValue(20000);
row4.CreateCell(
2).SetCellValue(0.3);
HSSFRow?row5?=?sheet1.CreateRow(
4);
row5.CreateCell(
0).SetCellValue(20001);
row5.CreateCell(
1).SetCellValue(50000);
row5.CreateCell(
2).SetCellValue(0.4);
HSSFRow?row6?=?sheet1.CreateRow(
5);
row6.CreateCell(
0).SetCellValue(50001);
row6.CreateCell(
2).SetCellValue(0.5);
HSSFRow?row8?=?sheet1.CreateRow(
7);
row8.CreateCell(
0).SetCellValue("收入");
row8.CreateCell(
1).SetCellValue("稅率");
HSSFRow?row9?=?sheet1.CreateRow(
8);
row9.CreateCell(
0).SetCellValue(7800);
row9.CreateCell(
1).SetCellFormula("LOOKUP(A9,$A$2:$A$6,$C$2:$C$6)");
這是一個根據(jù)工資查詢相應(yīng)稅率的例子脂男。我們首先創(chuàng)建了不同工資區(qū)間對應(yīng)稅率的字典养叛,然后根據(jù)具體的工資在字典中找出對應(yīng)的稅率。執(zhí)行后生成的Excel如下:
下面對各參數(shù)加以說明:第一個參數(shù):需要查找的內(nèi)容宰翅,本例中指向A9單元格弃甥,也就是7800;第二個參數(shù):比較對象區(qū)域汁讼,本例中的工資需要與$A$2:$A$6中的各單元格中的值進(jìn)行比較淆攻;第三個參數(shù):查找結(jié)果區(qū)域,如果匹配到會將此區(qū)域中對應(yīng)的數(shù)據(jù)返回嘿架。如本例中返回$C$2:$C$6中對應(yīng)的值瓶珊。可能有人會問眶明,字典中沒有7800對應(yīng)的稅率啊艰毒,那么Excel中怎么匹配的呢?答案是模糊匹配搜囱,并且LOOKUP函數(shù)只支持模糊匹配丑瞧。Excel會在$A$2:$A$6中找小于7800的最大值,也就是A3對應(yīng)的3001蜀肘,然后將對應(yīng)的$C$2:$C$6區(qū)域中的C3中的值返回绊汹,這就是最終結(jié)果0.2的由來。這下明白了吧:)
VLOOKUP另外扮宠,LOOKUP函數(shù)還有一位大哥--VLOOKUP西乖。兩兄弟有很多相似之處,但大哥本領(lǐng)更大坛增。Vlookup用對比數(shù)與一個“表”進(jìn)行對比获雕,而不是Lookup函數(shù)的某1列或1行,并且Vlookup可以選擇采用精確查詢或是模糊查詢方式收捣,而Lookup只有模糊查詢届案。將上例中設(shè)置公式的代碼換成:
row9.CreateCell(1).SetCellFormula("VLOOKUP(A9,$A$2:$C$6,3,TRUE)");
執(zhí)行后生成的Excel樣式如下:
第一個參數(shù):需要查找的內(nèi)容,這里是A9單元格罢艾;第二個參數(shù):需要比較的表楣颠,這里是$A$2:$C$6,注意VLOOKUP匹配時只與表中的第一列進(jìn)行匹配咐蚯。第三個參數(shù):匹配結(jié)果對應(yīng)的列序號童漩。這里要對應(yīng)的是稅率列,所以為3春锋。第四個參數(shù):指明是否模糊匹配矫膨。例子中的TRUE表示模糊匹配,與上例中一樣。匹配到的是第三行豆拨。如果將此參數(shù)改為FALSE直奋,因為在表中的第1列中找不到7800,所以會報“#N/A”的計算錯誤施禾。
另外,還有與VLOKUP類似的HLOOKUP搁胆。不同的是VLOOKUP用于在表格或數(shù)值數(shù)組的首列查找指定的數(shù)值弥搞,并由此返回表格或數(shù)組當(dāng)前行中指定列處的數(shù)值。而HLOOKUP用于在表格或數(shù)值數(shù)組的首行查找指定的數(shù)值渠旁,并由此返回表格或數(shù)組當(dāng)前列中指定行處的數(shù)值攀例。讀者可以自已去嘗試。
2.3.8用NPOI操作EXCEL--隨機數(shù)函數(shù)
我們知道顾腊,在大多數(shù)編程語言中都有隨機數(shù)函數(shù)粤铭。在Excel中,同樣存在著這樣一個函數(shù)—RAND()函數(shù)杂靶,用于生成隨機數(shù)梆惯。先來看一個最簡單的例子:
HSSFSheet?sheet1?=?hssfworkbook.CreateSheet("Sheet1");
sheet1.CreateRow(
0).CreateCell(0).SetCellFormula("RAND()");
RAND()函數(shù)將返回一個0-1之間的隨機數(shù),執(zhí)行后生成的Excel文件如下:
這只是最簡單直接的RAND()函數(shù)的應(yīng)用吗垮,只要我們稍加修改垛吗,就可以作出很多種變換。如取0-100之前的隨機整數(shù)烁登,可設(shè)置公式為:
sheet1.CreateRow(0).CreateCell(0).SetCellFormula("int(RAND()*100)");
取10-20之間的隨機實數(shù)怯屉,可設(shè)置公式為:
sheet1.CreateRow(0).CreateCell(0).SetCellFormula("rand()*(20-10)+10");
隨機小寫字母:
sheet1.CreateRow(0).CreateCell(0).SetCellFormula("CHAR(INT(RAND()*26)+97)");
隨機大寫字母:
sheet1.CreateRow(0).CreateCell(0).SetCellFormula("CHAR(INT(RAND()*26)+65)")
隨機大小寫字母:
sheet1.CreateRow(0).CreateCell(0).SetCellFormula("CHAR(INT(RAND()*26)+if(INT(RAND()*2)=0,65,97))");
上面幾例中除了用到RAND函數(shù)以外,還用到了CHAR函數(shù)用來將ASCII碼換為字母饵沧,INT函數(shù)用來取整锨络。值得注意的是INT函數(shù)不會四舍五入,無論小數(shù)點后是多少都會被舍去狼牺。這里只是RAND函數(shù)的幾個簡單應(yīng)用羡儿,還有很多隨機數(shù)的例子都可以根據(jù)這些,再結(jié)合不同的其它函數(shù)引申出來锁右。
2.3.9用NPOI操作EXCEL--通過NPOI獲得公式的返回值
前面我們學(xué)習(xí)了通過NPOI向Excel中設(shè)置公式失受,那么有些讀者可能會問:“NPOI能不能獲取公式的返回值呢?”咏瑟,答案是可以拂到!一、獲取模板文件中公式的返回值如在D盤中有一個名為text.xls的Excel文件码泞,其內(nèi)容如下:
注意C1單元格中設(shè)置的是公式“$A1*$B1”兄旬,而不是值“12”。利用NPOI,只需要寫簡單的幾句代碼就可以取得此公式的返回值:
HSSFWorkbook?wb?=newHSSFWorkbook(newFileStream("d:/test.xls",FileMode.Open));
HSSFCell?cell?=?wb.GetSheet(
"Sheet1").GetRow(0).GetCell(2);
System.Console.WriteLine(cell.NumericCellValue);
輸出結(jié)果為:
可見NPOI成功的“解析”了此.xls文件中的公式领铐。注意NumericCellValue屬性會自動根據(jù)單元格的類型處理悯森,如果為空將返0,如果為數(shù)值將返回數(shù)值绪撵,如果為公式將返回公式計算后的結(jié)果瓢姻。單元格的類型可以通過CellType屬性獲取。
二音诈、獲取NPOI生成的Excel文件中公式的返回值上例中是從一個已經(jīng)存在的Excel文件中獲取公式的返回值幻碱,那么如果Excel文件是通過NPOI創(chuàng)建的,直接用上面的方法獲取细溅,可能得不到想要的結(jié)果褥傍。如:
1HSSFWorkbook?hssfworkbook?=newHSSFWorkbook();
2HSSFSheet?sheet1?=?hssfworkbook.CreateSheet("Sheet1");
3HSSFRow?row?=?sheet1.CreateRow(0);
4row.CreateCell(0).SetCellValue(3);
5row.CreateCell(1).SetCellValue(4);
6HSSFCell?cell?=?row.CreateCell(2);
78cell.SetCellFormula("$A1+$B1");
9System.Console.WriteLine(cell.NumericCellValue);
執(zhí)行上面代碼,將輸出結(jié)果“0”喇聊,而不是我們想要的結(jié)果“7”恍风。那么將如何解決呢?這時要用到HSSFFormulaEvaluator類誓篱。在第8行后加上這兩句就可以了:
HSSFFormulaEvaluator?e?=newHSSFFormulaEvaluator(hssfworkbook);
cell?=?e.EvaluateInCell(cell);
運行結(jié)果如下:
2.4.1用NPOI操作EXCEL--畫線
之所有說NPOI強大朋贬,是因為常用的Excel操作她都可以通過編程的方式完成。這節(jié)開始燕鸽,我們開始學(xué)習(xí)NPOI的畫圖功能兄世。先從最簡單的開始,畫一條直線:
對應(yīng)的代碼為:
HSSFSheet?sheet1?=?hssfworkbook.CreateSheet("Sheet1");
HSSFPatriarch?patriarch?=?sheet1.CreateDrawingPatriarch();
HSSFClientAnchor?a1?=
newHSSFClientAnchor(255,125,1023,150,0,0,2,2);
HSSFSimpleShape?line1?=?patriarch.CreateSimpleShape(a1);
line1.ShapeType?=?HSSFSimpleShape.OBJECT_TYPE_LINE;
line1.LineStyle?=?HSSFShape.LINESTYLE_SOLID;
//在NPOI中線的寬度12700表示1pt,所以這里是0.5pt粗的線條啊研。line1.LineWidth?=6350;
通常御滩,利用NPOI畫圖主要有以下幾個步驟:
1.
創(chuàng)建一個Patriarch;
2.
創(chuàng)建一個Anchor党远,以確定圖形的位置削解;
3.
調(diào)用Patriarch創(chuàng)建圖形;
4.
設(shè)置圖形類型(直線沟娱,矩形氛驮,圓形等)及樣式(顏色,粗細(xì)等)济似。
關(guān)于HSSFClientAnchor(dx1,dy1,dx2,dy2,col1,row1,col2,row2)的參數(shù)矫废,有必要在這里說明一下:
dx1
:起始單元格的x偏移量,如例子中的255表示直線起始位置距A1單元格左側(cè)的距離砰蠢;
dy1
:起始單元格的y偏移量蓖扑,如例子中的125表示直線起始位置距A1單元格上側(cè)的距離;
dx2
:終止單元格的x偏移量台舱,如例子中的1023表示直線起始位置距C3單元格左側(cè)的距離律杠;
dy2
:終止單元格的y偏移量,如例子中的150表示直線起始位置距C3單元格上側(cè)的距離;
col1
:起始單元格列序號柜去,從0開始計算灰嫉;
row1
:起始單元格行序號,從0開始計算嗓奢,如例子中col1=0,row1=0就表示起始單元格為A1讼撒;
col2
:終止單元格列序號,從0開始計算股耽;
row2
:終止單元格行序號椿肩,從0開始計算,如例子中col2=2,row2=2就表示起始單元格為C3豺谈;
最后,關(guān)于LineStyle屬性贡这,有如下一些可選值茬末,對應(yīng)的效果分別如圖所示:
2.4.2用NPOI操作EXCEL--畫矩形
上一節(jié)我們講了NPOI中畫圖的基本步驟:
1.
創(chuàng)建一個Patriarch;
2.
創(chuàng)建一個Anchor盖矫,以確定圖形的位置丽惭;
3.
調(diào)用Patriarch創(chuàng)建圖形;
4.
設(shè)置圖形類型(直線辈双,矩形责掏,圓形等)及樣式(顏色,粗細(xì)等)湃望。
這一節(jié)我們將按照這個步驟創(chuàng)建一個矩形换衬。廢話少說,上代碼:
HSSFSheet?sheet1?=?hssfworkbook.CreateSheet("Sheet1");
HSSFPatriarch?patriarch?=?sheet1.CreateDrawingPatriarch();
HSSFClientAnchor?a1?=
newHSSFClientAnchor(255,125,1023,150,0,0,2,2);
HSSFSimpleShape?rec1?=?patriarch.CreateSimpleShape(a1);
//此處設(shè)置圖形類型為矩形rec1.ShapeType?=?HSSFSimpleShape.OBJECT_TYPE_RECTANGLE;
//設(shè)置填充色rec1.SetFillColor(125,125,125);
//設(shè)置邊框樣式rec1.LineStyle?=?HSSFShape.LINESTYLE_DASHGEL;
//設(shè)置邊框?qū)挾萺ec1.LineWidth?=25400;
//設(shè)置邊框顏色rec1.SetLineStyleColor(100,0,100);
代碼執(zhí)行效果:
其中SetFillColor和SetLineStyleColor函數(shù)的三個參數(shù)分別是RGB三色值证芭,具體表示什么顏色瞳浦,找個Photoshop試試:)關(guān)于HSSFClientAnchor參數(shù)說明、邊框樣式废士,邊框?qū)挾鹊恼f明可以參見前一篇博文:
http://www.cnblogs.com/atao/archive/2009/09/13/1565645.html
2.4.3用NPOI操作EXCEL--畫圓形
前面我們學(xué)習(xí)了NPOI中的畫簡單直線和矩形的功能叫潦,今天我們一起學(xué)習(xí)一下它支持的另一種簡單圖形--圓形。同樣官硝,按照前面所講的繪圖“四步曲”:
1.
創(chuàng)建一個Patriarch矗蕊;
2.
創(chuàng)建一個Anchor,以確定圖形的位置氢架;
3.
調(diào)用Patriarch創(chuàng)建圖形傻咖;
4.
設(shè)置圖形類型(直線,矩形达箍,圓形等)及樣式(顏色没龙,粗細(xì)等)。還是以例子加以說明:
HSSFSheet?sheet1?=?hssfworkbook.CreateSheet("Sheet1");
HSSFPatriarch?patriarch?=?sheet1.CreateDrawingPatriarch();
HSSFClientAnchor?a1?=
newHSSFClientAnchor(0,0,1023,0,0,0,1,3);
HSSFSimpleShape?rec1?=?patriarch.CreateSimpleShape(a1);
rec1.ShapeType?=?HSSFSimpleShape.OBJECT_TYPE_OVAL;
rec1.SetFillColor(
125,125,125);
rec1.LineStyle?=?HSSFShape.LINESTYLE_DASHGEL;
rec1.LineWidth?=
12700;
rec1.SetLineStyleColor(
100,0,100);
WriteToFile();
這里rec1.ShapeType =HSSFSimpleShape.OBJECT_TYPE_OVAL;表示圖形為橢圓。適當(dāng)調(diào)整HSSFClientAnchor的各參數(shù)可以得到圓形硬纤。關(guān)于HSSFClientAnchor構(gòu)造函數(shù)和邊框解滓、填充色等前兩節(jié)都有介紹,這里不再重述筝家。詳情情見:畫矩形和畫線洼裤。
上面代碼執(zhí)行生成的Excel如下:
2.4.4用NPOI操作EXCEL--畫Grid
在NPOI中,本身沒有畫Grid的方法溪王。但我們知道Grid其實就是由橫線和豎線構(gòu)成的腮鞍,所在我們可以通過畫線的方式來模擬畫Grid。
HSSFSheet?sheet1?=?hssfworkbook.CreateSheet("Sheet1");
HSSFRow?row?=?sheet1.CreateRow(
2);
row.CreateCell(
1);
row.HeightInPoints?=
240;
sheet1.SetColumnWidth(
2,9000);
intlinesCount?=20;
HSSFPatriarch?patriarch?=?sheet1.CreateDrawingPatriarch();
//因為HSSFClientAnchor中dx只能在0-1023之間,dy只能在0-255之間莹菱,所以這里采用比例的方式doublexRatio?=1023.0/?(linesCount*10);
doubleyRatio?=255.0/?(linesCount*10);
//畫豎線intx1?=0;
inty1?=0;
intx2?=0;
inty2?=200;
for(inti?=0;?i?<?linesCount;?i++)
{
HSSFClientAnchor?a2?=
newHSSFClientAnchor();
a2.SetAnchor((
short)2,2,?(int)(x1?*?xRatio),?(int)(y1?*?yRatio),
(
short)2,2,?(int)(x2?*?xRatio),?(int)(y2?*?yRatio));
HSSFSimpleShape?shape2?=?patriarch.CreateSimpleShape(a2);
shape2.ShapeType?=?(HSSFSimpleShape.OBJECT_TYPE_LINE);
x1?+=
10;
x2?+=
10;
}
//畫橫線x1?=0;
y1?=
0;
x2?=
200;
y2?=
0;
for(inti?=0;?i?<?linesCount;?i++)
{
HSSFClientAnchor?a2?=
newHSSFClientAnchor();
a2.SetAnchor((
short)2,2,?(int)(x1?*?xRatio),?(int)(y1?*?yRatio),
(
short)2,2,?(int)(x2?*?xRatio),?(int)(y2?*?yRatio));
HSSFSimpleShape?shape2?=?patriarch.CreateSimpleShape(a2);
shape2.ShapeType?=?(HSSFSimpleShape.OBJECT_TYPE_LINE);
y1?+=
10;
y2?+=
10;
}
請注意HSSFClientAnchor對象中的dx只能取0-1023之間的數(shù)移国,dy只能取0-255之間的數(shù)。我們可以理解為是將單元格的寬和高平分成了1023和255份道伟,設(shè)置dx和dy時相當(dāng)于按比例取對應(yīng)的座標(biāo)迹缀。最終生成的Excel如下:
2.4.5用NPOI操作EXCEL--插入圖片
我們知道,在Excel中是可以插入圖片的蜜徽。操作菜單是“插入->圖片”祝懂,然后選擇要插入圖片,可以很容易地在Excel插入圖片拘鞋。同樣砚蓬,在NPOI中,利用代碼也可以實現(xiàn)同樣的效果盆色。在NPOI中插入圖片的方法與畫圖的方法有點類似:
//add?picture?data?to?this?workbook.
byte[]?bytes?=?System.IO.File.ReadAllBytes(@"D:\MyProject\NPOIDemo\ShapeImage\image1.jpg");
intpictureIdx?=?hssfworkbook.AddPicture(bytes,?HSSFWorkbook.PICTURE_TYPE_JPEG);
//create?sheet
HSSFSheet?sheet?=?hssfworkbook.CreateSheet("Sheet1");
//?Create?the?drawing?patriarch.??This?is?the?top?level?container?for?all?shapes.
HSSFPatriarch?patriarch?=?sheet.CreateDrawingPatriarch();
//add?a?picture
HSSFClientAnchor?anchor?=newHSSFClientAnchor(0,0,1023,0,0,0,1,3);
HSSFPicture?pict?=?patriarch.CreatePicture(anchor,?pictureIdx);
與畫簡單圖形不同的是灰蛙,首先要將圖片讀入到byte數(shù)組,然后添加到workbook中傅事;最后調(diào)用的是patriarch.CreatePicture(anchor, pictureIdx)方法顯示圖片缕允,而不是patriarch.CreateSimpleShape(anchor)方法。上面這段代碼執(zhí)行后生成的Excel文件樣式如下:
我們發(fā)現(xiàn)蹭越,插入的圖片被拉伸填充在HSSFClientAnchor指定的區(qū)域障本。有時可能我們并不需要拉伸的效果,怎么辦呢响鹃?很簡單驾霜,在最后加上這樣一句用來自動調(diào)節(jié)圖片大小:
pict.Resize();
添加代碼后再執(zhí)行上述代碼买置,生成的Excel樣式如下:
圖片已經(jīng)自動伸縮到原始大小了粪糙。
NPOI 1.2教程- 2.5打印相關(guān)設(shè)置
作者:Tony Qu
NPOI官方網(wǎng)站:http://npoi.codeplex.com/
打印設(shè)置主要包括方向設(shè)置、縮放忿项、紙張設(shè)置蓉冈、頁邊距等城舞。NPOI 1.2支持大部分打印屬性,能夠讓你輕松滿足客戶的打印需要寞酿。
首先是方向設(shè)置家夺,Excel支持兩種頁面方向,即縱向和橫向伐弹。
在NPOI中如何設(shè)置呢拉馋?你可以通過HSSFSheet.PrintSetup.Landscape來設(shè)置,Landscape是布爾類型的惨好,在英語中是橫向的意思煌茴。如果Landscape等于true,則表示頁面方向為橫向日川;否則為縱向蔓腐。
接著是縮放設(shè)置,
這里的縮放比例對應(yīng)于HSSFSheet.PrintSetup.Scale龄句,而頁寬和頁高分別對應(yīng)于HSSFSheet.PrintSetup.FitWidth和HSSFSheet.PrintSetup.FitHeight合住。要注意的是,這里的PrintSetup.Scale應(yīng)該被設(shè)置為0-100之間的值撒璧,而不是小數(shù)。
接下來就是紙張設(shè)置了笨使,對應(yīng)于HSSFSheet.PrintSetup.PaperSize卿樱,但這里的PaperSize并不是隨便設(shè)置的,而是由一些固定的值決定的硫椰,具體的值與對應(yīng)的紙張如下表所示:
值紙張
1US Letter 8 1/2 x 11 in
2USLetter Small 8 1/2 x 11 in
3US Tabloid 11 x 17 in
4US Ledger 17 x 11 in
5US Legal 8 1/2 x 14 in
6US Statement 5 1/2 x 8 1/2 in
7US Executive 7 1/4 x 10 1/2 in
8A3 297 x 420 mm
9A4 210 x 297 mm
10A4 Small 210 x 297 mm
11A5 148 x 210 mm
12B4 (JIS) 250 x 354
13B5 (JIS) 182 x 257 mm
14Folio 8 1/2 x 13 in
15Quarto 215 x 275 mm
1610 x 14 in
1711 x 17 in
18US Note 8 1/2 x 11 in
19US Envelope #9 3 7/8 x 8 7/8
20US Envelope #10 4 1/8 x 9 1/2
21US Envelope #11 4 1/2 x 10 3/8
22US Envelope #12 4 \276 x 11
23US Envelope #14 5 x 11 1/2
24C size sheet
25D size sheet
26E size sheet
27Envelope DL 110 x 220mm
28Envelope C5 162 x 229 mm
29Envelope C3 324 x 458 mm
30Envelope C4 229 x 324 mm
31Envelope C6 114 x 162 mm
32Envelope C65 114 x 229 mm
33Envelope B4 250 x 353 mm
34Envelope B5 176 x 250 mm
35Envelope B6 176 x 125 mm
36Envelope 110 x 230 mm
37US Envelope Monarch 3.875 x 7.5 in
386 3/4 US Envelope 3 5/8 x 6 1/2 in
39US Std Fanfold 14 7/8 x 11 in
40German Std Fanfold 8 1/2 x 12 in
41German Legal Fanfold 8 1/2 x 13 in
42B4 (ISO) 250 x 353 mm
43Japanese Postcard 100 x 148 mm
449 x 11 in
4510 x 11 in
4615 x 11 in
47Envelope Invite 220 x 220 mm
48RESERVED--DO NOT USE
49RESERVED--DO NOT USE
50US Letter Extra 9 \275 x 12 in
51US Legal Extra 9 \275 x 15 in
52US Tabloid Extra 11.69 x 18 in
53A4 Extra 9.27 x 12.69 in
54Letter Transverse 8 \275 x 11 in
55A4 Transverse 210 x 297 mm
56Letter Extra Transverse 9\275 x 12 in
57SuperA/SuperA/A4 227 x 356 mm
58SuperB/SuperB/A3 305 x 487 mm
59US Letter Plus 8.5 x 12.69 in
60A4 Plus 210 x 330 mm
61A5 Transverse 148 x 210 mm
62B5 (JIS) Transverse 182 x 257 mm
63A3 Extra 322 x 445 mm
64A5 Extra 174 x 235 mm
65B5 (ISO) Extra 201 x 276 mm
66A2 420 x 594 mm
67A3 Transverse 297 x 420 mm
68A3 Extra Transverse 322 x 445 mm
69Japanese Double Postcard 200 x 148 mm
70A6 105 x 148 mm
71Japanese Envelope Kaku #2
72Japanese Envelope Kaku #3
73Japanese Envelope Chou #3
74Japanese Envelope Chou #4
75Letter Rotated 11 x 8 1/2 11 in
76A3 Rotated 420 x 297 mm
77A4 Rotated 297 x 210 mm
78A5 Rotated 210 x 148 mm
79B4 (JIS) Rotated 364 x 257 mm
80B5 (JIS) Rotated 257 x 182 mm
81Japanese Postcard Rotated 148 x 100 mm
82Double Japanese Postcard Rotated 148 x 200 mm
83A6 Rotated 148 x 105 mm
84Japanese Envelope Kaku #2 Rotated
85Japanese Envelope Kaku #3 Rotated
86Japanese Envelope Chou #3 Rotated
87Japanese Envelope Chou #4 Rotated
88B6 (JIS) 128 x 182 mm
89B6 (JIS) Rotated 182 x 128 mm
9012 x 11 in
91Japanese Envelope You #4
92Japanese Envelope You #4 Rotated
93PRC 16K 146 x 215 mm
94PRC 32K 97 x 151 mm
95PRC 32K(Big) 97 x 151 mm
96PRC Envelope #1 102 x 165 mm
97PRC Envelope #2 102 x 176 mm
98PRC Envelope #3 125 x 176 mm
99PRC Envelope #4 110 x 208 mm
100PRC Envelope #5 110 x 220 mm
101PRC Envelope #6 120 x 230 mm
102PRC Envelope #7 160 x 230 mm
103PRC Envelope #8 120 x 309 mm
104PRC Envelope #9 229 x 324 mm
105PRC Envelope #10 324 x 458 mm
106PRC 16K Rotated
107PRC 32K Rotated
108PRC 32K(Big) Rotated
109PRC Envelope #1 Rotated 165 x 102 mm
110PRC Envelope #2 Rotated 176 x 102 mm
111PRC Envelope #3 Rotated 176 x 125 mm
112PRC Envelope #4 Rotated 208 x 110 mm
113PRC Envelope #5 Rotated 220 x 110 mm
114PRC Envelope #6 Rotated 230 x 120 mm
115PRC Envelope #7 Rotated 230 x 160 mm
116PRC Envelope #8 Rotated 309 x 120 mm
117PRC Envelope #9 Rotated 324 x 229 mm
118PRC Envelope #10 Rotated 458 x 324 mm
(此表摘自《Excel Binary File Format (.xls) Structure Specification.pdf》)
HSSFSheet下面定義了一些xxxx_PAPERSIZE的常量繁调,但都是非常常用的紙張大小,如果滿足不了你的需要靶草,可以根據(jù)上表自己給PaperSize屬性賦值蹄胰。所以,如果你要設(shè)置紙張大小可以用這樣的代碼:
HSSFSheet.PrintSetup.PaperSize=HSSFSheet.A4_PAPERSIZE;
或
HSSFSheet.PrintSetup.PaperSize=9;(A4 210*297mm)
再下來就是打印的起始頁碼奕翔,它對應(yīng)于HSSFSheet.PrintSetup.PageStart和HSSFSheet.PrintSetup.UsePage裕寨,如果UsePage=false,那么就相當(dāng)于“自動”派继,這時PageStart不起作用宾袜;如果UsePage=true,PageStart才會起作用驾窟。所以在設(shè)置PageStart之前庆猫,必須先把UsePage設(shè)置為true。
“打印”欄中的“網(wǎng)格線”設(shè)置對應(yīng)于HSSFSheet.IsPrintGridlines绅络,請注意月培,這里不是HSSFSheet.PrintSetup下面嘁字,所以別搞混了。這里之所以不隸屬于PrintSetup是由底層存儲該信息的record決定的杉畜,底層是把IsGridsPrinted放在GridsetRecord里面的纪蜒,而不是PrintSetupRecord里面的,盡管界面上是放在一起的寻行。另外還有一個HSSFSheet.IsGridsPrinted屬性霍掺,這個屬性對應(yīng)于底層的gridset Record,但這個record是保留的拌蜘,從微軟的文檔顯示沒有任何意義杆烁,所以這個屬性請不要去設(shè)置。
“單色打印”則對應(yīng)于HSSFSheet.PrintSetup.NoColors简卧,這是布爾類型的兔魂,值為true時,表示單色打印举娩。
“草稿品質(zhì)”對應(yīng)于HSSFSheet.PrintSetup.IsDraft析校,也是布爾類型的,值為true時铜涉,表示用草稿品質(zhì)打印智玻。
這里的打印順序是由HSSFSheet.PrintSetup.LeftToRight決定的,它是布爾類型的芙代,當(dāng)為true時吊奢,則表示“先行后列”;如果是false纹烹,則表示“先列后行”页滚。
在NPOI 1.2中,“行號列標(biāo)”铺呵、“批注”和“錯誤單元格打印為”裹驰、“頁邊距”暫不支持,將在以后的版本中支持片挂。
有關(guān)打印的范例可以參考NPOI 1.2正式版中的SetPrintSettingsInXls項目幻林。
2.6.1用NPOI操作EXCEL--調(diào)整表單顯示比例
在Excel中,可以通過調(diào)整右下角的滾動條來調(diào)整Sheet的顯示比例音念。如圖:
在NPOI中滋将,也能通過代碼實現(xiàn)這樣的功能,并且代碼非常簡單:
HSSFSheet?sheet1?=?hssfworkbook.CreateSheet("Sheet1");
sheet1.CreateRow(
0).CreateCell(0).SetCellValue("This?is?a?test.");
//50%?zoom
sheet1.SetZoom(1,2);
我們發(fā)現(xiàn)症昏,SetZoom有兩個參數(shù)随闽。其中第一個參數(shù)表示縮放比例的分子,第二個參數(shù)表示縮放比例的分母肝谭,所以SetZoom(1,2)就表示縮小到1/2,也就是50%。代碼執(zhí)行后生成的Excel樣式如下:
如果將SetZoom的參數(shù)改成(2,1)费封,代碼執(zhí)行后生成的Excel樣式如下矾飞,表示擴大兩倍:
2.6.2用NPOI操作EXCEL--設(shè)置密碼
有時吞获,我們可能需要某些單元格只讀,如在做模板時,模板中的數(shù)據(jù)是不能隨意讓別人改的。在Excel中更哄,可以通過“審閱->保護(hù)工作表”來完成,如下圖:
那么腥寇,在NPOI中有沒有辦法通過編碼的方式達(dá)到這一效果呢成翩?答案是肯定的。
HSSFSheet?sheet1?=?hssfworkbook.CreateSheet("Sheet1");
HSSFRow?row1?=?sheet1.CreateRow(
0);
HSSFCell?cel1?=?row1.CreateCell(
0);
HSSFCell?cel2?=?row1.CreateCell(
1);
HSSFCellStyle?unlocked?=?hssfworkbook.CreateCellStyle();
unlocked.IsLocked?=
false;
HSSFCellStyle?locked?=?hssfworkbook.CreateCellStyle();
locked.IsLocked?=
true;
cel1.SetCellValue(
"沒被鎖定");
cel1.CellStyle?=?unlocked;
cel2.SetCellValue(
"被鎖定");
cel2.CellStyle?=?locked;
sheet1.ProtectSheet(
"password");
正如代碼中所看到的赦役,我們通過設(shè)置CellStype的ISLocked為True麻敌,表示此單元格將被鎖定。相當(dāng)于在Excel中執(zhí)行了如下操作:
然后通過ProtectSheet設(shè)置密碼掂摔。
執(zhí)行結(jié)果如下:
沒被鎖定的列可以任意修改术羔。
被鎖定的列不能修改。
輸入密碼可以解除鎖定乙漓。
NPOI 1.2教程-組合行级历、列
作者:Tony Qu
NPOI官方網(wǎng)站:http://npoi.codeplex.com/
Excel 2007中有一個面板是專門用于設(shè)置組合功能的,叫做“分級顯示”面板叭披,如下所示:
可能我們在過去生成Excel文件的時候根本不會用這個功能鱼喉,也沒辦法用,因為cvs法和html法沒辦法控制這些東西趋观。這里簡單的介紹一下什么叫做組合:
組合分為行組合和列組合,所謂行組合锋边,就是讓n行組合成一個集合皱坛,能夠進(jìn)行展開和合攏操作,在Excel中顯示如下:
圖中左側(cè)就是用于控制行組合折疊的圖標(biāo)豆巨,圖中上部就是用于控制列組合的剩辟,是不是有點像TreeView中的折疊節(jié)點?很多時候由于數(shù)據(jù)太多往扔,為了讓用戶對于大量數(shù)據(jù)一目了然贩猎,我們可以使用行列組合來解決顯示大綱,這和Visual Studio里面的region的概念是類似的萍膛。
細(xì)心的朋友可能已經(jīng)注意到了吭服,我們其實可以對一行做多次組合操作,這就是分級顯示的概念蝗罗,圖中就把行2-3分為2個組合艇棕,第2行到第4行為一個組合蝌戒,第2行到第5行一個組合,所以是分兩級沼琉。
在NPOI中北苟,要實現(xiàn)分組其實并不難,你只需要調(diào)用HSSFSheet.GroupRow和HSSFSheet.GroupColumn這兩個方法就可以了打瘪。
首先我們來看HSSFSheet.GroupRow友鼻,GroupRow有2個參數(shù),分別是fromRow和toRow闺骚,表示起始行號和結(jié)束行號彩扔,這些行號都是從0開始算起的。
HSSFWorkbookhssfworkbook =newHSSFWorkbook();
HSSFSheet s =hssfworkbook.CreateSheet("Sheet1");
s.GroupRow(1,3);
上面的代碼把第2行到第4行做了組合葛碧。
要組合列借杰,其實代碼很相似,如下所示:
s.GroupColumn(1,3)
上面的代碼把B至D列做了組合进泼。
正如上圖中Excel的“分級顯示”面板所示蔗衡,有“組合”,也一定有“取消組合”乳绕,NPOI中你可以用HSSFSheet.UngroupRow和HSSFSheet.UngroupColumn绞惦,參數(shù)和GroupXXX是一樣的,如果要取消第2到第4行的組合洋措,就可以用下面的代碼:
s.UngroupColumn(1,3)
相關(guān)范例請見NPOI 1.2正式版中的GroupRowAndColumnInXls項目济蝉。
2.6.4用NPOI操作EXCEL--鎖定列
在Excel中,有時可能會出現(xiàn)列數(shù)太多或是行數(shù)太多的情況菠发,這時可以通過鎖定列來凍結(jié)部分列王滤,不隨滾動條滑動,方便查看滓鸠。在Excel中設(shè)置凍結(jié)列的方法如下:
同樣雁乡,利用NPOI,通過代碼也能實現(xiàn)上面的效果:
HSSFSheet?sheet1?=?hssfworkbook.CreateSheet("Sheet1");
HSSFRow?row1?=?sheet1.CreateRow(
0);
row1.CreateCell(
0).SetCellValue("凍結(jié)列");
sheet1.CreateFreezePane(
1,0,1,0);
代碼執(zhí)行結(jié)果如下:
下面對CreateFreezePane的參數(shù)作一下說明:第一個參數(shù)表示要凍結(jié)的列數(shù)糜俗;第二個參數(shù)表示要凍結(jié)的行數(shù)踱稍,這里只凍結(jié)列所以為0;第三個參數(shù)表示右邊區(qū)域可見的首列序號悠抹,從1開始計算珠月;第四個參數(shù)表示下邊區(qū)域可見的首行序號,也是從1開始計算楔敌,這里是凍結(jié)列啤挎,所以為0;
舉例說明也許更好理解卵凑,將各參數(shù)設(shè)置為如下:
sheet1.CreateFreezePane(2,0,5,0);
得到的效果如下圖:
注意圖中C侵浸、D和E列默認(rèn)是看不到的旺韭,滾動才看得到,這就是第三個參數(shù)5起了作用掏觉,是不是很好理解了呢:)
接下來区端,看一下凍結(jié)行的效果。將上面的代碼稍作修改:
HSSFSheet?sheet1?=?hssfworkbook.CreateSheet("Sheet1");
HSSFRow?row1?=?sheet1.CreateRow(
0);
row1.CreateCell(
0).SetCellValue("凍結(jié)行");
sheet1.CreateFreezePane(
0,1,0,1);
執(zhí)行后生成的Excel文件效果見下圖:
那么澳腹,如果要行和列同時凍結(jié)該怎么做呢织盼?聰明的你一定能想得到,呵呵~~
NPOI 1.2教程-顯示/隱藏Excel網(wǎng)格線
作者:Tony Qu
NPOI官方網(wǎng)站:http://npoi.codeplex.com/
有些時候酱塔,我們需要網(wǎng)格線沥邻,而有些時候我們不需要,這取決于實際的業(yè)務(wù)需求羊娃。前兩天inmegin兄就問我唐全,怎么把網(wǎng)格給去掉,因為他們要把Excel文檔當(dāng)Word使蕊玷,也許是因為Excel排版方便吧邮利。
Excel中的網(wǎng)格線設(shè)置是以表(Sheet)為單位進(jìn)行管理的,這也就意味著你可以讓一個表顯示網(wǎng)格線垃帅,而另一個表不顯示延届,這是不沖突的。
在Excel 2007中贸诚,我們通常用“工作表選項”面板來設(shè)置這個屬性:
在面板中方庭,你會發(fā)現(xiàn)有2個多選框,一個是查看酱固,一個是打印械念,也就是說Excel是把查看和打印網(wǎng)格線作為兩個設(shè)置來處理的,存儲的Record也是不同的运悲。
在NPOI中龄减,如果要讓網(wǎng)格線在查看時顯示/隱藏,你可以HSSFSheet.DisplayGridlines屬性扇苞,默認(rèn)值為true(這也是為什么默認(rèn)情況下我們能夠看到網(wǎng)格線)。下面的代碼就是讓網(wǎng)格線在查看時不可見的:
HSSFWorkbookhssfworkbook =newHSSFWorkbook();
HSSFSheet s1= hssfworkbook.CreateSheet("Sheet1");
s1.DisplayGridlines=false;
如果要在打印時顯示/隱藏網(wǎng)格線寄纵,你可以用HSSFSheet.IsGridlinesPrinted屬性鳖敷,默認(rèn)值為false(這就是默認(rèn)情況下打印看不到網(wǎng)格線的原因)。代碼和上面差不多:
s1.IsGridsPrinted=true;
上面的代碼將在打印時顯示網(wǎng)格線程拭,打印的效果如下所示定踱。
在此也提醒大家,如果這個Excel最終客戶有打印意向恃鞋,可別忘了把IsGridPrinted屬性也設(shè)置上崖媚。
相關(guān)范例可以參考NPOI 1.2正式版中的DisplayGridlinesInXls項目亦歉。
2.6.6用NPOI操作EXCEL--設(shè)置初始視圖的行、列
有些時候畅哑,我們可能希望生成的Excel文件在被打開的時候自動將焦點定位在某個單元格或是選中某個區(qū)域中肴楷。在NPOI中可以通過SetAsActiveCell和SetActiveCellRange等幾個方法實現(xiàn)。
首先我們看一下設(shè)置初始視圖中選中某個單元格的方法:
//use?HSSFCell.SetAsActiveCell()?to?select?B6?as?the?active?column
HSSFSheet?sheet1?=?hssfworkbook.CreateSheet("Sheet?A");
CreateCellArray(sheet1);
sheet1.GetRow(
5).GetCell(1).SetAsActiveCell();
//set?TopRow?and?LeftCol?to?make?B6?the?first?cell?in?the?visible?area
sheet1.TopRow?=5;
sheet1.LeftCol?=
1;
其中CreateCellArray(sheet1)方法用來寫示范數(shù)據(jù)荠呐,其代碼為(下同):
staticvoidCreateCellArray(HSSFSheet?sheet)
{
for(inti?=0;?i?<300;?i++)
{
HSSFRow?row=sheet.CreateRow(i);
for(intj?=0;?j?<150;?j++)
{
HSSFCell?cell?=?row.CreateCell(j);
cell.SetCellValue(i*j);
}
}
}
生成的Excel打開時效果如下赛蔫,注意B6為默認(rèn)選中狀態(tài),TopRow和LeftCol設(shè)置B6為當(dāng)前可見區(qū)域的第一個單元格:
如果不設(shè)置TopRow和LeftCol屬性泥张,默認(rèn)的可見域的第一個單元格為A1呵恢,如下是另一種設(shè)置活動單元格的方法,但沒有設(shè)置此Sheet的TopRow和LeftCol:
HSSFSheet?sheet2?=?hssfworkbook.CreateSheet("Sheet?B");
sheet2.Sheet.SetActiveCell(
1,5);
對應(yīng)生成的Excel顯示為:
除了設(shè)置某個單元格為選中狀態(tài)外媚创,還NPOI可以設(shè)置某個區(qū)域為選中狀態(tài):
//use?Sheet.SetActiveCellRange?to?select?a?cell?range
HSSFSheet?sheet3?=?hssfworkbook.CreateSheet("Sheet?C");
CreateCellArray(sheet3);
sheet3.Sheet.SetActiveCellRange(
2,5,1,5);
以上代碼設(shè)置了Sheet C的選中區(qū)域為B3:F6:
還有更強大的渗钉,設(shè)置多個選中區(qū)域:
//use?Sheet.SetActiveCellRange?to?select?multiple?cell?ranges
HSSFSheet?sheet4?=?hssfworkbook.CreateSheet("Sheet?D");
CreateCellArray(sheet4);
List?cellranges?=
newList();
cellranges.Add(
newCellRangeAddress8Bit(1,3,2,5));
cellranges.Add(
newCellRangeAddress8Bit(6,7,8,9));
sheet4.Sheet.SetActiveCellRange(cellranges,
1,6,9);
如果一個Excel文件中有多個Sheet,還可以通過如下語句設(shè)置打開時的初始Sheet:
hssfworkbook.ActiveSheetIndex?=2;
2.6.7用NPOI操作EXCEL--數(shù)據(jù)有效性
在有些情況下(比如Excel引入)钞钙,我們可能不允許用戶在Excel隨意輸入一些無效數(shù)據(jù)鳄橘,這時就要在模板中加一些數(shù)據(jù)有效性的驗證。在Excel中歇竟,設(shè)置數(shù)據(jù)有效性的方步驟如下:(1)先選定一個區(qū)域挥唠;數(shù)據(jù)有效性”中設(shè)置數(shù)據(jù)有效性驗證(如圖)。à(2)在菜單“數(shù)據(jù)
同樣焕议,利用NPOI宝磨,用代碼也可以實現(xiàn):
HSSFSheet?sheet1?=?hssfworkbook.CreateSheet("Sheet1");
sheet1.CreateRow(
0).CreateCell(0).SetCellValue("日期列");
CellRangeAddressList?regions1?=
newCellRangeAddressList(1,65535,0,0);
DVConstraint?constraint1?=?DVConstraint.CreateDateConstraint(DVConstraint.OperatorType.BETWEEN,
"1900-01-01","2999-12-31","yyyy-MM-dd");
HSSFDataValidation?dataValidate1?=
newHSSFDataValidation(regions1,?constraint1);
dataValidate1.CreateErrorBox(
"error","You?must?input?a?date.");
sheet1.AddValidationData(dataValidate1);
上面是一個在第一列要求輸入1900-1-1至2999-12-31之間日期的有效性驗證的例子,生成的Excel效果如下盅安,當(dāng)輸入非法時將給出警告:
下面對剛才用到的幾個方法加以說明:
CellRangeAddressList
類表示一個區(qū)域唤锉,構(gòu)造函數(shù)中的四個參數(shù)分別表示起始行序號,終止行序號别瞭,起始列序號窿祥,終止列序號。所以第一列所在區(qū)域就表示為:
//所有序號都從零算起蝙寨,第一行標(biāo)題行除外晒衩,所以第一個參數(shù)是1,65535是一個Sheet的最大行數(shù)newCellRangeAddressList(1,65535,0,0);
另外墙歪,CreateDateConstraint的第一個參數(shù)除了設(shè)置成DVConstraint.OperatorType.BETWEEN外听系,還可以設(shè)置成如下一些值,大家可以自己一個個去試看看效果:
最后虹菲,dataValidate1.CreateErrorBox(title,text)靠胜,用來創(chuàng)建出錯時的提示信息。第一個參數(shù)表示提示框的標(biāo)題,第二個參數(shù)表示提示框的內(nèi)容浪漠。
理解了上面這些陕习,創(chuàng)建一個整數(shù)類型的有效性驗證也不難實現(xiàn):
sheet1.CreateRow(0).CreateCell(1).SetCellValue("數(shù)值列");
CellRangeAddressList?regions2?=
newCellRangeAddressList(1,65535,1,1);
DVConstraint?constraint2?=?DVConstraint.CreateNumericConstraint(DVConstraint.ValidationType.INTEGER,DVConstraint.OperatorType.BETWEEN,
"0","100");
HSSFDataValidation?dataValidate2?=
newHSSFDataValidation(regions2,?constraint2);
dataValidate2.CreateErrorBox(
"error","You?must?input?a?numeric?between?0?and?100.");
sheet1.AddValidationData(dataValidate2);
生成的Excel效果為:
下一節(jié)我們將學(xué)習(xí)利用數(shù)據(jù)有效性創(chuàng)建下拉列表的例子。
2.6.8用NPOI操作EXCEL--生成下拉列表
上一節(jié)我們講了簡單的數(shù)據(jù)有效性驗證址愿,這一節(jié)我們學(xué)習(xí)一下數(shù)據(jù)有效性的另一個應(yīng)用--下拉列表该镣。在Excel中,并沒有類似Web中的下拉控件必盖,其下拉效果是通過數(shù)據(jù)有效性來實現(xiàn)的拌牲。設(shè)置步驟為:(1)選定一個要生成下拉列表的區(qū)域;(2)設(shè)置數(shù)據(jù)有效性為序列歌粥,并在來源中填充可選下拉的值塌忽,用“,”隔開(如圖)。
對應(yīng)的效果為:
同樣失驶,利用NPOI代碼也可以實現(xiàn)上面的效果:
HSSFSheet?sheet1?=?hssfworkbook.CreateSheet("Sheet1");
CellRangeAddressList?regions?=
newCellRangeAddressList(0,65535,0,0);
DVConstraint?constraint?=?DVConstraint.CreateExplicitListConstraint(
newstring[]?{"itemA","itemB","itemC"});
HSSFDataValidation?dataValidate?=
newHSSFDataValidation(regions,?constraint);
sheet1.AddValidationData(dataValidate);
下面對代碼作一下簡要說明:先設(shè)置一個需要提供下拉的區(qū)域土居,關(guān)于CellRangeAddressList構(gòu)造函數(shù)參數(shù)的說明請參見上一節(jié):
CellRangeAddressList?regions?=newCellRangeAddressList(0,65535,0,0);
然后將下拉項作為一個數(shù)組傳給CreateExplicitListConstraint作為參數(shù)創(chuàng)建一個約束,根據(jù)要控制的區(qū)域和約束創(chuàng)建數(shù)據(jù)有效性就可以了嬉探。
但是這樣會有一個問題:Excel中允許輸入的序列來源長度最大為255個字符擦耀,也就是說當(dāng)下拉項的總字符串長度超過255是將會出錯。那么如果下拉項很多的情況下應(yīng)該怎么處理呢涩堤?答案是通過引用的方式眷蜓。步驟如下:先創(chuàng)建一個Sheet專門用于存儲下拉項的值,并將各下拉項的值寫入其中:
HSSFSheet?sheet2?=?hssfworkbook.CreateSheet("ShtDictionary");
sheet2.CreateRow(
0).CreateCell(0).SetCellValue("itemA");
sheet2.CreateRow(
1).CreateCell(0).SetCellValue("itemB");
sheet2.CreateRow(
2).CreateCell(0).SetCellValue("itemC");
然后定義一個名稱胎围,指向剛才創(chuàng)建的下拉項的區(qū)域:
HSSFName?range?=?hssfworkbook.CreateName();
range.Reference?=
"ShtDictionary!$A1:$A3";
range.NameName?=
"dicRange";
最后吁系,設(shè)置數(shù)據(jù)約束時指向這個名稱而不是字符數(shù)組:
HSSFSheet?sheet1?=?hssfworkbook.CreateSheet("Sheet1");
CellRangeAddressList?regions?=
newCellRangeAddressList(0,65535,0,0);
DVConstraint?constraint?=?DVConstraint.CreateFormulaListConstraint(
"dicRange");
HSSFDataValidation?dataValidate?=
newHSSFDataValidation(regions,?constraint);
sheet1.AddValidationData(dataValidate);
執(zhí)行這段代碼,生成的Excel效果如下:
在名稱管理器中會發(fā)現(xiàn)有一個名為"dicRange"的名稱白魂,指向"ShtDictionary!$A1:$A3"的下拉項區(qū)域:
在數(shù)據(jù)有效性中會發(fā)現(xiàn)來源變成了"=dicRange"汽纤,指向上面定義的名稱。而不是以前的"itemA,itemB,itemC":